LCOV - code coverage report
Current view: top level - dev/ic - adw.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 438 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: adw.c,v 1.55 2017/09/08 05:36:52 deraadt Exp $ */
       2             : /* $NetBSD: adw.c,v 1.23 2000/05/27 18:24:50 dante Exp $         */
       3             : 
       4             : /*
       5             :  * Generic driver for the Advanced Systems Inc. SCSI controllers
       6             :  *
       7             :  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
       8             :  * All rights reserved.
       9             :  *
      10             :  * Author: Baldassare Dante Profeta <dante@mclink.it>
      11             :  *
      12             :  * Redistribution and use in source and binary forms, with or without
      13             :  * modification, are permitted provided that the following conditions
      14             :  * are met:
      15             :  * 1. Redistributions of source code must retain the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer.
      17             :  * 2. Redistributions in binary form must reproduce the above copyright
      18             :  *    notice, this list of conditions and the following disclaimer in the
      19             :  *    documentation and/or other materials provided with the distribution.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      22             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      23             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      24             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      25             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      26             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      27             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      29             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      31             :  * POSSIBILITY OF SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include <sys/param.h>
      35             : #include <sys/systm.h>
      36             : #include <sys/kernel.h>
      37             : #include <sys/errno.h>
      38             : #include <sys/device.h>
      39             : #include <sys/malloc.h>
      40             : #include <sys/buf.h>
      41             : #include <sys/timeout.h>
      42             : 
      43             : #include <machine/bus.h>
      44             : #include <machine/intr.h>
      45             : 
      46             : #include <scsi/scsi_all.h>
      47             : #include <scsi/scsiconf.h>
      48             : 
      49             : #include <dev/ic/adwlib.h>
      50             : #include <dev/microcode/adw/adwmcode.h>
      51             : #include <dev/ic/adw.h>
      52             : 
      53             : /******************************************************************************/
      54             : 
      55             : 
      56             : int adw_alloc_controls(ADW_SOFTC *);
      57             : int adw_alloc_carriers(ADW_SOFTC *);
      58             : int adw_create_ccbs(ADW_SOFTC *, ADW_CCB *, int);
      59             : void adw_ccb_free(void *, void *);
      60             : void adw_reset_ccb(ADW_CCB *);
      61             : int adw_init_ccb(ADW_SOFTC *, ADW_CCB *);
      62             : void *adw_ccb_alloc(void *);
      63             : int adw_queue_ccb(ADW_SOFTC *, ADW_CCB *, int);
      64             : 
      65             : void adw_scsi_cmd(struct scsi_xfer *);
      66             : int adw_build_req(struct scsi_xfer *, ADW_CCB *, int);
      67             : void adw_build_sglist(ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *);
      68             : void adw_minphys(struct buf *, struct scsi_link *);
      69             : void adw_isr_callback(ADW_SOFTC *, ADW_SCSI_REQ_Q *);
      70             : void adw_async_callback(ADW_SOFTC *, u_int8_t);
      71             : 
      72             : void adw_print_info(ADW_SOFTC *, int);
      73             : 
      74             : int adw_poll(ADW_SOFTC *, struct scsi_xfer *, int);
      75             : void adw_timeout(void *);
      76             : void adw_reset_bus(ADW_SOFTC *);
      77             : 
      78             : 
      79             : /******************************************************************************/
      80             : 
      81             : 
      82             : struct cfdriver adw_cd = {
      83             :         NULL, "adw", DV_DULL
      84             : };
      85             : 
      86             : /******************************************************************************/
      87             : /*                       DMA Mapping for Control Blocks                       */
      88             : /******************************************************************************/
      89             : 
      90             : 
      91             : int
      92           0 : adw_alloc_controls(ADW_SOFTC *sc)
      93             : {
      94           0 :         bus_dma_segment_t seg;
      95           0 :         int             error, rseg;
      96             : 
      97             :         /*
      98             :          * Allocate the control structure.
      99             :          */
     100           0 :         if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control),
     101           0 :             NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) != 0) {
     102           0 :                 printf("%s: unable to allocate control structures,"
     103           0 :                        " error = %d\n", sc->sc_dev.dv_xname, error);
     104           0 :                 return (error);
     105             :         }
     106           0 :         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
     107             :                    sizeof(struct adw_control), (caddr_t *) & sc->sc_control,
     108           0 :                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
     109           0 :                 printf("%s: unable to map control structures, error = %d\n",
     110           0 :                        sc->sc_dev.dv_xname, error);
     111           0 :                 return (error);
     112             :         }
     113             : 
     114             :         /*
     115             :          * Create and load the DMA map used for the control blocks.
     116             :          */
     117           0 :         if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adw_control),
     118             :                            1, sizeof(struct adw_control), 0, BUS_DMA_NOWAIT,
     119           0 :                                        &sc->sc_dmamap_control)) != 0) {
     120           0 :                 printf("%s: unable to create control DMA map, error = %d\n",
     121           0 :                        sc->sc_dev.dv_xname, error);
     122           0 :                 return (error);
     123             :         }
     124           0 :         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
     125             :                            sc->sc_control, sizeof(struct adw_control), NULL,
     126           0 :                                      BUS_DMA_NOWAIT)) != 0) {
     127           0 :                 printf("%s: unable to load control DMA map, error = %d\n",
     128           0 :                        sc->sc_dev.dv_xname, error);
     129           0 :                 return (error);
     130             :         }
     131             : 
     132           0 :         return (0);
     133           0 : }
     134             : 
     135             : 
     136             : int
     137           0 : adw_alloc_carriers(ADW_SOFTC *sc)
     138             : {
     139           0 :         bus_dma_segment_t seg;
     140           0 :         int             error, rseg;
     141             : 
     142             :         /*
     143             :          * Allocate the control structure.
     144             :          */
     145           0 :         sc->sc_control->carriers = 
     146           0 :                 malloc(ADW_MAX_CARRIER * sizeof(ADW_CARRIER), M_DEVBUF,
     147             :                        M_NOWAIT);
     148           0 :         if (sc->sc_control->carriers == NULL)
     149           0 :                 return (ENOMEM);
     150             : 
     151             : 
     152           0 :         if ((error = bus_dmamem_alloc(sc->sc_dmat,
     153             :                         sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
     154           0 :                         0x10, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
     155           0 :                 printf("%s: unable to allocate carrier structures,"
     156           0 :                        " error = %d\n", sc->sc_dev.dv_xname, error);
     157           0 :                 return (error);
     158             :         }
     159           0 :         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
     160             :                         sizeof(ADW_CARRIER) * ADW_MAX_CARRIER,
     161             :                         (caddr_t *) &sc->sc_control->carriers,
     162           0 :                         BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
     163           0 :                 printf("%s: unable to map carrier structures,"
     164           0 :                         " error = %d\n", sc->sc_dev.dv_xname, error);
     165           0 :                 return (error);
     166             :         }
     167             : 
     168             :         /*
     169             :          * Create and load the DMA map used for the control blocks.
     170             :          */
     171           0 :         if ((error = bus_dmamap_create(sc->sc_dmat,
     172             :                         sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 1,
     173             :                         sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, 0,BUS_DMA_NOWAIT,
     174           0 :                         &sc->sc_dmamap_carrier)) != 0) {
     175           0 :                 printf("%s: unable to create carriers DMA map,"
     176           0 :                         " error = %d\n", sc->sc_dev.dv_xname, error);
     177           0 :                 return (error);
     178             :         }
     179           0 :         if ((error = bus_dmamap_load(sc->sc_dmat,
     180             :                         sc->sc_dmamap_carrier, sc->sc_control->carriers,
     181             :                         sizeof(ADW_CARRIER) * ADW_MAX_CARRIER, NULL,
     182           0 :                         BUS_DMA_NOWAIT)) != 0) {
     183           0 :                 printf("%s: unable to load carriers DMA map,"
     184           0 :                         " error = %d\n", sc->sc_dev.dv_xname, error);
     185           0 :                 return (error);
     186             :         }
     187             : 
     188           0 :         return (0);
     189           0 : }
     190             : 
     191             : 
     192             : /******************************************************************************/
     193             : /*                           Control Blocks routines                          */
     194             : /******************************************************************************/
     195             : 
     196             : 
     197             : /*
     198             :  * Create a set of ccbs and add them to the free list.  Called once
     199             :  * by adw_init().  We return the number of CCBs successfully created.
     200             :  */
     201             : int
     202           0 : adw_create_ccbs(ADW_SOFTC *sc, ADW_CCB *ccbstore, int count)
     203             : {
     204             :         ADW_CCB        *ccb;
     205             :         int             i, error;
     206             : 
     207           0 :         for (i = 0; i < count; i++) {
     208           0 :                 ccb = &ccbstore[i];
     209           0 :                 if ((error = adw_init_ccb(sc, ccb)) != 0) {
     210           0 :                         printf("%s: unable to initialize ccb, error = %d\n",
     211           0 :                                sc->sc_dev.dv_xname, error);
     212           0 :                         return (i);
     213             :                 }
     214           0 :                 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
     215             :         }
     216             : 
     217           0 :         return (i);
     218           0 : }
     219             : 
     220             : 
     221             : /*
     222             :  * A ccb is put onto the free list.
     223             :  */
     224             : void
     225           0 : adw_ccb_free(void *xsc, void *xccb)
     226             : {
     227           0 :         ADW_SOFTC *sc = xsc;
     228           0 :         ADW_CCB *ccb = xccb;
     229             : 
     230           0 :         adw_reset_ccb(ccb);
     231             : 
     232           0 :         mtx_enter(&sc->sc_ccb_mtx);
     233           0 :         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
     234           0 :         mtx_leave(&sc->sc_ccb_mtx);
     235           0 : }
     236             : 
     237             : 
     238             : void
     239           0 : adw_reset_ccb(ADW_CCB *ccb)
     240             : {
     241             : 
     242           0 :         ccb->flags = 0;
     243           0 : }
     244             : 
     245             : 
     246             : int
     247           0 : adw_init_ccb(ADW_SOFTC *sc, ADW_CCB *ccb)
     248             : {
     249             :         int     hashnum, error;
     250             : 
     251             :         /*
     252             :          * Create the DMA map for this CCB.
     253             :          */
     254           0 :         error = bus_dmamap_create(sc->sc_dmat,
     255             :                                   (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
     256             :                          ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE,
     257             :                    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
     258           0 :         if (error) {
     259           0 :                 printf("%s: unable to create CCB DMA map, error = %d\n",
     260           0 :                        sc->sc_dev.dv_xname, error);
     261           0 :                 return (error);
     262             :         }
     263             : 
     264             :         /*
     265             :          * put in the phystokv hash table
     266             :          * Never gets taken out.
     267             :          */
     268           0 :         ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
     269           0 :             ADW_CCB_OFF(ccb);
     270           0 :         hashnum = CCB_HASH(ccb->hashkey);
     271           0 :         ccb->nexthash = sc->sc_ccbhash[hashnum];
     272           0 :         sc->sc_ccbhash[hashnum] = ccb;
     273           0 :         adw_reset_ccb(ccb);
     274           0 :         return (0);
     275           0 : }
     276             : 
     277             : 
     278             : /*
     279             :  * Get a free ccb
     280             :  *
     281             :  * If there are none, see if we can allocate a new one
     282             :  */
     283             : void *
     284           0 : adw_ccb_alloc(void *xsc)
     285             : {
     286           0 :         ADW_SOFTC *sc = xsc;
     287             :         ADW_CCB *ccb;
     288             : 
     289           0 :         mtx_enter(&sc->sc_ccb_mtx);
     290           0 :         ccb = TAILQ_FIRST(&sc->sc_free_ccb);
     291           0 :         if (ccb) {
     292           0 :                 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
     293           0 :                 ccb->flags |= CCB_ALLOC;
     294           0 :         }
     295           0 :         mtx_leave(&sc->sc_ccb_mtx);
     296             : 
     297           0 :         return (ccb);
     298             : }
     299             : 
     300             : 
     301             : /*
     302             :  * Given a physical address, find the ccb that it corresponds to.
     303             :  */
     304             : ADW_CCB *
     305           0 : adw_ccb_phys_kv(ADW_SOFTC *sc, u_int32_t ccb_phys)
     306             : {
     307           0 :         int hashnum = CCB_HASH(ccb_phys);
     308           0 :         ADW_CCB *ccb = sc->sc_ccbhash[hashnum];
     309             : 
     310           0 :         while (ccb) {
     311           0 :                 if (ccb->hashkey == ccb_phys)
     312             :                         break;
     313           0 :                 ccb = ccb->nexthash;
     314             :         }
     315           0 :         return (ccb);
     316             : }
     317             : 
     318             : 
     319             : /*
     320             :  * Queue a CCB to be sent to the controller, and send it if possible.
     321             :  */
     322             : int
     323           0 : adw_queue_ccb(ADW_SOFTC *sc, ADW_CCB *ccb, int retry)
     324             : {
     325             :         int             errcode = ADW_SUCCESS;
     326             : 
     327           0 :         if(!retry) {
     328           0 :                 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
     329           0 :         }
     330             : 
     331           0 :         while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
     332             : 
     333           0 :                 errcode = AdwExeScsiQueue(sc, &ccb->scsiq);
     334           0 :                 switch(errcode) {
     335             :                 case ADW_SUCCESS:
     336             :                         break;
     337             : 
     338             :                 case ADW_BUSY:
     339           0 :                         printf("ADW_BUSY\n");
     340           0 :                         return(ADW_BUSY);
     341             : 
     342             :                 case ADW_ERROR:
     343           0 :                         printf("ADW_ERROR\n");
     344           0 :                         TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
     345           0 :                         return(ADW_ERROR);
     346             :                 }
     347             : 
     348           0 :                 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
     349           0 :                 TAILQ_INSERT_TAIL(&sc->sc_pending_ccb, ccb, chain);
     350             : 
     351             :                 /* ALWAYS initialize stimeout, lest it contain garbage! */
     352           0 :                 timeout_set(&ccb->xs->stimeout, adw_timeout, ccb);
     353           0 :                 if ((ccb->xs->flags & SCSI_POLL) == 0)
     354           0 :                         timeout_add_msec(&ccb->xs->stimeout, ccb->timeout);
     355             :         }
     356             : 
     357           0 :         return(errcode);
     358           0 : }
     359             : 
     360             : 
     361             : /******************************************************************************/
     362             : /*                       SCSI layer interfacing routines                      */
     363             : /******************************************************************************/
     364             : 
     365             : 
     366             : int
     367           0 : adw_init(ADW_SOFTC *sc)
     368             : {
     369             :         u_int16_t       warn_code;
     370             : 
     371             : 
     372           0 :         sc->cfg.lib_version = (ADW_LIB_VERSION_MAJOR << 8) |
     373             :                 ADW_LIB_VERSION_MINOR;
     374           0 :         sc->cfg.chip_version =
     375           0 :                 ADW_GET_CHIP_VERSION(sc->sc_iot, sc->sc_ioh, sc->bus_type);
     376             : 
     377             :         /*
     378             :          * Reset the chip to start and allow register writes.
     379             :          */
     380           0 :         if (ADW_FIND_SIGNATURE(sc->sc_iot, sc->sc_ioh) == 0) {
     381           0 :                 panic("adw_init: adw_find_signature failed");
     382             :         } else {
     383           0 :                 AdwResetChip(sc->sc_iot, sc->sc_ioh);
     384             : 
     385           0 :                 warn_code = AdwInitFromEEPROM(sc);
     386             : 
     387           0 :                 if (warn_code & ADW_WARN_EEPROM_CHKSUM)
     388           0 :                         printf("%s: Bad checksum found. "
     389             :                                "Setting default values\n",
     390           0 :                                sc->sc_dev.dv_xname);
     391           0 :                 if (warn_code & ADW_WARN_EEPROM_TERMINATION)
     392           0 :                         printf("%s: Bad bus termination setting."
     393             :                                "Using automatic termination.\n",
     394           0 :                                sc->sc_dev.dv_xname);
     395             :         }
     396             : 
     397           0 :         sc->isr_callback = (ADW_CALLBACK) adw_isr_callback;
     398           0 :         sc->async_callback = (ADW_CALLBACK) adw_async_callback;
     399             : 
     400           0 :         return 0;
     401             : }
     402             : 
     403             : 
     404             : void
     405           0 : adw_attach(ADW_SOFTC *sc)
     406             : {
     407           0 :         struct scsibus_attach_args      saa;
     408             :         int                             i, error;
     409             : 
     410             : 
     411           0 :         TAILQ_INIT(&sc->sc_free_ccb);
     412           0 :         TAILQ_INIT(&sc->sc_waiting_ccb);
     413           0 :         TAILQ_INIT(&sc->sc_pending_ccb);
     414             : 
     415           0 :         mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
     416           0 :         scsi_iopool_init(&sc->sc_iopool, sc, adw_ccb_alloc, adw_ccb_free);
     417             : 
     418             :         /*
     419             :          * Allocate the Control Blocks.
     420             :          */
     421           0 :         error = adw_alloc_controls(sc);
     422           0 :         if (error)
     423           0 :                 return; /* (error) */ ;
     424             : 
     425             :         /*
     426             :          * Create and initialize the Control Blocks.
     427             :          */
     428           0 :         i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB);
     429           0 :         if (i == 0) {
     430           0 :                 printf("%s: unable to create Control Blocks\n",
     431           0 :                        sc->sc_dev.dv_xname);
     432           0 :                 return; /* (ENOMEM) */ ;
     433           0 :         } else if (i != ADW_MAX_CCB) {
     434           0 :                 printf("%s: WARNING: only %d of %d Control Blocks"
     435             :                        " created\n",
     436           0 :                        sc->sc_dev.dv_xname, i, ADW_MAX_CCB);
     437           0 :         }
     438             : 
     439             :         /*
     440             :          * Create and initialize the Carriers.
     441             :          */
     442           0 :         error = adw_alloc_carriers(sc);
     443           0 :         if (error)
     444           0 :                 return; /* (error) */ ;
     445             : 
     446             :         /*
     447             :          * Zero's the freeze_device status
     448             :          */
     449           0 :          bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
     450             : 
     451             :         /*
     452             :          * Initialize the adapter
     453             :          */
     454           0 :         switch (AdwInitDriver(sc)) {
     455             :         case ADW_IERR_BIST_PRE_TEST:
     456           0 :                 panic("%s: BIST pre-test error",
     457           0 :                       sc->sc_dev.dv_xname);
     458             :                 break;
     459             : 
     460             :         case ADW_IERR_BIST_RAM_TEST:
     461           0 :                 panic("%s: BIST RAM test error",
     462           0 :                       sc->sc_dev.dv_xname);
     463             :                 break;
     464             : 
     465             :         case ADW_IERR_MCODE_CHKSUM:
     466           0 :                 panic("%s: Microcode checksum error",
     467           0 :                       sc->sc_dev.dv_xname);
     468             :                 break;
     469             : 
     470             :         case ADW_IERR_ILLEGAL_CONNECTION:
     471           0 :                 panic("%s: All three connectors are in use",
     472           0 :                       sc->sc_dev.dv_xname);
     473             :                 break;
     474             : 
     475             :         case ADW_IERR_REVERSED_CABLE:
     476           0 :                 panic("%s: Cable is reversed",
     477           0 :                       sc->sc_dev.dv_xname);
     478             :                 break;
     479             : 
     480             :         case ADW_IERR_HVD_DEVICE:
     481           0 :                 panic("%s: HVD attached to LVD connector",
     482           0 :                       sc->sc_dev.dv_xname);
     483             :                 break;
     484             : 
     485             :         case ADW_IERR_SINGLE_END_DEVICE:
     486           0 :                 panic("%s: single-ended device is attached to"
     487             :                       " one of the connectors",
     488           0 :                       sc->sc_dev.dv_xname);
     489             :                 break;
     490             : 
     491             :         case ADW_IERR_NO_CARRIER:
     492           0 :                 panic("%s: unable to create Carriers",
     493           0 :                       sc->sc_dev.dv_xname);
     494             :                 break;
     495             : 
     496             :         case ADW_WARN_BUSRESET_ERROR:
     497           0 :                 printf("%s: WARNING: Bus Reset Error\n",
     498           0 :                       sc->sc_dev.dv_xname);
     499           0 :                 break;
     500             :         }
     501             : 
     502             :         /*
     503             :          * Fill in the adapter.
     504             :          */
     505           0 :         sc->sc_adapter.scsi_cmd = adw_scsi_cmd;
     506           0 :         sc->sc_adapter.scsi_minphys = adw_minphys;
     507             : 
     508             :         /*
     509             :          * fill in the prototype scsi_link.
     510             :          */
     511           0 :         sc->sc_link.adapter_softc = sc;
     512           0 :         sc->sc_link.adapter_target = sc->chip_scsi_id;
     513           0 :         sc->sc_link.adapter = &sc->sc_adapter;
     514           0 :         sc->sc_link.openings = 4;
     515           0 :         sc->sc_link.adapter_buswidth = ADW_MAX_TID+1;
     516           0 :         sc->sc_link.pool = &sc->sc_iopool;
     517             : 
     518           0 :         bzero(&saa, sizeof(saa));
     519           0 :         saa.saa_sc_link = &sc->sc_link;
     520             : 
     521           0 :         config_found(&sc->sc_dev, &saa, scsiprint);
     522           0 : }
     523             : 
     524             : 
     525             : void
     526           0 : adw_minphys(struct buf *bp, struct scsi_link *sl)
     527             : {
     528             : 
     529           0 :         if (bp->b_bcount > ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE))
     530           0 :                 bp->b_bcount = ((ADW_MAX_SG_LIST - 1) * PAGE_SIZE);
     531           0 :         minphys(bp);
     532           0 : }
     533             : 
     534             : 
     535             : /*
     536             :  * start a scsi operation given the command and the data address.
     537             :  * Also needs the unit, target and lu.
     538             :  */
     539             : void
     540           0 : adw_scsi_cmd(struct scsi_xfer *xs)
     541             : {
     542           0 :         struct scsi_link *sc_link = xs->sc_link;
     543           0 :         ADW_SOFTC      *sc = sc_link->adapter_softc;
     544             :         ADW_CCB        *ccb;
     545             :         int             s, nowait = 0, retry = 0;
     546             :         int             flags;
     547             : 
     548             :         /*
     549             :          * get a ccb to use. If the transfer
     550             :          * is from a buf (possibly from interrupt time)
     551             :          * then we can't allow it to sleep
     552             :          */
     553             : 
     554           0 :         flags = xs->flags;
     555           0 :         if (nowait)
     556           0 :                 flags |= SCSI_NOSLEEP;
     557           0 :         ccb = xs->io;
     558             : 
     559           0 :         ccb->xs = xs;
     560           0 :         ccb->timeout = xs->timeout;
     561             : 
     562           0 :         if (adw_build_req(xs, ccb, flags)) {
     563             : retryagain:
     564           0 :                 s = splbio();
     565           0 :                 retry = adw_queue_ccb(sc, ccb, retry);
     566           0 :                 splx(s);
     567             : 
     568           0 :                 switch(retry) {
     569             :                 case ADW_BUSY:
     570           0 :                         goto retryagain;
     571             : 
     572             :                 case ADW_ERROR:
     573           0 :                         xs->error = XS_DRIVER_STUFFUP;
     574           0 :                         scsi_done(xs);
     575           0 :                         return;
     576             :                 }
     577             : 
     578             :                 /*
     579             :                  * Usually return SUCCESSFULLY QUEUED
     580             :                  */
     581           0 :                 if ((xs->flags & SCSI_POLL) == 0)
     582           0 :                         return;
     583             : 
     584             :                 /*
     585             :                  * If we can't use interrupts, poll on completion
     586             :                  */
     587           0 :                 if (adw_poll(sc, xs, ccb->timeout)) {
     588           0 :                         adw_timeout(ccb);
     589           0 :                         if (adw_poll(sc, xs, ccb->timeout))
     590           0 :                                 adw_timeout(ccb);
     591             :                 }
     592             :         } else {
     593             :                 /* adw_build_req() has set xs->error already */
     594           0 :                 scsi_done(xs);
     595             :         }
     596           0 : }
     597             : 
     598             : 
     599             : /*
     600             :  * Build a request structure for the Wide Boards.
     601             :  */
     602             : int
     603           0 : adw_build_req(struct scsi_xfer *xs, ADW_CCB *ccb, int flags)
     604             : {
     605           0 :         struct scsi_link *sc_link = xs->sc_link;
     606           0 :         ADW_SOFTC      *sc = sc_link->adapter_softc;
     607           0 :         bus_dma_tag_t   dmat = sc->sc_dmat;
     608             :         ADW_SCSI_REQ_Q *scsiqp;
     609             :         int             error;
     610             : 
     611           0 :         scsiqp = &ccb->scsiq;
     612           0 :         bzero(scsiqp, sizeof(ADW_SCSI_REQ_Q));
     613             : 
     614             :         /*
     615             :          * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the
     616             :          * physical CCB structure.
     617             :          */
     618           0 :         scsiqp->ccb_ptr = ccb->hashkey;
     619             : 
     620             :         /*
     621             :          * Build the ADW_SCSI_REQ_Q request.
     622             :          */
     623             : 
     624             :         /*
     625             :          * Set CDB length and copy it to the request structure.
     626             :          * For wide  boards a CDB length maximum of 16 bytes
     627             :          * is supported.
     628             :          */
     629           0 :         scsiqp->cdb_len = xs->cmdlen;
     630           0 :         bcopy((caddr_t)xs->cmd, &scsiqp->cdb, 12);
     631           0 :         bcopy((caddr_t)xs->cmd + 12, &scsiqp->cdb16, 4);
     632             : 
     633           0 :         scsiqp->target_id = sc_link->target;
     634           0 :         scsiqp->target_lun = sc_link->lun;
     635             : 
     636           0 :         scsiqp->vsense_addr = &ccb->scsi_sense;
     637           0 :         scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
     638           0 :                         ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense);
     639           0 :         scsiqp->sense_len = sizeof(struct scsi_sense_data);
     640             : 
     641             :         /*
     642             :          * Build ADW_SCSI_REQ_Q for a scatter-gather buffer command.
     643             :          */
     644           0 :         if (xs->datalen) {
     645             :                 /*
     646             :                  * Map the DMA transfer.
     647             :                  */
     648           0 :                 error = bus_dmamap_load(dmat,
     649             :                       ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
     650             :                         (flags & SCSI_NOSLEEP) ?
     651             :                         BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
     652             : 
     653           0 :                 if (error) {
     654           0 :                         if (error == EFBIG) {
     655           0 :                                 printf("%s: adw_scsi_cmd, more than %d dma"
     656             :                                        " segments\n",
     657             :                                        sc->sc_dev.dv_xname, ADW_MAX_SG_LIST);
     658           0 :                         } else {
     659           0 :                                 printf("%s: adw_scsi_cmd, error %d loading"
     660             :                                        " dma map\n",
     661             :                                        sc->sc_dev.dv_xname, error);
     662             :                         }
     663             : 
     664           0 :                         xs->error = XS_DRIVER_STUFFUP;
     665           0 :                         return (0);
     666             :                 }
     667           0 :                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
     668             :                     0, ccb->dmamap_xfer->dm_mapsize,
     669             :                     (xs->flags & SCSI_DATA_IN) ?
     670             :                     BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
     671             : 
     672             :                 /*
     673             :                  * Build scatter-gather list.
     674             :                  */
     675           0 :                 scsiqp->data_cnt = xs->datalen;
     676           0 :                 scsiqp->vdata_addr = xs->data;
     677           0 :                 scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr;
     678           0 :                 bzero(ccb->sg_block, sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK);
     679           0 :                 adw_build_sglist(ccb, scsiqp, ccb->sg_block);
     680           0 :         } else {
     681             :                 /*
     682             :                  * No data xfer, use non S/G values.
     683             :                  */
     684           0 :                 scsiqp->data_cnt = 0;
     685           0 :                 scsiqp->vdata_addr = 0;
     686           0 :                 scsiqp->data_addr = 0;
     687             :         }
     688             : 
     689           0 :         return (1);
     690           0 : }
     691             : 
     692             : 
     693             : /*
     694             :  * Build scatter-gather list for Wide Boards.
     695             :  */
     696             : void
     697           0 : adw_build_sglist(ADW_CCB *ccb, ADW_SCSI_REQ_Q *scsiqp, ADW_SG_BLOCK *sg_block)
     698             : {
     699             :         u_long          sg_block_next_addr;     /* block and its next */
     700             :         u_int32_t       sg_block_physical_addr;
     701             :         int             i;      /* how many SG entries */
     702           0 :         bus_dma_segment_t *sg_list = &ccb->dmamap_xfer->dm_segs[0];
     703           0 :         int             sg_elem_cnt = ccb->dmamap_xfer->dm_nsegs;
     704             : 
     705             : 
     706           0 :         sg_block_next_addr = (u_long) sg_block; /* allow math operation */
     707           0 :         sg_block_physical_addr = ccb->hashkey +
     708             :             offsetof(struct adw_ccb, sg_block[0]);
     709           0 :         scsiqp->sg_real_addr = sg_block_physical_addr;
     710             : 
     711             :         /*
     712             :          * If there are more than NO_OF_SG_PER_BLOCK dma segments (hw sg-list)
     713             :          * then split the request into multiple sg-list blocks.
     714             :          */
     715             : 
     716           0 :         do {
     717           0 :                 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
     718           0 :                         sg_block->sg_list[i].sg_addr = sg_list->ds_addr;
     719           0 :                         sg_block->sg_list[i].sg_count = sg_list->ds_len;
     720             : 
     721           0 :                         if (--sg_elem_cnt == 0) {
     722             :                                 /* last entry, get out */
     723           0 :                                 sg_block->sg_cnt = i + 1;
     724           0 :                                 sg_block->sg_ptr = 0; /* next link = NULL */
     725             :                                 return;
     726             :                         }
     727           0 :                         sg_list++;
     728             :                 }
     729           0 :                 sg_block_next_addr += sizeof(ADW_SG_BLOCK);
     730           0 :                 sg_block_physical_addr += sizeof(ADW_SG_BLOCK);
     731             : 
     732           0 :                 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
     733           0 :                 sg_block->sg_ptr = sg_block_physical_addr;
     734           0 :                 sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */
     735           0 :         } while (1);
     736           0 : }
     737             : 
     738             : 
     739             : /******************************************************************************/
     740             : /*                       Interrupts and TimeOut routines                      */
     741             : /******************************************************************************/
     742             : 
     743             : 
     744             : int
     745           0 : adw_intr(void *arg)
     746             : {
     747           0 :         ADW_SOFTC      *sc = arg;
     748             : 
     749             : 
     750           0 :         if(AdwISR(sc) != ADW_FALSE) {
     751           0 :                 return (1);
     752             :         }
     753             : 
     754           0 :         return (0);
     755           0 : }
     756             : 
     757             : 
     758             : /*
     759             :  * Poll a particular unit, looking for a particular xs
     760             :  */
     761             : int
     762           0 : adw_poll(ADW_SOFTC *sc, struct scsi_xfer *xs, int count)
     763             : {
     764             :         int s;
     765             : 
     766             :         /* timeouts are in msec, so we loop in 1000 usec cycles */
     767           0 :         while (count > 0) {
     768           0 :                 s = splbio();
     769           0 :                 adw_intr(sc);
     770           0 :                 splx(s);
     771           0 :                 if (xs->flags & ITSDONE) {
     772           0 :                         if ((xs->cmd->opcode == INQUIRY)
     773           0 :                             && (xs->sc_link->lun == 0)
     774           0 :                             && (xs->error == XS_NOERROR))
     775           0 :                                 adw_print_info(sc, xs->sc_link->target);
     776           0 :                         return (0);
     777             :                 }
     778           0 :                 delay(1000);    /* only happens in boot so ok */
     779           0 :                 count--;
     780             :         }
     781           0 :         return (1);
     782           0 : }
     783             : 
     784             : 
     785             : void
     786           0 : adw_timeout(void *arg)
     787             : {
     788           0 :         ADW_CCB        *ccb = arg;
     789           0 :         struct scsi_xfer *xs = ccb->xs;
     790           0 :         struct scsi_link *sc_link = xs->sc_link;
     791           0 :         ADW_SOFTC      *sc = sc_link->adapter_softc;
     792             :         int             s;
     793             : 
     794           0 :         sc_print_addr(sc_link);
     795           0 :         printf("timed out");
     796             : 
     797           0 :         s = splbio();
     798             : 
     799           0 :         if (ccb->flags & CCB_ABORTED) {
     800             :         /*
     801             :          * Abort Timed Out
     802             :          *
     803             :          * No more opportunities. Lets try resetting the bus and
     804             :          * reinitialize the host adapter.
     805             :          */
     806           0 :                 timeout_del(&xs->stimeout);
     807           0 :                 printf(" AGAIN. Resetting SCSI Bus\n");
     808           0 :                 adw_reset_bus(sc);
     809           0 :                 splx(s);
     810           0 :                 return;
     811           0 :         } else if (ccb->flags & CCB_ABORTING) {
     812             :         /*
     813             :          * Abort the operation that has timed out.
     814             :          *
     815             :          * Second opportunity.
     816             :          */
     817             :                 printf("\n");
     818             :                 xs->error = XS_TIMEOUT;
     819           0 :                 ccb->flags |= CCB_ABORTED;
     820             : #if 0
     821             :                 /*
     822             :                  * - XXX - 3.3a microcode is BROKEN!!!
     823             :                  *
     824             :                  * We cannot abort a CCB, so we can only hope the command
     825             :                  * get completed before the next timeout, otherwise a
     826             :                  * Bus Reset will arrive inexorably.
     827             :                  */
     828             :                 /*
     829             :                  * ADW_ABORT_CCB() makes the board to generate an interrupt
     830             :                  *
     831             :                  * - XXX - The above assertion MUST be verified (and this
     832             :                  *         code changed as well [callout_*()]), when the
     833             :                  *         ADW_ABORT_CCB will be working again
     834             :                  */
     835             :                 ADW_ABORT_CCB(sc, ccb);
     836             : #endif
     837             :                 /*
     838             :                  * waiting for multishot callout_reset() let's restart it
     839             :                  * by hand so the next time a timeout event will occur
     840             :                  * we will reset the bus.
     841             :                  */
     842           0 :                 timeout_add_msec(&xs->stimeout, ccb->timeout);
     843           0 :         } else {
     844             :         /*
     845             :          * Abort the operation that has timed out.
     846             :          *
     847             :          * First opportunity.
     848             :          */
     849             :                 printf("\n");
     850             :                 xs->error = XS_TIMEOUT;
     851           0 :                 ccb->flags |= CCB_ABORTING;
     852             : #if 0
     853             :                 /*
     854             :                  * - XXX - 3.3a microcode is BROKEN!!!
     855             :                  *
     856             :                  * We cannot abort a CCB, so we can only hope the command
     857             :                  * get completed before the next 2 timeout, otherwise a
     858             :                  * Bus Reset will arrive inexorably.
     859             :                  */
     860             :                 /*
     861             :                  * ADW_ABORT_CCB() makes the board to generate an interrupt
     862             :                  *
     863             :                  * - XXX - The above assertion MUST be verified (and this
     864             :                  *         code changed as well [callout_*()]), when the
     865             :                  *         ADW_ABORT_CCB will be working again
     866             :                  */
     867             :                 ADW_ABORT_CCB(sc, ccb);
     868             : #endif
     869             :                 /*
     870             :                  * waiting for multishot callout_reset() let's restart it
     871             :                  * by hand so to give a second opportunity to the command
     872             :                  * which timed-out.
     873             :                  */
     874           0 :                 timeout_add_msec(&xs->stimeout, ccb->timeout);
     875             :         }
     876             : 
     877           0 :         splx(s);
     878           0 : }
     879             : 
     880             : 
     881             : void
     882           0 : adw_reset_bus(ADW_SOFTC *sc) 
     883             : {
     884             :         ADW_CCB *ccb;
     885             :         int      s;
     886             : 
     887           0 :         s = splbio();
     888           0 :         AdwResetSCSIBus(sc); /* XXX - should check return value? */
     889           0 :         while((ccb = TAILQ_LAST(&sc->sc_pending_ccb,
     890           0 :                         adw_pending_ccb)) != NULL) {
     891           0 :                 timeout_del(&ccb->xs->stimeout);
     892           0 :                 TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
     893           0 :                 TAILQ_INSERT_HEAD(&sc->sc_waiting_ccb, ccb, chain);
     894             :         }
     895             : 
     896           0 :         bzero(sc->sc_freeze_dev, sizeof(sc->sc_freeze_dev));
     897           0 :         adw_queue_ccb(sc, TAILQ_FIRST(&sc->sc_waiting_ccb), 1);
     898             : 
     899           0 :         splx(s);
     900           0 : }
     901             : 
     902             : 
     903             : /******************************************************************************/
     904             : /*              Host Adapter and Peripherals Information Routines             */
     905             : /******************************************************************************/
     906             : 
     907             : 
     908             : void
     909           0 : adw_print_info(ADW_SOFTC *sc, int tid)
     910             : {
     911           0 :         bus_space_handle_t ioh = sc->sc_ioh;
     912           0 :         bus_space_tag_t iot = sc->sc_iot;
     913             :         u_int16_t hshk_cfg, able_mask, period = 0;
     914             : 
     915             :         /* hshk/HSHK means 'handskake' */
     916             : 
     917           0 :         ADW_READ_WORD_LRAM(iot, ioh,
     918             :             ADW_MC_DEVICE_HSHK_CFG_TABLE + (2 * tid), hshk_cfg);
     919             : 
     920           0 :         ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_WDTR_ABLE, able_mask);
     921           0 :         if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
     922           0 :                 hshk_cfg &= ~HSHK_CFG_WIDE_XFR;
     923             : 
     924           0 :         ADW_READ_WORD_LRAM(iot, ioh, ADW_MC_SDTR_ABLE, able_mask);
     925           0 :         if ((able_mask & ADW_TID_TO_TIDMASK(tid)) == 0)
     926           0 :                 hshk_cfg &= ~HSHK_CFG_OFFSET;
     927             : 
     928           0 :         printf("%s: target %d using %d bit ", sc->sc_dev.dv_xname, tid,
     929           0 :             (hshk_cfg & HSHK_CFG_WIDE_XFR) ? 16 : 8);
     930             : 
     931           0 :         if ((hshk_cfg & HSHK_CFG_OFFSET) == 0)
     932           0 :                 printf("async ");
     933             :         else {
     934           0 :                 period = (hshk_cfg & 0x1f00) >> 8;
     935           0 :                 switch (period) {
     936             :                 case 0x11: 
     937           0 :                         printf("80.0 ");
     938           0 :                         break;
     939             :                 case 0x10:
     940           0 :                         printf("40.0 ");
     941           0 :                         break;
     942             :                 default:
     943           0 :                         period = (period * 25) + 50;
     944           0 :                         printf("%d.%d ", 1000/period, ADW_TENTHS(1000, period));
     945           0 :                         break;
     946             :                 }
     947           0 :                 printf("MHz %d REQ/ACK offset ", hshk_cfg & HSHK_CFG_OFFSET);
     948             :         }
     949             : 
     950           0 :         printf("xfers\n");
     951           0 : }       
     952             : 
     953             : 
     954             : /******************************************************************************/
     955             : /*                        WIDE boards Interrupt callbacks                     */
     956             : /******************************************************************************/
     957             : 
     958             : 
     959             : /*
     960             :  * adw_isr_callback() - Second Level Interrupt Handler called by AdwISR()
     961             :  *
     962             :  * Interrupt callback function for the Wide SCSI Adw Library.
     963             :  *
     964             :  * Notice:
     965             :  * Interrupts are disabled by the caller (AdwISR() function), and will be
     966             :  * enabled at the end of the caller.
     967             :  */
     968             : void
     969           0 : adw_isr_callback(ADW_SOFTC *sc, ADW_SCSI_REQ_Q *scsiq)
     970             : {
     971             :         bus_dma_tag_t   dmat;
     972             :         ADW_CCB        *ccb;
     973             :         struct scsi_xfer *xs;
     974             :         struct scsi_sense_data *s1, *s2;
     975             : 
     976             : 
     977           0 :         ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr);
     978           0 :         TAILQ_REMOVE(&sc->sc_pending_ccb, ccb, chain);
     979             : 
     980           0 :         if ((ccb->flags & CCB_ALLOC) == 0) {
     981           0 :                 panic("%s: unallocated ccb found on pending list!",
     982           0 :                     sc->sc_dev.dv_xname);
     983             :                 return;
     984             :         }
     985             : 
     986           0 :         xs = ccb->xs;
     987           0 :         timeout_del(&xs->stimeout);
     988             : 
     989             :         /*
     990             :          * If we were a data transfer, unload the map that described
     991             :          * the data buffer.
     992             :          */
     993           0 :         dmat = sc->sc_dmat;
     994           0 :         if (xs->datalen) {
     995           0 :                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
     996             :                     0, ccb->dmamap_xfer->dm_mapsize,
     997             :                     ((xs->flags & SCSI_DATA_IN) ?
     998             :                         BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE));
     999           0 :                 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
    1000           0 :         }
    1001             : 
    1002             :         /*
    1003             :          * 'done_status' contains the command's ending status.
    1004             :          * 'host_status' contains the host adapter status.
    1005             :          * 'scsi_status' contains the scsi peripheral status.
    1006             :          */
    1007             : 
    1008           0 :         sc->sc_freeze_dev[scsiq->target_id] = 0;
    1009           0 :         xs->status = scsiq->scsi_status;
    1010             : 
    1011           0 :         switch (scsiq->done_status) {
    1012             :         case QD_NO_ERROR: /* (scsi_status == 0) && (host_status == 0) */
    1013             : NO_ERROR:
    1014           0 :                 xs->resid = scsiq->data_cnt;
    1015           0 :                 xs->error = XS_NOERROR;
    1016           0 :                 break;
    1017             : 
    1018             :         case QD_WITH_ERROR:
    1019           0 :                 switch (scsiq->host_status) {
    1020             :                 case QHSTA_NO_ERROR:
    1021           0 :                         switch (scsiq->scsi_status) {
    1022             :                         case SCSI_COND_MET:
    1023             :                         case SCSI_INTERM:
    1024             :                         case SCSI_INTERM_COND_MET:
    1025             :                                 /*
    1026             :                                  * These non-zero status values are 
    1027             :                                  * not really error conditions.
    1028             :                                  *
    1029             :                                  * XXX - would it be too paranoid to 
    1030             :                                  *       add SCSI_OK here in
    1031             :                                  *       case the docs are wrong re
    1032             :                                  *       QD_NO_ERROR?
    1033             :                                  */
    1034             :                                 goto NO_ERROR;
    1035             : 
    1036             :                         case SCSI_CHECK:
    1037             :                         case SCSI_TERMINATED:
    1038             :                         case SCSI_ACA_ACTIVE:
    1039           0 :                                 s1 = &ccb->scsi_sense;
    1040           0 :                                 s2 = &xs->sense;
    1041           0 :                                 *s2 = *s1;
    1042           0 :                                 xs->error = XS_SENSE;
    1043           0 :                                 break;
    1044             : 
    1045             :                         case SCSI_BUSY:
    1046             :                         case SCSI_QUEUE_FULL:
    1047             :                         case SCSI_RESV_CONFLICT:
    1048           0 :                                 sc->sc_freeze_dev[scsiq->target_id] = 1;
    1049           0 :                                 xs->error = XS_BUSY;
    1050           0 :                                 break;
    1051             :                 
    1052             :                         default: /* scsiq->scsi_status value */
    1053           0 :                                 printf("%s: bad scsi_status: 0x%02x.\n"
    1054           0 :                                     ,sc->sc_dev.dv_xname
    1055             :                                     ,scsiq->scsi_status);
    1056           0 :                                 xs->error = XS_DRIVER_STUFFUP;
    1057           0 :                                 break;
    1058             :                         }
    1059             :                         break;
    1060             :                 
    1061             :                 case QHSTA_M_SEL_TIMEOUT:
    1062           0 :                         xs->error = XS_SELTIMEOUT;
    1063           0 :                         break;
    1064             : 
    1065             :                 case QHSTA_M_DIRECTION_ERR:
    1066             :                 case QHSTA_M_SXFR_OFF_UFLW:
    1067             :                 case QHSTA_M_SXFR_OFF_OFLW:
    1068             :                 case QHSTA_M_SXFR_XFR_OFLW:
    1069             :                 case QHSTA_M_QUEUE_ABORTED:
    1070             :                 case QHSTA_M_INVALID_DEVICE:
    1071             :                 case QHSTA_M_SGBACKUP_ERROR:
    1072             :                 case QHSTA_M_SXFR_DESELECTED:
    1073             :                 case QHSTA_M_SXFR_XFR_PH_ERR:
    1074             :                 case QHSTA_M_BUS_DEVICE_RESET:
    1075             :                 case QHSTA_M_NO_AUTO_REQ_SENSE:
    1076             :                 case QHSTA_M_BAD_CMPL_STATUS_IN:
    1077             :                 case QHSTA_M_SXFR_UNKNOWN_ERROR:
    1078             :                 case QHSTA_M_AUTO_REQ_SENSE_FAIL:
    1079             :                 case QHSTA_M_UNEXPECTED_BUS_FREE:
    1080           0 :                         printf("%s: host adapter error 0x%02x."
    1081             :                                " See adw(4).\n"
    1082           0 :                             ,sc->sc_dev.dv_xname, scsiq->host_status);
    1083           0 :                         xs->error = XS_DRIVER_STUFFUP;
    1084           0 :                         break;
    1085             : 
    1086             :                 case QHSTA_M_RDMA_PERR:
    1087             :                 case QHSTA_M_SXFR_WD_TMO:
    1088             :                 case QHSTA_M_WTM_TIMEOUT:
    1089             :                 case QHSTA_M_FROZEN_TIDQ:
    1090             :                 case QHSTA_M_SXFR_SDMA_ERR:
    1091             :                 case QHSTA_M_SXFR_SXFR_PERR:
    1092             :                 case QHSTA_M_SCSI_BUS_RESET:
    1093             :                 case QHSTA_M_DIRECTION_ERR_HUNG:
    1094             :                 case QHSTA_M_SCSI_BUS_RESET_UNSOL:
    1095             :                         /*
    1096             :                          * XXX - are all these cases really asking
    1097             :                          *       for a card reset? _BUS_RESET and
    1098             :                          *       _BUS_RESET_UNSOL added just to make
    1099             :                          *       sure the pending queue is cleared out
    1100             :                          *       in case card has lost track of them.
    1101             :                          */
    1102           0 :                         printf("%s: host adapter error 0x%02x,"
    1103             :                                " resetting bus. See adw(4).\n"
    1104           0 :                             ,sc->sc_dev.dv_xname, scsiq->host_status);
    1105           0 :                         adw_reset_bus(sc);
    1106           0 :                         xs->error = XS_RESET;
    1107           0 :                         break;
    1108             :                         
    1109             :                 default: /* scsiq->host_status value */
    1110             :                         /*
    1111             :                          * XXX - is a panic really appropriate here? If
    1112             :                          *       not, would it be better to make the 
    1113             :                          *       XS_DRIVER_STUFFUP case above the 
    1114             :                          *       default behaviour? Or XS_RESET?
    1115             :                          */
    1116           0 :                         panic("%s: bad host_status: 0x%02x"
    1117           0 :                             ,sc->sc_dev.dv_xname, scsiq->host_status);
    1118             :                         break;      
    1119             :                 }
    1120             :                 break;
    1121             : 
    1122             :         case QD_ABORTED_BY_HOST:
    1123           0 :                 xs->error = XS_DRIVER_STUFFUP;
    1124           0 :                 break;
    1125             : 
    1126             :         default: /* scsiq->done_status value */
    1127             :                 /*
    1128             :                  * XXX - would QD_NO_STATUS really mean the I/O is not
    1129             :                  *       done? and would that mean it should somehow be
    1130             :                  *       put back as a pending I/O?
    1131             :                  */
    1132           0 :                 printf("%s: bad done_status: 0x%02x"
    1133             :                        " (host_status: 0x%02x, scsi_status: 0x%02x)\n"
    1134           0 :                     ,sc->sc_dev.dv_xname
    1135             :                     ,scsiq->done_status
    1136           0 :                     ,scsiq->host_status
    1137           0 :                     ,scsiq->scsi_status);
    1138           0 :                 xs->error = XS_DRIVER_STUFFUP;
    1139           0 :                 break;
    1140             :         }
    1141             : 
    1142           0 :         scsi_done(xs);
    1143           0 : }
    1144             : 
    1145             : 
    1146             : /*
    1147             :  * adw_async_callback() - Adw Library asynchronous event callback function.
    1148             :  */
    1149             : void
    1150           0 : adw_async_callback(ADW_SOFTC *sc, u_int8_t code)
    1151             : {
    1152           0 :         switch (code) {
    1153             :         case ADW_ASYNC_SCSI_BUS_RESET_DET:
    1154             :                 /* The firmware detected a SCSI Bus reset. */
    1155           0 :                 printf("%s: SCSI Bus reset detected\n", sc->sc_dev.dv_xname);
    1156           0 :                 break;
    1157             : 
    1158             :         case ADW_ASYNC_RDMA_FAILURE:
    1159             :                 /*
    1160             :                  * Handle RDMA failure by resetting the SCSI Bus and
    1161             :                  * possibly the chip if it is unresponsive.
    1162             :                  */
    1163           0 :                 printf("%s: RDMA failure. Resetting the SCSI Bus and"
    1164           0 :                                 " the adapter\n", sc->sc_dev.dv_xname);
    1165           0 :                 adw_reset_bus(sc);
    1166           0 :                 break;
    1167             : 
    1168             :         case ADW_HOST_SCSI_BUS_RESET:
    1169             :                 /* Host generated SCSI bus reset occurred. */
    1170           0 :                 printf("%s: Host generated SCSI bus reset occurred\n",
    1171           0 :                                 sc->sc_dev.dv_xname);
    1172           0 :                 break;
    1173             : 
    1174             : 
    1175             :         case ADW_ASYNC_CARRIER_READY_FAILURE:
    1176             :                 /* 
    1177             :                  * Carrier Ready failure.
    1178             :                  *
    1179             :                  * A warning only - RISC too busy to realize it's been 
    1180             :                  * tickled. Occurs in normal operation under heavy
    1181             :                  * load, so a message is printed only when ADW_DEBUG'ing
    1182             :                  */
    1183             : #ifdef ADW_DEBUG
    1184             :                 printf("%s: Carrier Ready failure!\n", sc->sc_dev.dv_xname);
    1185             : #endif
    1186             :                 break;
    1187             : 
    1188             :         default:
    1189           0 :                 printf("%s: Unknown Async callback code (ignored): 0x%02x\n",
    1190           0 :                     sc->sc_dev.dv_xname, code);
    1191           0 :                 break;
    1192             :         }
    1193           0 : }

Generated by: LCOV version 1.13