The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/adw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 01358b658e4f24d2132cdc8828d088d4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.