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/buslogic/bt.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 /*-
    2  * Generic driver for the BusLogic MultiMaster SCSI host adapters
    3  * Product specific probe and attach routines can be found in:
    4  * sys/dev/buslogic/bt_isa.c    BT-54X, BT-445 cards
    5  * sys/dev/buslogic/bt_mca.c    BT-64X, SDC3211B, SDC3211F
    6  * sys/dev/buslogic/bt_eisa.c   BT-74X, BT-75x cards, SDC3222F
    7  * sys/dev/buslogic/bt_pci.c    BT-946, BT-948, BT-956, BT-958 cards
    8  *
    9  * Copyright (c) 1998, 1999 Justin T. Gibbs.
   10  * All rights reserved.
   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  *    without modification, immediately at the beginning of the file.
   18  * 2. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD$");
   36 
   37  /*
   38   * Special thanks to Leonard N. Zubkoff for writing such a complete and
   39   * well documented Mylex/BusLogic MultiMaster driver for Linux.  Support
   40   * in this driver for the wide range of MultiMaster controllers and
   41   * firmware revisions, with their otherwise undocumented quirks, would not
   42   * have been possible without his efforts.
   43   */
   44 
   45 #include <sys/param.h>
   46 #include <sys/conf.h>
   47 #include <sys/systm.h> 
   48 #include <sys/malloc.h>
   49 #include <sys/kernel.h>
   50 #include <sys/lock.h>
   51 #include <sys/module.h>
   52 #include <sys/mutex.h>
   53 #include <sys/sysctl.h>
   54 #include <sys/bus.h>
   55  
   56 #include <machine/bus.h>
   57 #include <sys/rman.h>
   58 
   59 #include <cam/cam.h>
   60 #include <cam/cam_ccb.h>
   61 #include <cam/cam_sim.h>
   62 #include <cam/cam_xpt_sim.h>
   63 #include <cam/cam_debug.h>
   64 
   65 #include <cam/scsi/scsi_message.h>
   66 
   67 #include <vm/vm.h>
   68 #include <vm/pmap.h>
   69  
   70 #include <dev/buslogic/btreg.h>
   71 
   72 /* MailBox Management functions */
   73 static __inline void    btnextinbox(struct bt_softc *bt);
   74 static __inline void    btnextoutbox(struct bt_softc *bt);
   75 
   76 static __inline void
   77 btnextinbox(struct bt_softc *bt)
   78 {
   79         if (bt->cur_inbox == bt->last_inbox)
   80                 bt->cur_inbox = bt->in_boxes;
   81         else
   82                 bt->cur_inbox++;
   83 }
   84 
   85 static __inline void
   86 btnextoutbox(struct bt_softc *bt)
   87 {
   88         if (bt->cur_outbox == bt->last_outbox)
   89                 bt->cur_outbox = bt->out_boxes;
   90         else
   91                 bt->cur_outbox++;
   92 }
   93 
   94 /* CCB Mangement functions */
   95 static __inline u_int32_t               btccbvtop(struct bt_softc *bt,
   96                                                   struct bt_ccb *bccb);
   97 static __inline struct bt_ccb*          btccbptov(struct bt_softc *bt,
   98                                                   u_int32_t ccb_addr);
   99 static __inline u_int32_t               btsensepaddr(struct bt_softc *bt,
  100                                                      struct bt_ccb *bccb);
  101 static __inline struct scsi_sense_data* btsensevaddr(struct bt_softc *bt,
  102                                                      struct bt_ccb *bccb);
  103 
  104 static __inline u_int32_t
  105 btccbvtop(struct bt_softc *bt, struct bt_ccb *bccb)
  106 {
  107         return (bt->bt_ccb_physbase
  108               + (u_int32_t)((caddr_t)bccb - (caddr_t)bt->bt_ccb_array));
  109 }
  110 
  111 static __inline struct bt_ccb *
  112 btccbptov(struct bt_softc *bt, u_int32_t ccb_addr)
  113 {
  114         return (bt->bt_ccb_array +
  115                 ((struct bt_ccb*)(uintptr_t)ccb_addr - (struct bt_ccb*)(uintptr_t)bt->bt_ccb_physbase));
  116 }
  117 
  118 static __inline u_int32_t
  119 btsensepaddr(struct bt_softc *bt, struct bt_ccb *bccb)
  120 {
  121         u_int index;
  122 
  123         index = (u_int)(bccb - bt->bt_ccb_array);
  124         return (bt->sense_buffers_physbase
  125                 + (index * sizeof(struct scsi_sense_data)));
  126 }
  127 
  128 static __inline struct scsi_sense_data *
  129 btsensevaddr(struct bt_softc *bt, struct bt_ccb *bccb)
  130 {
  131         u_int index;
  132 
  133         index = (u_int)(bccb - bt->bt_ccb_array);
  134         return (bt->sense_buffers + index);
  135 }
  136 
  137 static __inline struct bt_ccb*  btgetccb(struct bt_softc *bt);
  138 static __inline void            btfreeccb(struct bt_softc *bt,
  139                                           struct bt_ccb *bccb);
  140 static void             btallocccbs(struct bt_softc *bt);
  141 static bus_dmamap_callback_t btexecuteccb;
  142 static void             btdone(struct bt_softc *bt, struct bt_ccb *bccb,
  143                                bt_mbi_comp_code_t comp_code);
  144 static void             bt_intr_locked(struct bt_softc *bt);
  145 
  146 /* Host adapter command functions */
  147 static int      btreset(struct bt_softc* bt, int hard_reset);
  148 
  149 /* Initialization functions */
  150 static int                      btinitmboxes(struct bt_softc *bt);
  151 static bus_dmamap_callback_t    btmapmboxes;
  152 static bus_dmamap_callback_t    btmapccbs;
  153 static bus_dmamap_callback_t    btmapsgs;
  154 
  155 /* Transfer Negotiation Functions */
  156 static void btfetchtransinfo(struct bt_softc *bt,
  157                              struct ccb_trans_settings *cts);
  158 
  159 /* CAM SIM entry points */
  160 #define ccb_bccb_ptr spriv_ptr0
  161 #define ccb_bt_ptr spriv_ptr1
  162 static void     btaction(struct cam_sim *sim, union ccb *ccb);
  163 static void     btpoll(struct cam_sim *sim);
  164 
  165 /* Our timeout handler */
  166 static void     bttimeout(void *arg);
  167 
  168 /*
  169  * XXX
  170  * Do our own re-probe protection until a configuration
  171  * manager can do it for us.  This ensures that we don't
  172  * reprobe a card already found by the EISA or PCI probes.
  173  */
  174 struct bt_isa_port bt_isa_ports[] =
  175 {
  176         { 0x130, 0, 4 },
  177         { 0x134, 0, 5 },
  178         { 0x230, 0, 2 },
  179         { 0x234, 0, 3 },
  180         { 0x330, 0, 0 },
  181         { 0x334, 0, 1 }
  182 };
  183 
  184 /*
  185  * I/O ports listed in the order enumerated by the
  186  * card for certain op codes.
  187  */
  188 u_int16_t bt_board_ports[] =
  189 {
  190         0x330,
  191         0x334,
  192         0x230,
  193         0x234,
  194         0x130,
  195         0x134
  196 };
  197 
  198 /* Exported functions */
  199 void
  200 bt_init_softc(device_t dev, struct resource *port,
  201               struct resource *irq, struct resource *drq)
  202 {
  203         struct bt_softc *bt = device_get_softc(dev);
  204 
  205         SLIST_INIT(&bt->free_bt_ccbs);
  206         LIST_INIT(&bt->pending_ccbs);
  207         SLIST_INIT(&bt->sg_maps);
  208         bt->dev = dev;
  209         bt->port = port;
  210         bt->irq = irq;
  211         bt->drq = drq;
  212         mtx_init(&bt->lock, "bt", NULL, MTX_DEF);
  213 }
  214 
  215 void
  216 bt_free_softc(device_t dev)
  217 {
  218         struct bt_softc *bt = device_get_softc(dev);
  219 
  220         switch (bt->init_level) {
  221         default:
  222         case 11:
  223                 bus_dmamap_unload(bt->sense_dmat, bt->sense_dmamap);
  224         case 10:
  225                 bus_dmamem_free(bt->sense_dmat, bt->sense_buffers,
  226                                 bt->sense_dmamap);
  227         case 9:
  228                 bus_dma_tag_destroy(bt->sense_dmat);
  229         case 8:
  230         {
  231                 struct sg_map_node *sg_map;
  232 
  233                 while ((sg_map = SLIST_FIRST(&bt->sg_maps))!= NULL) {
  234                         SLIST_REMOVE_HEAD(&bt->sg_maps, links);
  235                         bus_dmamap_unload(bt->sg_dmat,
  236                                           sg_map->sg_dmamap);
  237                         bus_dmamem_free(bt->sg_dmat, sg_map->sg_vaddr,
  238                                         sg_map->sg_dmamap);
  239                         free(sg_map, M_DEVBUF);
  240                 }
  241                 bus_dma_tag_destroy(bt->sg_dmat);
  242         }
  243         case 7:
  244                 bus_dmamap_unload(bt->ccb_dmat, bt->ccb_dmamap);
  245                 /* FALLTHROUGH */
  246         case 6:
  247                 bus_dmamem_free(bt->ccb_dmat, bt->bt_ccb_array,
  248                                 bt->ccb_dmamap);
  249                 /* FALLTHROUGH */
  250         case 5:
  251                 bus_dma_tag_destroy(bt->ccb_dmat);
  252                 /* FALLTHROUGH */
  253         case 4:
  254                 bus_dmamap_unload(bt->mailbox_dmat, bt->mailbox_dmamap);
  255                 /* FALLTHROUGH */
  256         case 3:
  257                 bus_dmamem_free(bt->mailbox_dmat, bt->in_boxes,
  258                                 bt->mailbox_dmamap);
  259                 /* FALLTHROUGH */
  260         case 2:
  261                 bus_dma_tag_destroy(bt->buffer_dmat);
  262                 /* FALLTHROUGH */
  263         case 1:
  264                 bus_dma_tag_destroy(bt->mailbox_dmat);
  265                 /* FALLTHROUGH */
  266         case 0:
  267                 break;
  268         }
  269         mtx_destroy(&bt->lock);
  270 }
  271 
  272 int
  273 bt_port_probe(device_t dev, struct bt_probe_info *info)
  274 {
  275         struct bt_softc *bt = device_get_softc(dev);
  276         config_data_t config_data;
  277         int error;
  278 
  279         /* See if there is really a card present */
  280         if (bt_probe(dev) || bt_fetch_adapter_info(dev))
  281                 return(1);
  282 
  283         /*
  284          * Determine our IRQ, and DMA settings and
  285          * export them to the configuration system.
  286          */
  287         mtx_lock(&bt->lock);
  288         error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
  289                        (u_int8_t*)&config_data, sizeof(config_data),
  290                        DEFAULT_CMD_TIMEOUT);
  291         mtx_unlock(&bt->lock);
  292         if (error != 0) {
  293                 printf("bt_port_probe: Could not determine IRQ or DMA "
  294                        "settings for adapter.\n");
  295                 return (1);
  296         }
  297 
  298         if (bt->model[0] == '5') {
  299                 /* DMA settings only make sense for ISA cards */
  300                 switch (config_data.dma_chan) {
  301                 case DMA_CHAN_5:
  302                         info->drq = 5;
  303                         break;
  304                 case DMA_CHAN_6:
  305                         info->drq = 6;
  306                         break;
  307                 case DMA_CHAN_7:
  308                         info->drq = 7;
  309                         break;
  310                 default:
  311                         printf("bt_port_probe: Invalid DMA setting "
  312                                "detected for adapter.\n");
  313                         return (1);
  314                 }
  315         } else {
  316                 /* VL/EISA/PCI DMA */
  317                 info->drq = -1;
  318         }
  319         switch (config_data.irq) {
  320         case IRQ_9:
  321         case IRQ_10:
  322         case IRQ_11:
  323         case IRQ_12:
  324         case IRQ_14:
  325         case IRQ_15:
  326                 info->irq = ffs(config_data.irq) + 8;
  327                 break;
  328         default:
  329                 printf("bt_port_probe: Invalid IRQ setting %x"
  330                        "detected for adapter.\n", config_data.irq);
  331                 return (1);
  332         }
  333         return (0);
  334 }
  335 
  336 /*
  337  * Probe the adapter and verify that the card is a BusLogic.
  338  */
  339 int
  340 bt_probe(device_t dev)
  341 {
  342         struct bt_softc *bt = device_get_softc(dev);
  343         esetup_info_data_t esetup_info;
  344         u_int    status;
  345         u_int    intstat;
  346         u_int    geometry;
  347         int      error;
  348         u_int8_t param;
  349 
  350         /*
  351          * See if the three I/O ports look reasonable.
  352          * Touch the minimal number of registers in the
  353          * failure case.
  354          */
  355         status = bt_inb(bt, STATUS_REG);
  356         if ((status == 0)
  357          || (status & (DIAG_ACTIVE|CMD_REG_BUSY|
  358                        STATUS_REG_RSVD|CMD_INVALID)) != 0) {
  359                 if (bootverbose)
  360                         device_printf(dev, "Failed Status Reg Test - %x\n",
  361                                status);
  362                 return (ENXIO);
  363         }
  364 
  365         intstat = bt_inb(bt, INTSTAT_REG);
  366         if ((intstat & INTSTAT_REG_RSVD) != 0) {
  367                 device_printf(dev, "Failed Intstat Reg Test\n");
  368                 return (ENXIO);
  369         }
  370 
  371         geometry = bt_inb(bt, GEOMETRY_REG);
  372         if (geometry == 0xFF) {
  373                 if (bootverbose)
  374                         device_printf(dev, "Failed Geometry Reg Test\n");
  375                 return (ENXIO);
  376         }
  377 
  378         /*
  379          * Looking good so far.  Final test is to reset the
  380          * adapter and attempt to fetch the extended setup
  381          * information.  This should filter out all 1542 cards.
  382          */
  383         mtx_lock(&bt->lock);
  384         if ((error = btreset(bt, /*hard_reset*/TRUE)) != 0) {
  385                 mtx_unlock(&bt->lock);
  386                 if (bootverbose)
  387                         device_printf(dev, "Failed Reset\n");
  388                 return (ENXIO);
  389         }
  390         
  391         param = sizeof(esetup_info);
  392         error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &param, /*parmlen*/1,
  393                        (u_int8_t*)&esetup_info, sizeof(esetup_info),
  394                        DEFAULT_CMD_TIMEOUT);
  395         mtx_unlock(&bt->lock);
  396         if (error != 0) {
  397                 return (ENXIO);
  398         }
  399 
  400         return (0);
  401 }
  402 
  403 /*
  404  * Pull the boards setup information and record it in our softc.
  405  */
  406 int
  407 bt_fetch_adapter_info(device_t dev)
  408 {
  409         struct bt_softc *bt = device_get_softc(dev);
  410         board_id_data_t board_id;
  411         esetup_info_data_t esetup_info;
  412         config_data_t config_data;
  413         int      error;
  414         u_int8_t length_param;
  415 
  416         /* First record the firmware version */
  417         mtx_lock(&bt->lock);
  418         error = bt_cmd(bt, BOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0,
  419                        (u_int8_t*)&board_id, sizeof(board_id),
  420                        DEFAULT_CMD_TIMEOUT);
  421         if (error != 0) {
  422                 mtx_unlock(&bt->lock);
  423                 device_printf(dev, "bt_fetch_adapter_info - Failed Get Board Info\n");
  424                 return (error);
  425         }
  426         bt->firmware_ver[0] = board_id.firmware_rev_major;
  427         bt->firmware_ver[1] = '.';
  428         bt->firmware_ver[2] = board_id.firmware_rev_minor;
  429         bt->firmware_ver[3] = '\0';
  430                 
  431         /*
  432          * Depending on the firmware major and minor version,
  433          * we may be able to fetch additional minor version info.
  434          */
  435         if (bt->firmware_ver[0] > '') {
  436                 
  437                 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_3DIG, NULL, /*parmlen*/0,
  438                                (u_int8_t*)&bt->firmware_ver[3], 1,
  439                                DEFAULT_CMD_TIMEOUT);
  440                 if (error != 0) {
  441                         mtx_unlock(&bt->lock);
  442                         device_printf(dev,
  443                                       "bt_fetch_adapter_info - Failed Get "
  444                                       "Firmware 3rd Digit\n");
  445                         return (error);
  446                 }
  447                 if (bt->firmware_ver[3] == ' ')
  448                         bt->firmware_ver[3] = '\0';
  449                 bt->firmware_ver[4] = '\0';
  450         }
  451 
  452         if (strcmp(bt->firmware_ver, "3.3") >= 0) {
  453 
  454                 error = bt_cmd(bt, BOP_INQUIRE_FW_VER_4DIG, NULL, /*parmlen*/0,
  455                                (u_int8_t*)&bt->firmware_ver[4], 1,
  456                                DEFAULT_CMD_TIMEOUT);
  457                 if (error != 0) {
  458                         mtx_unlock(&bt->lock);
  459                         device_printf(dev,
  460                                       "bt_fetch_adapter_info - Failed Get "
  461                                       "Firmware 4th Digit\n");
  462                         return (error);
  463                 }
  464                 if (bt->firmware_ver[4] == ' ')
  465                         bt->firmware_ver[4] = '\0';
  466                 bt->firmware_ver[5] = '\0';
  467         }
  468 
  469         /*
  470          * Some boards do not handle the "recently documented"
  471          * Inquire Board Model Number command correctly or do not give
  472          * exact information.  Use the Firmware and Extended Setup
  473          * information in these cases to come up with the right answer.
  474          * The major firmware revision number indicates:
  475          *
  476          *      5.xx    BusLogic "W" Series Host Adapters:
  477          *              BT-948/958/958D
  478          *      4.xx    BusLogic "C" Series Host Adapters:
  479          *              BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
  480          *      3.xx    BusLogic "S" Series Host Adapters:
  481          *              BT-747S/747D/757S/757D/445S/545S/542D
  482          *              BT-542B/742A (revision H)
  483          *      2.xx    BusLogic "A" Series Host Adapters:
  484          *              BT-542B/742A (revision G and below)
  485          *      0.xx    AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
  486          */
  487         length_param = sizeof(esetup_info);
  488         error = bt_cmd(bt, BOP_INQUIRE_ESETUP_INFO, &length_param, /*parmlen*/1,
  489                        (u_int8_t*)&esetup_info, sizeof(esetup_info),
  490                        DEFAULT_CMD_TIMEOUT);
  491         if (error != 0) {
  492                 mtx_unlock(&bt->lock);
  493                 return (error);
  494         }
  495         
  496         bt->bios_addr = esetup_info.bios_addr << 12;
  497 
  498         bt->mailbox_addrlimit = BUS_SPACE_MAXADDR;
  499         if (esetup_info.bus_type == 'A'
  500          && bt->firmware_ver[0] == '2') {
  501                 snprintf(bt->model, sizeof(bt->model), "542B");
  502         } else if (esetup_info.bus_type == 'E'
  503                 && bt->firmware_ver[0] == '2') {
  504 
  505                 /*
  506                  * The 742A seems to object if its mailboxes are
  507                  * allocated above the 16MB mark.
  508                  */
  509                 bt->mailbox_addrlimit = BUS_SPACE_MAXADDR_24BIT;
  510                 snprintf(bt->model, sizeof(bt->model), "742A");
  511         } else if (esetup_info.bus_type == 'E'
  512                 && bt->firmware_ver[0] == '') {
  513                 /* AMI FastDisk EISA Series 441 0.x */
  514                 snprintf(bt->model, sizeof(bt->model), "747A");
  515         } else {
  516                 ha_model_data_t model_data;
  517                 int i;
  518 
  519                 length_param = sizeof(model_data);
  520                 error = bt_cmd(bt, BOP_INQUIRE_MODEL, &length_param, 1,
  521                                (u_int8_t*)&model_data, sizeof(model_data),
  522                                DEFAULT_CMD_TIMEOUT);
  523                 if (error != 0) {
  524                         mtx_unlock(&bt->lock);
  525                         device_printf(dev,
  526                                       "bt_fetch_adapter_info - Failed Inquire "
  527                                       "Model Number\n");
  528                         return (error);
  529                 }
  530                 for (i = 0; i < sizeof(model_data.ascii_model); i++) {
  531                         bt->model[i] = model_data.ascii_model[i];
  532                         if (bt->model[i] == ' ')
  533                                 break;
  534                 }
  535                 bt->model[i] = '\0';
  536         }
  537 
  538         bt->level_trigger_ints = esetup_info.level_trigger_ints ? 1 : 0;
  539 
  540         /* SG element limits */
  541         bt->max_sg = esetup_info.max_sg;
  542 
  543         /* Set feature flags */
  544         bt->wide_bus = esetup_info.wide_bus;
  545         bt->diff_bus = esetup_info.diff_bus;
  546         bt->ultra_scsi = esetup_info.ultra_scsi;
  547 
  548         if ((bt->firmware_ver[0] == '5')
  549          || (bt->firmware_ver[0] == '4' && bt->wide_bus))
  550                 bt->extended_lun = TRUE;
  551 
  552         bt->strict_rr = (strcmp(bt->firmware_ver, "3.31") >= 0);
  553 
  554         bt->extended_trans =
  555             ((bt_inb(bt, GEOMETRY_REG) & EXTENDED_TRANSLATION) != 0);
  556 
  557         /*
  558          * Determine max CCB count and whether tagged queuing is
  559          * available based on controller type. Tagged queuing
  560          * only works on 'W' series adapters, 'C' series adapters
  561          * with firmware of rev 4.42 and higher, and 'S' series
  562          * adapters with firmware of rev 3.35 and higher.  The
  563          * maximum CCB counts are as follows:
  564          *
  565          *      192     BT-948/958/958D
  566          *      100     BT-946C/956C/956CD/747C/757C/757CD/445C
  567          *      50      BT-545C/540CF
  568          *      30      BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
  569          */
  570         if (bt->firmware_ver[0] == '5') {
  571                 bt->max_ccbs = 192;
  572                 bt->tag_capable = TRUE;
  573         } else if (bt->firmware_ver[0] == '4') {
  574                 if (bt->model[0] == '5')
  575                         bt->max_ccbs = 50;
  576                 else
  577                         bt->max_ccbs = 100;
  578                 bt->tag_capable = (strcmp(bt->firmware_ver, "4.22") >= 0);
  579         } else {
  580                 bt->max_ccbs = 30;
  581                 if (bt->firmware_ver[0] == '3'
  582                  && (strcmp(bt->firmware_ver, "3.35") >= 0))
  583                         bt->tag_capable = TRUE;
  584                 else
  585                         bt->tag_capable = FALSE;
  586         }
  587 
  588         if (bt->tag_capable != FALSE)
  589                 bt->tags_permitted = ALL_TARGETS;
  590 
  591         /* Determine Sync/Wide/Disc settings */
  592         if (bt->firmware_ver[0] >= '4') {
  593                 auto_scsi_data_t auto_scsi_data;
  594                 fetch_lram_params_t fetch_lram_params;
  595                 int error;
  596                 
  597                 /*
  598                  * These settings are stored in the
  599                  * AutoSCSI data in LRAM of 'W' and 'C'
  600                  * adapters.
  601                  */
  602                 fetch_lram_params.offset = AUTO_SCSI_BYTE_OFFSET;
  603                 fetch_lram_params.response_len = sizeof(auto_scsi_data);
  604                 error = bt_cmd(bt, BOP_FETCH_LRAM,
  605                                (u_int8_t*)&fetch_lram_params,
  606                                sizeof(fetch_lram_params),
  607                                (u_int8_t*)&auto_scsi_data,
  608                                sizeof(auto_scsi_data), DEFAULT_CMD_TIMEOUT);
  609 
  610                 if (error != 0) {
  611                         mtx_unlock(&bt->lock);
  612                         device_printf(dev,
  613                                       "bt_fetch_adapter_info - Failed "
  614                                       "Get Auto SCSI Info\n");
  615                         return (error);
  616                 }
  617 
  618                 bt->disc_permitted = auto_scsi_data.low_disc_permitted
  619                                    | (auto_scsi_data.high_disc_permitted << 8);
  620                 bt->sync_permitted = auto_scsi_data.low_sync_permitted
  621                                    | (auto_scsi_data.high_sync_permitted << 8);
  622                 bt->fast_permitted = auto_scsi_data.low_fast_permitted
  623                                    | (auto_scsi_data.high_fast_permitted << 8);
  624                 bt->ultra_permitted = auto_scsi_data.low_ultra_permitted
  625                                    | (auto_scsi_data.high_ultra_permitted << 8);
  626                 bt->wide_permitted = auto_scsi_data.low_wide_permitted
  627                                    | (auto_scsi_data.high_wide_permitted << 8);
  628 
  629                 if (bt->ultra_scsi == FALSE)
  630                         bt->ultra_permitted = 0;
  631 
  632                 if (bt->wide_bus == FALSE)
  633                         bt->wide_permitted = 0;
  634         } else {
  635                 /*
  636                  * 'S' and 'A' series have this information in the setup
  637                  * information structure.
  638                  */
  639                 setup_data_t    setup_info;
  640 
  641                 length_param = sizeof(setup_info);
  642                 error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, &length_param,
  643                                /*paramlen*/1, (u_int8_t*)&setup_info,
  644                                sizeof(setup_info), DEFAULT_CMD_TIMEOUT);
  645 
  646                 if (error != 0) {
  647                         mtx_unlock(&bt->lock);
  648                         device_printf(dev,
  649                                       "bt_fetch_adapter_info - Failed "
  650                                       "Get Setup Info\n");
  651                         return (error);
  652                 }
  653 
  654                 if (setup_info.initiate_sync != 0) {
  655                         bt->sync_permitted = ALL_TARGETS;
  656 
  657                         if (bt->model[0] == '7') {
  658                                 if (esetup_info.sync_neg10MB != 0)
  659                                         bt->fast_permitted = ALL_TARGETS;
  660                                 if (strcmp(bt->model, "757") == 0)
  661                                         bt->wide_permitted = ALL_TARGETS;
  662                         }
  663                 }
  664                 bt->disc_permitted = ALL_TARGETS;
  665         }
  666 
  667         /* We need as many mailboxes as we can have ccbs */
  668         bt->num_boxes = bt->max_ccbs;
  669 
  670         /* Determine our SCSI ID */
  671         
  672         error = bt_cmd(bt, BOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
  673                        (u_int8_t*)&config_data, sizeof(config_data),
  674                        DEFAULT_CMD_TIMEOUT);
  675         mtx_unlock(&bt->lock);
  676         if (error != 0) {
  677                 device_printf(dev,
  678                               "bt_fetch_adapter_info - Failed Get Config\n");
  679                 return (error);
  680         }
  681         bt->scsi_id = config_data.scsi_id;
  682 
  683         return (0);
  684 }
  685 
  686 /*
  687  * Start the board, ready for normal operation
  688  */
  689 int
  690 bt_init(device_t dev)
  691 {
  692         struct bt_softc *bt = device_get_softc(dev);
  693 
  694         /* Announce the Adapter */
  695         device_printf(dev, "BT-%s FW Rev. %s ", bt->model, bt->firmware_ver);
  696 
  697         if (bt->ultra_scsi != 0)
  698                 printf("Ultra ");
  699 
  700         if (bt->wide_bus != 0)
  701                 printf("Wide ");
  702         else
  703                 printf("Narrow ");
  704 
  705         if (bt->diff_bus != 0)
  706                 printf("Diff ");
  707 
  708         printf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", bt->scsi_id,
  709                bt->max_ccbs);
  710 
  711         /*
  712          * Create our DMA tags.  These tags define the kinds of device
  713          * accessible memory allocations and memory mappings we will 
  714          * need to perform during normal operation.
  715          *
  716          * Unless we need to further restrict the allocation, we rely
  717          * on the restrictions of the parent dmat, hence the common
  718          * use of MAXADDR and MAXSIZE.
  719          */
  720 
  721         /* DMA tag for mapping buffers into device visible space. */
  722         if (bus_dma_tag_create( /* parent       */ bt->parent_dmat,
  723                                 /* alignment    */ 1,
  724                                 /* boundary     */ 0,
  725                                 /* lowaddr      */ BUS_SPACE_MAXADDR,
  726                                 /* highaddr     */ BUS_SPACE_MAXADDR,
  727                                 /* filter       */ NULL,
  728                                 /* filterarg    */ NULL,
  729                                 /* maxsize      */ DFLTPHYS,
  730                                 /* nsegments    */ BT_NSEG,
  731                                 /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
  732                                 /* flags        */ BUS_DMA_ALLOCNOW,
  733                                 /* lockfunc     */ busdma_lock_mutex,
  734                                 /* lockarg      */ &bt->lock,
  735                                 &bt->buffer_dmat) != 0) {
  736                 goto error_exit;
  737         }
  738 
  739         bt->init_level++;
  740         /* DMA tag for our mailboxes */
  741         if (bus_dma_tag_create( /* parent       */ bt->parent_dmat,
  742                                 /* alignment    */ 1,
  743                                 /* boundary     */ 0,
  744                                 /* lowaddr      */ bt->mailbox_addrlimit,
  745                                 /* highaddr     */ BUS_SPACE_MAXADDR,
  746                                 /* filter       */ NULL,
  747                                 /* filterarg    */ NULL,
  748                                 /* maxsize      */ bt->num_boxes *
  749                                                    (sizeof(bt_mbox_in_t) +
  750                                                     sizeof(bt_mbox_out_t)),
  751                                 /* nsegments    */ 1,
  752                                 /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
  753                                 /* flags        */ 0,
  754                                 /* lockfunc     */ NULL,
  755                                 /* lockarg      */ NULL,
  756                                 &bt->mailbox_dmat) != 0) {
  757                 goto error_exit;
  758         }
  759 
  760         bt->init_level++;
  761 
  762         /* Allocation for our mailboxes */
  763         if (bus_dmamem_alloc(bt->mailbox_dmat, (void **)&bt->out_boxes,
  764                              BUS_DMA_NOWAIT, &bt->mailbox_dmamap) != 0) {
  765                 goto error_exit;
  766         }
  767 
  768         bt->init_level++;
  769 
  770         /* And permanently map them */
  771         bus_dmamap_load(bt->mailbox_dmat, bt->mailbox_dmamap,
  772                         bt->out_boxes,
  773                         bt->num_boxes * (sizeof(bt_mbox_in_t)
  774                                        + sizeof(bt_mbox_out_t)),
  775                         btmapmboxes, bt, /*flags*/0);
  776 
  777         bt->init_level++;
  778 
  779         bt->in_boxes = (bt_mbox_in_t *)&bt->out_boxes[bt->num_boxes];
  780 
  781         mtx_lock(&bt->lock);
  782         btinitmboxes(bt);
  783         mtx_unlock(&bt->lock);
  784 
  785         /* DMA tag for our ccb structures */
  786         if (bus_dma_tag_create( /* parent       */ bt->parent_dmat,
  787                                 /* alignment    */ 1,
  788                                 /* boundary     */ 0,
  789                                 /* lowaddr      */ BUS_SPACE_MAXADDR,
  790                                 /* highaddr     */ BUS_SPACE_MAXADDR,
  791                                 /* filter       */ NULL,
  792                                 /* filterarg    */ NULL,
  793                                 /* maxsize      */ bt->max_ccbs *
  794                                                    sizeof(struct bt_ccb),
  795                                 /* nsegments    */ 1,
  796                                 /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
  797                                 /* flags        */ 0,
  798                                 /* lockfunc     */ NULL,
  799                                 /* lockarg      */ NULL,
  800                                 &bt->ccb_dmat) != 0) {
  801                 goto error_exit;
  802         }
  803 
  804         bt->init_level++;
  805 
  806         /* Allocation for our ccbs */
  807         if (bus_dmamem_alloc(bt->ccb_dmat, (void **)&bt->bt_ccb_array,
  808                              BUS_DMA_NOWAIT, &bt->ccb_dmamap) != 0) {
  809                 goto error_exit;
  810         }
  811 
  812         bt->init_level++;
  813 
  814         /* And permanently map them */
  815         bus_dmamap_load(bt->ccb_dmat, bt->ccb_dmamap,
  816                         bt->bt_ccb_array,
  817                         bt->max_ccbs * sizeof(struct bt_ccb),
  818                         btmapccbs, bt, /*flags*/0);
  819 
  820         bt->init_level++;
  821 
  822         /* DMA tag for our S/G structures.  We allocate in page sized chunks */
  823         if (bus_dma_tag_create( /* parent       */ bt->parent_dmat,
  824                                 /* alignment    */ 1,
  825                                 /* boundary     */ 0,
  826                                 /* lowaddr      */ BUS_SPACE_MAXADDR,
  827                                 /* highaddr     */ BUS_SPACE_MAXADDR,
  828                                 /* filter       */ NULL,
  829                                 /* filterarg    */ NULL,
  830                                 /* maxsize      */ PAGE_SIZE,
  831                                 /* nsegments    */ 1,
  832                                 /* maxsegsz     */ BUS_SPACE_MAXSIZE_32BIT,
  833                                 /* flags        */ 0,
  834                                 /* lockfunc     */ NULL,
  835                                 /* lockarg      */ NULL,
  836                                 &bt->sg_dmat) != 0) {
  837                 goto error_exit;
  838         }
  839 
  840         bt->init_level++;
  841 
  842         /* Perform initial CCB allocation */
  843         bzero(bt->bt_ccb_array, bt->max_ccbs * sizeof(struct bt_ccb));
  844         btallocccbs(bt);
  845 
  846         if (bt->num_ccbs == 0) {
  847                 device_printf(dev,
  848                               "bt_init - Unable to allocate initial ccbs\n");
  849                 goto error_exit;
  850         }
  851 
  852         /*
  853          * Note that we are going and return (to attach)
  854          */
  855         return 0;
  856 
  857 error_exit:
  858 
  859         return (ENXIO);
  860 }
  861 
  862 int
  863 bt_attach(device_t dev)
  864 {
  865         struct bt_softc *bt = device_get_softc(dev);
  866         int tagged_dev_openings;
  867         struct cam_devq *devq;
  868         int error;
  869 
  870         /*
  871          * We reserve 1 ccb for error recovery, so don't
  872          * tell the XPT about it.
  873          */
  874         if (bt->tag_capable != 0)
  875                 tagged_dev_openings = bt->max_ccbs - 1;
  876         else
  877                 tagged_dev_openings = 0;
  878 
  879         /*
  880          * Create the device queue for our SIM.
  881          */
  882         devq = cam_simq_alloc(bt->max_ccbs - 1);
  883         if (devq == NULL)
  884                 return (ENOMEM);
  885 
  886         /*
  887          * Construct our SIM entry
  888          */
  889         bt->sim = cam_sim_alloc(btaction, btpoll, "bt", bt,
  890             device_get_unit(bt->dev), &bt->lock, 2, tagged_dev_openings, devq);
  891         if (bt->sim == NULL) {
  892                 cam_simq_free(devq);
  893                 return (ENOMEM);
  894         }
  895 
  896         mtx_lock(&bt->lock);
  897         if (xpt_bus_register(bt->sim, dev, 0) != CAM_SUCCESS) {
  898                 cam_sim_free(bt->sim, /*free_devq*/TRUE);
  899                 mtx_unlock(&bt->lock);
  900                 return (ENXIO);
  901         }
  902         
  903         if (xpt_create_path(&bt->path, /*periph*/NULL,
  904                             cam_sim_path(bt->sim), CAM_TARGET_WILDCARD,
  905                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
  906                 xpt_bus_deregister(cam_sim_path(bt->sim));
  907                 cam_sim_free(bt->sim, /*free_devq*/TRUE);
  908                 mtx_unlock(&bt->lock);
  909                 return (ENXIO);
  910         }
  911         mtx_unlock(&bt->lock);
  912                 
  913         /*
  914          * Setup interrupt.
  915          */
  916         error = bus_setup_intr(dev, bt->irq, INTR_TYPE_CAM | INTR_ENTROPY |
  917             INTR_MPSAFE, NULL, bt_intr, bt, &bt->ih);
  918         if (error) {
  919                 device_printf(dev, "bus_setup_intr() failed: %d\n", error);
  920                 return (error);
  921         }
  922 
  923         return (0);
  924 }
  925 
  926 int
  927 bt_check_probed_iop(u_int ioport)
  928 {
  929         u_int i;
  930 
  931         for (i = 0; i < BT_NUM_ISAPORTS; i++) {
  932                 if (bt_isa_ports[i].addr == ioport) {
  933                         if (bt_isa_ports[i].probed != 0)
  934                                 return (1);
  935                         else {
  936                                 return (0);
  937                         }
  938                 }
  939         }
  940         return (1);
  941 }
  942 
  943 void
  944 bt_mark_probed_bio(isa_compat_io_t port)
  945 {
  946         if (port < BIO_DISABLED)
  947                 bt_mark_probed_iop(bt_board_ports[port]);
  948 }
  949 
  950 void
  951 bt_mark_probed_iop(u_int ioport)
  952 {
  953         u_int i;
  954 
  955         for (i = 0; i < BT_NUM_ISAPORTS; i++) {
  956                 if (ioport == bt_isa_ports[i].addr) {
  957                         bt_isa_ports[i].probed = 1;
  958                         break;
  959                 }
  960         }
  961 }
  962 
  963 void
  964 bt_find_probe_range(int ioport, int *port_index, int *max_port_index)
  965 {
  966         if (ioport > 0) {
  967                 int i;
  968 
  969                 for (i = 0;i < BT_NUM_ISAPORTS; i++)
  970                         if (ioport <= bt_isa_ports[i].addr)
  971                                 break;
  972                 if ((i >= BT_NUM_ISAPORTS)
  973                  || (ioport != bt_isa_ports[i].addr)) {
  974                         printf(
  975 "bt_find_probe_range: Invalid baseport of 0x%x specified.\n"
  976 "bt_find_probe_range: Nearest valid baseport is 0x%x.\n"
  977 "bt_find_probe_range: Failing probe.\n",
  978                                ioport,
  979                                (i < BT_NUM_ISAPORTS)
  980                                     ? bt_isa_ports[i].addr
  981                                     : bt_isa_ports[BT_NUM_ISAPORTS - 1].addr);
  982                         *port_index = *max_port_index = -1;
  983                         return;
  984                 }
  985                 *port_index = *max_port_index = bt_isa_ports[i].bio;
  986         } else {
  987                 *port_index = 0;
  988                 *max_port_index = BT_NUM_ISAPORTS - 1;
  989         }
  990 }
  991 
  992 int
  993 bt_iop_from_bio(isa_compat_io_t bio_index)
  994 {
  995         if (bio_index < BT_NUM_ISAPORTS)
  996                 return (bt_board_ports[bio_index]);
  997         return (-1);
  998 }
  999 
 1000 
 1001 static void
 1002 btallocccbs(struct bt_softc *bt)
 1003 {
 1004         struct bt_ccb *next_ccb;
 1005         struct sg_map_node *sg_map;
 1006         bus_addr_t physaddr;
 1007         bt_sg_t *segs;
 1008         int newcount;
 1009         int i;
 1010 
 1011         if (bt->num_ccbs >= bt->max_ccbs)
 1012                 /* Can't allocate any more */
 1013                 return;
 1014 
 1015         next_ccb = &bt->bt_ccb_array[bt->num_ccbs];
 1016 
 1017         sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_NOWAIT);
 1018 
 1019         if (sg_map == NULL)
 1020                 goto error_exit;
 1021 
 1022         /* Allocate S/G space for the next batch of CCBS */
 1023         if (bus_dmamem_alloc(bt->sg_dmat, (void **)&sg_map->sg_vaddr,
 1024                              BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
 1025                 free(sg_map, M_DEVBUF);
 1026                 goto error_exit;
 1027         }
 1028 
 1029         SLIST_INSERT_HEAD(&bt->sg_maps, sg_map, links);
 1030 
 1031         bus_dmamap_load(bt->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr,
 1032                         PAGE_SIZE, btmapsgs, bt, /*flags*/0);
 1033         
 1034         segs = sg_map->sg_vaddr;
 1035         physaddr = sg_map->sg_physaddr;
 1036 
 1037         newcount = (PAGE_SIZE / (BT_NSEG * sizeof(bt_sg_t)));
 1038         for (i = 0; bt->num_ccbs < bt->max_ccbs && i < newcount; i++) {
 1039                 int error;
 1040 
 1041                 next_ccb->sg_list = segs;
 1042                 next_ccb->sg_list_phys = physaddr;
 1043                 next_ccb->flags = BCCB_FREE;
 1044                 callout_init_mtx(&next_ccb->timer, &bt->lock, 0);
 1045                 error = bus_dmamap_create(bt->buffer_dmat, /*flags*/0,
 1046                                           &next_ccb->dmamap);
 1047                 if (error != 0)
 1048                         break;
 1049                 SLIST_INSERT_HEAD(&bt->free_bt_ccbs, next_ccb, links);
 1050                 segs += BT_NSEG;
 1051                 physaddr += (BT_NSEG * sizeof(bt_sg_t));
 1052                 next_ccb++;
 1053                 bt->num_ccbs++;
 1054         }
 1055 
 1056         /* Reserve a CCB for error recovery */
 1057         if (bt->recovery_bccb == NULL) {
 1058                 bt->recovery_bccb = SLIST_FIRST(&bt->free_bt_ccbs);
 1059                 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
 1060         }
 1061 
 1062         if (SLIST_FIRST(&bt->free_bt_ccbs) != NULL)
 1063                 return;
 1064 
 1065 error_exit:
 1066         device_printf(bt->dev, "Can't malloc BCCBs\n");
 1067 }
 1068 
 1069 static __inline void
 1070 btfreeccb(struct bt_softc *bt, struct bt_ccb *bccb)
 1071 {
 1072 
 1073         if (!dumping)
 1074                 mtx_assert(&bt->lock, MA_OWNED);
 1075         if ((bccb->flags & BCCB_ACTIVE) != 0)
 1076                 LIST_REMOVE(&bccb->ccb->ccb_h, sim_links.le);
 1077         if (bt->resource_shortage != 0
 1078          && (bccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
 1079                 bccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 1080                 bt->resource_shortage = FALSE;
 1081         }
 1082         bccb->flags = BCCB_FREE;
 1083         SLIST_INSERT_HEAD(&bt->free_bt_ccbs, bccb, links);
 1084         bt->active_ccbs--;
 1085 }
 1086 
 1087 static __inline struct bt_ccb*
 1088 btgetccb(struct bt_softc *bt)
 1089 {
 1090         struct  bt_ccb* bccb;
 1091 
 1092         if (!dumping)
 1093                 mtx_assert(&bt->lock, MA_OWNED);
 1094         if ((bccb = SLIST_FIRST(&bt->free_bt_ccbs)) != NULL) {
 1095                 SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
 1096                 bt->active_ccbs++;
 1097         } else {
 1098                 btallocccbs(bt);
 1099                 bccb = SLIST_FIRST(&bt->free_bt_ccbs);
 1100                 if (bccb != NULL) {
 1101                         SLIST_REMOVE_HEAD(&bt->free_bt_ccbs, links);
 1102                         bt->active_ccbs++;
 1103                 }
 1104         }
 1105 
 1106         return (bccb);
 1107 }
 1108 
 1109 static void
 1110 btaction(struct cam_sim *sim, union ccb *ccb)
 1111 {
 1112         struct  bt_softc *bt;
 1113 
 1114         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("btaction\n"));
 1115         
 1116         bt = (struct bt_softc *)cam_sim_softc(sim);
 1117         mtx_assert(&bt->lock, MA_OWNED);
 1118         
 1119         switch (ccb->ccb_h.func_code) {
 1120         /* Common cases first */
 1121         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
 1122         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
 1123         {
 1124                 struct  bt_ccb  *bccb;
 1125                 struct  bt_hccb *hccb;
 1126 
 1127                 /*
 1128                  * get a bccb to use.
 1129                  */
 1130                 if ((bccb = btgetccb(bt)) == NULL) {
 1131 
 1132                         bt->resource_shortage = TRUE;
 1133                         xpt_freeze_simq(bt->sim, /*count*/1);
 1134                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
 1135                         xpt_done(ccb);
 1136                         return;
 1137                 }
 1138                 
 1139                 hccb = &bccb->hccb;
 1140 
 1141                 /*
 1142                  * So we can find the BCCB when an abort is requested
 1143                  */
 1144                 bccb->ccb = ccb;
 1145                 ccb->ccb_h.ccb_bccb_ptr = bccb;
 1146                 ccb->ccb_h.ccb_bt_ptr = bt;
 1147 
 1148                 /*
 1149                  * Put all the arguments for the xfer in the bccb
 1150                  */
 1151                 hccb->target_id = ccb->ccb_h.target_id;
 1152                 hccb->target_lun = ccb->ccb_h.target_lun;
 1153                 hccb->btstat = 0;
 1154                 hccb->sdstat = 0;
 1155 
 1156                 if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
 1157                         struct ccb_scsiio *csio;
 1158                         struct ccb_hdr *ccbh;
 1159                         int error;
 1160 
 1161                         csio = &ccb->csio;
 1162                         ccbh = &csio->ccb_h;
 1163                         hccb->opcode = INITIATOR_CCB_WRESID;
 1164                         hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) ? 1 : 0;
 1165                         hccb->dataout =(ccb->ccb_h.flags & CAM_DIR_OUT) ? 1 : 0;
 1166                         hccb->cmd_len = csio->cdb_len;
 1167                         if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) {
 1168                                 ccb->ccb_h.status = CAM_REQ_INVALID;
 1169                                 btfreeccb(bt, bccb);
 1170                                 xpt_done(ccb);
 1171                                 return;
 1172                         }
 1173                         hccb->sense_len = csio->sense_len;
 1174                         if ((ccbh->flags & CAM_TAG_ACTION_VALID) != 0
 1175                          && ccb->csio.tag_action != CAM_TAG_ACTION_NONE) {
 1176                                 hccb->tag_enable = TRUE;
 1177                                 hccb->tag_type = (ccb->csio.tag_action & 0x3);
 1178                         } else {
 1179                                 hccb->tag_enable = FALSE;
 1180                                 hccb->tag_type = 0;
 1181                         }
 1182                         if ((ccbh->flags & CAM_CDB_POINTER) != 0) {
 1183                                 if ((ccbh->flags & CAM_CDB_PHYS) == 0) {
 1184                                         bcopy(csio->cdb_io.cdb_ptr,
 1185                                               hccb->scsi_cdb, hccb->cmd_len);
 1186                                 } else {
 1187                                         /* I guess I could map it in... */
 1188                                         ccbh->status = CAM_REQ_INVALID;
 1189                                         btfreeccb(bt, bccb);
 1190                                         xpt_done(ccb);
 1191                                         return;
 1192                                 }
 1193                         } else {
 1194                                 bcopy(csio->cdb_io.cdb_bytes,
 1195                                       hccb->scsi_cdb, hccb->cmd_len);
 1196                         }
 1197                         /* If need be, bounce our sense buffer */
 1198                         if (bt->sense_buffers != NULL) {
 1199                                 hccb->sense_addr = btsensepaddr(bt, bccb);
 1200                         } else {
 1201                                 hccb->sense_addr = vtophys(&csio->sense_data);
 1202                         }
 1203                         /*
 1204                          * If we have any data to send with this command,
 1205                          * map it into bus space.
 1206                          */
 1207                         error = bus_dmamap_load_ccb(
 1208                             bt->buffer_dmat,
 1209                             bccb->dmamap,
 1210                             ccb,
 1211                             btexecuteccb,
 1212                             bccb,
 1213                             /*flags*/0);
 1214                         if (error == EINPROGRESS) {
 1215                                 /*
 1216                                  * So as to maintain ordering, freeze the
 1217                                  * controller queue until our mapping is
 1218                                  * returned.
 1219                                  */
 1220                                 xpt_freeze_simq(bt->sim, 1);
 1221                                 csio->ccb_h.status |= CAM_RELEASE_SIMQ;
 1222                         }
 1223                 } else {
 1224                         hccb->opcode = INITIATOR_BUS_DEV_RESET;
 1225                         /* No data transfer */
 1226                         hccb->datain = TRUE;
 1227                         hccb->dataout = TRUE;
 1228                         hccb->cmd_len = 0;
 1229                         hccb->sense_len = 0;
 1230                         hccb->tag_enable = FALSE;
 1231                         hccb->tag_type = 0;
 1232                         btexecuteccb(bccb, NULL, 0, 0);
 1233                 }
 1234                 break;
 1235         }
 1236         case XPT_ABORT:                 /* Abort the specified CCB */
 1237                 /* XXX Implement */
 1238                 ccb->ccb_h.status = CAM_REQ_INVALID;
 1239                 xpt_done(ccb);
 1240                 break;
 1241         case XPT_SET_TRAN_SETTINGS:
 1242         {
 1243                 /* XXX Implement */
 1244                 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
 1245                 xpt_done(ccb);
 1246                 break;
 1247         }
 1248         case XPT_GET_TRAN_SETTINGS:
 1249         /* Get default/user set transfer settings for the target */
 1250         {
 1251                 struct  ccb_trans_settings *cts;
 1252                 u_int   target_mask;
 1253 
 1254                 cts = &ccb->cts;
 1255                 target_mask = 0x01 << ccb->ccb_h.target_id;
 1256                 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
 1257                         struct ccb_trans_settings_scsi *scsi =
 1258                             &cts->proto_specific.scsi;
 1259                         struct ccb_trans_settings_spi *spi =
 1260                             &cts->xport_specific.spi;
 1261                         cts->protocol = PROTO_SCSI;
 1262                         cts->protocol_version = SCSI_REV_2;
 1263                         cts->transport = XPORT_SPI;
 1264                         cts->transport_version = 2;
 1265 
 1266                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 1267                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 1268 
 1269                         if ((bt->disc_permitted & target_mask) != 0)
 1270                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
 1271                         if ((bt->tags_permitted & target_mask) != 0)
 1272                                 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
 1273 
 1274                         if ((bt->ultra_permitted & target_mask) != 0)
 1275                                 spi->sync_period = 12;
 1276                         else if ((bt->fast_permitted & target_mask) != 0)
 1277                                 spi->sync_period = 25;
 1278                         else if ((bt->sync_permitted & target_mask) != 0)
 1279                                 spi->sync_period = 50;
 1280                         else
 1281                                 spi->sync_period = 0;
 1282 
 1283                         if (spi->sync_period != 0)
 1284                                 spi->sync_offset = 15;
 1285 
 1286                         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
 1287                         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
 1288 
 1289                         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
 1290                         if ((bt->wide_permitted & target_mask) != 0)
 1291                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 1292                         else
 1293                                 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 1294 
 1295                         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
 1296                                 scsi->valid = CTS_SCSI_VALID_TQ;
 1297                                 spi->valid |= CTS_SPI_VALID_DISC;
 1298                         } else
 1299                                 scsi->valid = 0;
 1300                 } else {
 1301                         btfetchtransinfo(bt, cts);
 1302                 }
 1303 
 1304                 ccb->ccb_h.status = CAM_REQ_CMP;
 1305                 xpt_done(ccb);
 1306                 break;
 1307         }
 1308         case XPT_CALC_GEOMETRY:
 1309         {
 1310                 struct    ccb_calc_geometry *ccg;
 1311                 u_int32_t size_mb;
 1312                 u_int32_t secs_per_cylinder;
 1313 
 1314                 ccg = &ccb->ccg;
 1315                 size_mb = ccg->volume_size
 1316                         / ((1024L * 1024L) / ccg->block_size);
 1317                 
 1318                 if (size_mb >= 1024 && (bt->extended_trans != 0)) {
 1319                         if (size_mb >= 2048) {
 1320                                 ccg->heads = 255;
 1321                                 ccg->secs_per_track = 63;
 1322                         } else {
 1323                                 ccg->heads = 128;
 1324                                 ccg->secs_per_track = 32;
 1325                         }
 1326                 } else {
 1327                         ccg->heads = 64;
 1328                         ccg->secs_per_track = 32;
 1329                 }
 1330                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 1331                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 1332                 ccb->ccb_h.status = CAM_REQ_CMP;
 1333                 xpt_done(ccb);
 1334                 break;
 1335         }
 1336         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
 1337         {
 1338                 btreset(bt, /*hardreset*/TRUE);
 1339                 ccb->ccb_h.status = CAM_REQ_CMP;
 1340                 xpt_done(ccb);
 1341                 break;
 1342         }
 1343         case XPT_TERM_IO:               /* Terminate the I/O process */
 1344                 /* XXX Implement */
 1345                 ccb->ccb_h.status = CAM_REQ_INVALID;
 1346                 xpt_done(ccb);
 1347                 break;
 1348         case XPT_PATH_INQ:              /* Path routing inquiry */
 1349         {
 1350                 struct ccb_pathinq *cpi = &ccb->cpi;
 1351                 
 1352                 cpi->version_num = 1; /* XXX??? */
 1353                 cpi->hba_inquiry = PI_SDTR_ABLE;
 1354                 if (bt->tag_capable != 0)
 1355                         cpi->hba_inquiry |= PI_TAG_ABLE;
 1356                 if (bt->wide_bus != 0)
 1357                         cpi->hba_inquiry |= PI_WIDE_16;
 1358                 cpi->target_sprt = 0;
 1359                 cpi->hba_misc = 0;
 1360                 cpi->hba_eng_cnt = 0;
 1361                 cpi->max_target = bt->wide_bus ? 15 : 7;
 1362                 cpi->max_lun = 7;
 1363                 cpi->initiator_id = bt->scsi_id;
 1364                 cpi->bus_id = cam_sim_bus(sim);
 1365                 cpi->base_transfer_speed = 3300;
 1366                 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 1367                 strlcpy(cpi->hba_vid, "BusLogic", HBA_IDLEN);
 1368                 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 1369                 cpi->unit_number = cam_sim_unit(sim);
 1370                 cpi->ccb_h.status = CAM_REQ_CMP;
 1371                 cpi->transport = XPORT_SPI;
 1372                 cpi->transport_version = 2;
 1373                 cpi->protocol = PROTO_SCSI;
 1374                 cpi->protocol_version = SCSI_REV_2;
 1375                 xpt_done(ccb);
 1376                 break;
 1377         }
 1378         default:
 1379                 ccb->ccb_h.status = CAM_REQ_INVALID;
 1380                 xpt_done(ccb);
 1381                 break;
 1382         }
 1383 }
 1384 
 1385 static void
 1386 btexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
 1387 {
 1388         struct   bt_ccb *bccb;
 1389         union    ccb *ccb;
 1390         struct   bt_softc *bt;
 1391 
 1392         bccb = (struct bt_ccb *)arg;
 1393         ccb = bccb->ccb;
 1394         bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr;
 1395 
 1396         if (error != 0) {
 1397                 if (error != EFBIG)
 1398                         device_printf(bt->dev,
 1399                                       "Unexepected error 0x%x returned from "
 1400                                       "bus_dmamap_load\n", error);
 1401                 if (ccb->ccb_h.status == CAM_REQ_INPROG) {
 1402                         xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
 1403                         ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
 1404                 }
 1405                 btfreeccb(bt, bccb);
 1406                 xpt_done(ccb);
 1407                 return;
 1408         }
 1409                 
 1410         if (nseg != 0) {
 1411                 bt_sg_t *sg;
 1412                 bus_dma_segment_t *end_seg;
 1413                 bus_dmasync_op_t op;
 1414 
 1415                 end_seg = dm_segs + nseg;
 1416 
 1417                 /* Copy the segments into our SG list */
 1418                 sg = bccb->sg_list;
 1419                 while (dm_segs < end_seg) {
 1420                         sg->len = dm_segs->ds_len;
 1421                         sg->addr = dm_segs->ds_addr;
 1422                         sg++;
 1423                         dm_segs++;
 1424                 }
 1425 
 1426                 if (nseg > 1) {
 1427                         bccb->hccb.opcode = INITIATOR_SG_CCB_WRESID;
 1428                         bccb->hccb.data_len = sizeof(bt_sg_t) * nseg;
 1429                         bccb->hccb.data_addr = bccb->sg_list_phys;
 1430                 } else {
 1431                         bccb->hccb.data_len = bccb->sg_list->len;
 1432                         bccb->hccb.data_addr = bccb->sg_list->addr;
 1433                 }
 1434 
 1435                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 1436                         op = BUS_DMASYNC_PREREAD;
 1437                 else
 1438                         op = BUS_DMASYNC_PREWRITE;
 1439 
 1440                 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op);
 1441 
 1442         } else {
 1443                 bccb->hccb.opcode = INITIATOR_CCB;
 1444                 bccb->hccb.data_len = 0;
 1445                 bccb->hccb.data_addr = 0;
 1446         }
 1447 
 1448         /*
 1449          * Last time we need to check if this CCB needs to
 1450          * be aborted.
 1451          */
 1452         if (ccb->ccb_h.status != CAM_REQ_INPROG) {
 1453                 if (nseg != 0)
 1454                         bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
 1455                 btfreeccb(bt, bccb);
 1456                 xpt_done(ccb);
 1457                 return;
 1458         }
 1459                 
 1460         bccb->flags = BCCB_ACTIVE;
 1461         ccb->ccb_h.status |= CAM_SIM_QUEUED;
 1462         LIST_INSERT_HEAD(&bt->pending_ccbs, &ccb->ccb_h, sim_links.le);
 1463 
 1464         callout_reset_sbt(&bccb->timer, SBT_1MS * ccb->ccb_h.timeout, 0,
 1465             bttimeout, bccb, 0);
 1466 
 1467         /* Tell the adapter about this command */
 1468         bt->cur_outbox->ccb_addr = btccbvtop(bt, bccb);
 1469         if (bt->cur_outbox->action_code != BMBO_FREE) {
 1470                 /*
 1471                  * We should never encounter a busy mailbox.
 1472                  * If we do, warn the user, and treat it as
 1473                  * a resource shortage.  If the controller is
 1474                  * hung, one of the pending transactions will
 1475                  * timeout causing us to start recovery operations.
 1476                  */
 1477                 device_printf(bt->dev,
 1478                               "Encountered busy mailbox with %d out of %d "
 1479                               "commands active!!!\n", bt->active_ccbs,
 1480                               bt->max_ccbs);
 1481                 callout_stop(&bccb->timer);
 1482                 if (nseg != 0)
 1483                         bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
 1484                 btfreeccb(bt, bccb);
 1485                 bt->resource_shortage = TRUE;
 1486                 xpt_freeze_simq(bt->sim, /*count*/1);
 1487                 ccb->ccb_h.status = CAM_REQUEUE_REQ;
 1488                 xpt_done(ccb);
 1489                 return;
 1490         }
 1491         bt->cur_outbox->action_code = BMBO_START;       
 1492         bt_outb(bt, COMMAND_REG, BOP_START_MBOX);
 1493         btnextoutbox(bt);
 1494 }
 1495 
 1496 void
 1497 bt_intr(void *arg)
 1498 {
 1499         struct  bt_softc *bt;
 1500 
 1501         bt = arg;
 1502         mtx_lock(&bt->lock);
 1503         bt_intr_locked(bt);
 1504         mtx_unlock(&bt->lock);
 1505 }
 1506 
 1507 void
 1508 bt_intr_locked(struct bt_softc *bt)
 1509 {
 1510         u_int   intstat;
 1511 
 1512         while (((intstat = bt_inb(bt, INTSTAT_REG)) & INTR_PENDING) != 0) {
 1513 
 1514                 if ((intstat & CMD_COMPLETE) != 0) {
 1515                         bt->latched_status = bt_inb(bt, STATUS_REG);
 1516                         bt->command_cmp = TRUE;
 1517                 }
 1518 
 1519                 bt_outb(bt, CONTROL_REG, RESET_INTR);
 1520 
 1521                 if ((intstat & IMB_LOADED) != 0) {
 1522                         while (bt->cur_inbox->comp_code != BMBI_FREE) {
 1523                                 btdone(bt,
 1524                                        btccbptov(bt, bt->cur_inbox->ccb_addr),
 1525                                        bt->cur_inbox->comp_code);
 1526                                 bt->cur_inbox->comp_code = BMBI_FREE;
 1527                                 btnextinbox(bt);
 1528                         }
 1529                 }
 1530 
 1531                 if ((intstat & SCSI_BUS_RESET) != 0) {
 1532                         btreset(bt, /*hardreset*/FALSE);
 1533                 }
 1534         }
 1535 }
 1536 
 1537 static void
 1538 btdone(struct bt_softc *bt, struct bt_ccb *bccb, bt_mbi_comp_code_t comp_code)
 1539 {
 1540         union  ccb        *ccb;
 1541         struct ccb_scsiio *csio;
 1542 
 1543         ccb = bccb->ccb;
 1544         csio = &bccb->ccb->csio;
 1545 
 1546         if ((bccb->flags & BCCB_ACTIVE) == 0) {
 1547                 device_printf(bt->dev,
 1548                               "btdone - Attempt to free non-active BCCB %p\n",
 1549                               (void *)bccb);
 1550                 return;
 1551         }
 1552 
 1553         if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 1554                 bus_dmasync_op_t op;
 1555 
 1556                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
 1557                         op = BUS_DMASYNC_POSTREAD;
 1558                 else
 1559                         op = BUS_DMASYNC_POSTWRITE;
 1560                 bus_dmamap_sync(bt->buffer_dmat, bccb->dmamap, op);
 1561                 bus_dmamap_unload(bt->buffer_dmat, bccb->dmamap);
 1562         }
 1563 
 1564         if (bccb == bt->recovery_bccb) {
 1565                 /*
 1566                  * The recovery BCCB does not have a CCB associated
 1567                  * with it, so short circuit the normal error handling.
 1568                  * We now traverse our list of pending CCBs and process
 1569                  * any that were terminated by the recovery CCBs action.
 1570                  * We also reinstate timeouts for all remaining, pending,
 1571                  * CCBs.
 1572                  */
 1573                 struct cam_path *path;
 1574                 struct ccb_hdr *ccb_h;
 1575                 cam_status error;
 1576 
 1577                 /* Notify all clients that a BDR occurred */
 1578                 error = xpt_create_path(&path, /*periph*/NULL,
 1579                                         cam_sim_path(bt->sim),
 1580                                         bccb->hccb.target_id,
 1581                                         CAM_LUN_WILDCARD);
 1582                 
 1583                 if (error == CAM_REQ_CMP) {
 1584                         xpt_async(AC_SENT_BDR, path, NULL);
 1585                         xpt_free_path(path);
 1586                 }
 1587 
 1588                 ccb_h = LIST_FIRST(&bt->pending_ccbs);
 1589                 while (ccb_h != NULL) {
 1590                         struct bt_ccb *pending_bccb;
 1591 
 1592                         pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr;
 1593                         if (pending_bccb->hccb.target_id
 1594                          == bccb->hccb.target_id) {
 1595                                 pending_bccb->hccb.btstat = BTSTAT_HA_BDR;
 1596                                 ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 1597                                 btdone(bt, pending_bccb, BMBI_ERROR);
 1598                         } else {
 1599                                 callout_reset_sbt(&pending_bccb->timer,
 1600                                     SBT_1MS * ccb_h->timeout, 0, bttimeout,
 1601                                     pending_bccb, 0);
 1602                                 ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 1603                         }
 1604                 }
 1605                 device_printf(bt->dev, "No longer in timeout\n");
 1606                 return;
 1607         }
 1608 
 1609         callout_stop(&bccb->timer);
 1610 
 1611         switch (comp_code) {
 1612         case BMBI_FREE:
 1613                 device_printf(bt->dev,
 1614                               "btdone - CCB completed with free status!\n");
 1615                 break;
 1616         case BMBI_NOT_FOUND:
 1617                 device_printf(bt->dev,
 1618                               "btdone - CCB Abort failed to find CCB\n");
 1619                 break;
 1620         case BMBI_ABORT:
 1621         case BMBI_ERROR:
 1622                 if (bootverbose) {
 1623                         printf("bt: ccb %p - error %x occurred.  "
 1624                                "btstat = %x, sdstat = %x\n",
 1625                                (void *)bccb, comp_code, bccb->hccb.btstat,
 1626                                bccb->hccb.sdstat);
 1627                 }
 1628                 /* An error occurred */
 1629                 switch(bccb->hccb.btstat) {
 1630                 case BTSTAT_DATARUN_ERROR:
 1631                         if (bccb->hccb.data_len == 0) {
 1632                                 /*
 1633                                  * At least firmware 4.22, does this
 1634                                  * for a QUEUE FULL condition.
 1635                                  */
 1636                                 bccb->hccb.sdstat = SCSI_STATUS_QUEUE_FULL;
 1637                         } else if (bccb->hccb.data_len < 0) {
 1638                                 csio->ccb_h.status = CAM_DATA_RUN_ERR;
 1639                                 break;
 1640                         }
 1641                         /* FALLTHROUGH */
 1642                 case BTSTAT_NOERROR:
 1643                 case BTSTAT_LINKED_CMD_COMPLETE:
 1644                 case BTSTAT_LINKED_CMD_FLAG_COMPLETE:
 1645                 case BTSTAT_DATAUNDERUN_ERROR:
 1646 
 1647                         csio->scsi_status = bccb->hccb.sdstat;
 1648                         csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
 1649                         switch(csio->scsi_status) {
 1650                         case SCSI_STATUS_CHECK_COND:
 1651                         case SCSI_STATUS_CMD_TERMINATED:
 1652                                 csio->ccb_h.status |= CAM_AUTOSNS_VALID;
 1653                                 /* Bounce sense back if necessary */
 1654                                 if (bt->sense_buffers != NULL) {
 1655                                         csio->sense_data =
 1656                                             *btsensevaddr(bt, bccb);
 1657                                 }
 1658                                 break;
 1659                         default:
 1660                                 break;
 1661                         case SCSI_STATUS_OK:
 1662                                 csio->ccb_h.status = CAM_REQ_CMP;
 1663                                 break;
 1664                         }
 1665                         csio->resid = bccb->hccb.data_len;
 1666                         break;
 1667                 case BTSTAT_SELTIMEOUT:
 1668                         csio->ccb_h.status = CAM_SEL_TIMEOUT;
 1669                         break;
 1670                 case BTSTAT_UNEXPECTED_BUSFREE:
 1671                         csio->ccb_h.status = CAM_UNEXP_BUSFREE;
 1672                         break;
 1673                 case BTSTAT_INVALID_PHASE:
 1674                         csio->ccb_h.status = CAM_SEQUENCE_FAIL;
 1675                         break;
 1676                 case BTSTAT_INVALID_ACTION_CODE:
 1677                         panic("%s: Inavlid Action code", bt_name(bt));
 1678                         break;
 1679                 case BTSTAT_INVALID_OPCODE:
 1680                         panic("%s: Inavlid CCB Opcode code", bt_name(bt));
 1681                         break;
 1682                 case BTSTAT_LINKED_CCB_LUN_MISMATCH:
 1683                         /* We don't even support linked commands... */
 1684                         panic("%s: Linked CCB Lun Mismatch", bt_name(bt));
 1685                         break;
 1686                 case BTSTAT_INVALID_CCB_OR_SG_PARAM:
 1687                         panic("%s: Invalid CCB or SG list", bt_name(bt));
 1688                         break;
 1689                 case BTSTAT_AUTOSENSE_FAILED:
 1690                         csio->ccb_h.status = CAM_AUTOSENSE_FAIL;
 1691                         break;
 1692                 case BTSTAT_TAGGED_MSG_REJECTED:
 1693                 {
 1694                         struct ccb_trans_settings neg; 
 1695                         struct ccb_trans_settings_scsi *scsi =
 1696                             &neg.proto_specific.scsi;
 1697 
 1698                         neg.protocol = PROTO_SCSI;
 1699                         neg.protocol_version = SCSI_REV_2;
 1700                         neg.transport = XPORT_SPI;
 1701                         neg.transport_version = 2;
 1702                         scsi->valid = CTS_SCSI_VALID_TQ;
 1703                         scsi->flags = 0;
 1704                         xpt_print_path(csio->ccb_h.path);
 1705                         printf("refuses tagged commands.  Performing "
 1706                                "non-tagged I/O\n");
 1707                         xpt_setup_ccb(&neg.ccb_h, csio->ccb_h.path,
 1708                                       /*priority*/1); 
 1709                         xpt_async(AC_TRANSFER_NEG, csio->ccb_h.path, &neg);
 1710                         bt->tags_permitted &= ~(0x01 << csio->ccb_h.target_id);
 1711                         csio->ccb_h.status = CAM_MSG_REJECT_REC;
 1712                         break;
 1713                 }
 1714                 case BTSTAT_UNSUPPORTED_MSG_RECEIVED:
 1715                         /*
 1716                          * XXX You would think that this is
 1717                          *     a recoverable error... Hmmm.
 1718                          */
 1719                         csio->ccb_h.status = CAM_REQ_CMP_ERR;
 1720                         break;
 1721                 case BTSTAT_HA_SOFTWARE_ERROR:
 1722                 case BTSTAT_HA_WATCHDOG_ERROR:
 1723                 case BTSTAT_HARDWARE_FAILURE:
 1724                         /* Hardware reset ??? Can we recover ??? */
 1725                         csio->ccb_h.status = CAM_NO_HBA;
 1726                         break;
 1727                 case BTSTAT_TARGET_IGNORED_ATN:
 1728                 case BTSTAT_OTHER_SCSI_BUS_RESET:
 1729                 case BTSTAT_HA_SCSI_BUS_RESET:
 1730                         if ((csio->ccb_h.status & CAM_STATUS_MASK)
 1731                          != CAM_CMD_TIMEOUT)
 1732                                 csio->ccb_h.status = CAM_SCSI_BUS_RESET;
 1733                         break;
 1734                 case BTSTAT_HA_BDR:
 1735                         if ((bccb->flags & BCCB_DEVICE_RESET) == 0)
 1736                                 csio->ccb_h.status = CAM_BDR_SENT;
 1737                         else
 1738                                 csio->ccb_h.status = CAM_CMD_TIMEOUT;
 1739                         break;
 1740                 case BTSTAT_INVALID_RECONNECT:
 1741                 case BTSTAT_ABORT_QUEUE_GENERATED:
 1742                         csio->ccb_h.status = CAM_REQ_TERMIO;
 1743                         break;
 1744                 case BTSTAT_SCSI_PERROR_DETECTED:
 1745                         csio->ccb_h.status = CAM_UNCOR_PARITY;
 1746                         break;
 1747                 }
 1748                 if (csio->ccb_h.status != CAM_REQ_CMP) {
 1749                         xpt_freeze_devq(csio->ccb_h.path, /*count*/1);
 1750                         csio->ccb_h.status |= CAM_DEV_QFRZN;
 1751                 }
 1752                 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0)
 1753                         ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 1754                 btfreeccb(bt, bccb);
 1755                 xpt_done(ccb);
 1756                 break;
 1757         case BMBI_OK:
 1758                 /* All completed without incident */
 1759                 ccb->ccb_h.status |= CAM_REQ_CMP;
 1760                 if ((bccb->flags & BCCB_RELEASE_SIMQ) != 0)
 1761                         ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
 1762                 btfreeccb(bt, bccb);
 1763                 xpt_done(ccb);
 1764                 break;
 1765         }
 1766 }
 1767 
 1768 static int
 1769 btreset(struct bt_softc* bt, int hard_reset)
 1770 {
 1771         struct   ccb_hdr *ccb_h;
 1772         u_int    status;
 1773         u_int    timeout;
 1774         u_int8_t reset_type;
 1775 
 1776         if (hard_reset != 0)
 1777                 reset_type = HARD_RESET;
 1778         else
 1779                 reset_type = SOFT_RESET;
 1780         bt_outb(bt, CONTROL_REG, reset_type);
 1781 
 1782         /* Wait 5sec. for Diagnostic start */
 1783         timeout = 5 * 10000;
 1784         while (--timeout) {
 1785                 status = bt_inb(bt, STATUS_REG);
 1786                 if ((status & DIAG_ACTIVE) != 0)
 1787                         break;
 1788                 DELAY(100);
 1789         }
 1790         if (timeout == 0) {
 1791                 if (bootverbose)
 1792                         device_printf(bt->dev,
 1793                             "btreset - Diagnostic Active failed to "
 1794                             "assert. status = 0x%x\n", status);
 1795                 return (ETIMEDOUT);
 1796         }
 1797 
 1798         /* Wait 10sec. for Diagnostic end */
 1799         timeout = 10 * 10000;
 1800         while (--timeout) {
 1801                 status = bt_inb(bt, STATUS_REG);
 1802                 if ((status & DIAG_ACTIVE) == 0)
 1803                         break;
 1804                 DELAY(100);
 1805         }
 1806         if (timeout == 0) {
 1807                 panic("%s: btreset - Diagnostic Active failed to drop. "
 1808                        "status = 0x%x\n", bt_name(bt), status);
 1809                 return (ETIMEDOUT);
 1810         }
 1811 
 1812         /* Wait for the host adapter to become ready or report a failure */
 1813         timeout = 10000;
 1814         while (--timeout) {
 1815                 status = bt_inb(bt, STATUS_REG);
 1816                 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0)
 1817                         break;
 1818                 DELAY(100);
 1819         }
 1820         if (timeout == 0) {
 1821                 device_printf(bt->dev,
 1822                     "btreset - Host adapter failed to come ready. "
 1823                     "status = 0x%x\n", status);
 1824                 return (ETIMEDOUT);
 1825         }
 1826 
 1827         /* If the diagnostics failed, tell the user */
 1828         if ((status & DIAG_FAIL) != 0
 1829          || (status & HA_READY) == 0) {
 1830                 device_printf(bt->dev,
 1831                     "btreset - Adapter failed diagnostics\n");
 1832 
 1833                 if ((status & DATAIN_REG_READY) != 0)
 1834                         device_printf(bt->dev,
 1835                             "btreset - Host Adapter Error code = 0x%x\n",
 1836                             bt_inb(bt, DATAIN_REG));
 1837                 return (ENXIO);
 1838         }
 1839 
 1840         /* If we've allocated mailboxes, initialize them */
 1841         if (bt->init_level > 4)
 1842                 btinitmboxes(bt);
 1843 
 1844         /* If we've attached to the XPT, tell it about the event */
 1845         if (bt->path != NULL)
 1846                 xpt_async(AC_BUS_RESET, bt->path, NULL);
 1847 
 1848         /*
 1849          * Perform completion processing for all outstanding CCBs.
 1850          */
 1851         while ((ccb_h = LIST_FIRST(&bt->pending_ccbs)) != NULL) {
 1852                 struct bt_ccb *pending_bccb;
 1853 
 1854                 pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr;
 1855                 pending_bccb->hccb.btstat = BTSTAT_HA_SCSI_BUS_RESET;
 1856                 btdone(bt, pending_bccb, BMBI_ERROR);
 1857         }
 1858 
 1859         return (0);
 1860 }
 1861 
 1862 /*
 1863  * Send a command to the adapter.
 1864  */
 1865 int
 1866 bt_cmd(struct bt_softc *bt, bt_op_t opcode, u_int8_t *params, u_int param_len,
 1867       u_int8_t *reply_data, u_int reply_len, u_int cmd_timeout)
 1868 {
 1869         u_int   timeout;
 1870         u_int   status;
 1871         u_int   saved_status;
 1872         u_int   intstat;
 1873         u_int   reply_buf_size;
 1874         int     cmd_complete;
 1875         int     error;
 1876 
 1877         /* No data returned to start */
 1878         reply_buf_size = reply_len;
 1879         reply_len = 0;
 1880         intstat = 0;
 1881         cmd_complete = 0;
 1882         saved_status = 0;
 1883         error = 0;
 1884 
 1885         bt->command_cmp = 0;
 1886         /*
 1887          * Wait up to 10 sec. for the adapter to become
 1888          * ready to accept commands.
 1889          */
 1890         timeout = 100000;
 1891         while (--timeout) {
 1892                 status = bt_inb(bt, STATUS_REG);
 1893                 if ((status & HA_READY) != 0
 1894                  && (status & CMD_REG_BUSY) == 0)
 1895                         break;
 1896                 /*
 1897                  * Throw away any pending data which may be
 1898                  * left over from earlier commands that we
 1899                  * timedout on.
 1900                  */
 1901                 if ((status & DATAIN_REG_READY) != 0)
 1902                         (void)bt_inb(bt, DATAIN_REG);
 1903                 DELAY(100);
 1904         }
 1905         if (timeout == 0) {
 1906                 device_printf(bt->dev,
 1907                     "bt_cmd: Timeout waiting for adapter ready, "
 1908                     "status = 0x%x\n", status);
 1909                 return (ETIMEDOUT);
 1910         }
 1911 
 1912         /*
 1913          * Send the opcode followed by any necessary parameter bytes.
 1914          */
 1915         bt_outb(bt, COMMAND_REG, opcode);
 1916 
 1917         /*
 1918          * Wait for up to 1sec for each byte of the
 1919          * parameter list sent to be sent.
 1920          */
 1921         timeout = 10000;
 1922         while (param_len && --timeout) {
 1923                 DELAY(100);
 1924                 status = bt_inb(bt, STATUS_REG);
 1925                 intstat = bt_inb(bt, INTSTAT_REG);
 1926         
 1927                 if ((intstat & (INTR_PENDING|CMD_COMPLETE))
 1928                  == (INTR_PENDING|CMD_COMPLETE)) {
 1929                         saved_status = status;
 1930                         cmd_complete = 1;
 1931                         break;
 1932                 }
 1933                 if (bt->command_cmp != 0) {
 1934                         saved_status = bt->latched_status;
 1935                         cmd_complete = 1;
 1936                         break;
 1937                 }
 1938                 if ((status & DATAIN_REG_READY) != 0)
 1939                         break;
 1940                 if ((status & CMD_REG_BUSY) == 0) {
 1941                         bt_outb(bt, COMMAND_REG, *params++);
 1942                         param_len--;
 1943                         timeout = 10000;
 1944                 }
 1945         }
 1946         if (timeout == 0) {
 1947                 device_printf(bt->dev, "bt_cmd: Timeout sending parameters, "
 1948                     "status = 0x%x\n", status);
 1949                 cmd_complete = 1;
 1950                 saved_status = status;
 1951                 error = ETIMEDOUT;
 1952         }
 1953 
 1954         /*
 1955          * Wait for the command to complete.
 1956          */
 1957         while (cmd_complete == 0 && --cmd_timeout) {
 1958 
 1959                 status = bt_inb(bt, STATUS_REG);
 1960                 intstat = bt_inb(bt, INTSTAT_REG);
 1961                 /*
 1962                  * It may be that this command was issued with
 1963                  * controller interrupts disabled.  We'll never
 1964                  * get to our command if an incoming mailbox
 1965                  * interrupt is pending, so take care of completed
 1966                  * mailbox commands by calling our interrupt handler.
 1967                  */
 1968                 if ((intstat & (INTR_PENDING|IMB_LOADED))
 1969                  == (INTR_PENDING|IMB_LOADED))
 1970                         bt_intr_locked(bt);
 1971 
 1972                 if (bt->command_cmp != 0) {
 1973                         /*
 1974                          * Our interrupt handler saw CMD_COMPLETE
 1975                          * status before we did.
 1976                          */
 1977                         cmd_complete = 1;
 1978                         saved_status = bt->latched_status;
 1979                 } else if ((intstat & (INTR_PENDING|CMD_COMPLETE))
 1980                         == (INTR_PENDING|CMD_COMPLETE)) {
 1981                         /*
 1982                          * Our poll (in case interrupts are blocked)
 1983                          * saw the CMD_COMPLETE interrupt.
 1984                          */
 1985                         cmd_complete = 1;
 1986                         saved_status = status;
 1987                 } else if (opcode == BOP_MODIFY_IO_ADDR
 1988                         && (status & CMD_REG_BUSY) == 0) {
 1989                         /*
 1990                          * The BOP_MODIFY_IO_ADDR does not issue a CMD_COMPLETE,
 1991                          * but it should update the status register.  So, we
 1992                          * consider this command complete when the CMD_REG_BUSY
 1993                          * status clears.
 1994                          */
 1995                         saved_status = status;
 1996                         cmd_complete = 1;
 1997                 } else if ((status & DATAIN_REG_READY) != 0) {
 1998                         u_int8_t data;
 1999 
 2000                         data = bt_inb(bt, DATAIN_REG);
 2001                         if (reply_len < reply_buf_size) {
 2002                                 *reply_data++ = data;
 2003                         } else {
 2004                                 device_printf(bt->dev,
 2005                                     "bt_cmd - Discarded reply data byte "
 2006                                     "for opcode 0x%x\n", opcode);
 2007                         }
 2008                         /*
 2009                          * Reset timeout to ensure at least a second
 2010                          * between response bytes.
 2011                          */
 2012                         cmd_timeout = MAX(cmd_timeout, 10000);
 2013                         reply_len++;
 2014 
 2015                 } else if ((opcode == BOP_FETCH_LRAM)
 2016                         && (status & HA_READY) != 0) {
 2017                                 saved_status = status;
 2018                                 cmd_complete = 1;
 2019                 }
 2020                 DELAY(100);
 2021         }
 2022         if (cmd_timeout == 0) {
 2023                 device_printf(bt->dev,
 2024                     "bt_cmd: Timeout waiting for command (%x) "
 2025                     "to complete.\n", opcode);
 2026                 device_printf(bt->dev, "status = 0x%x, intstat = 0x%x, "
 2027                     "rlen %d\n", status, intstat, reply_len);
 2028                 error = (ETIMEDOUT);
 2029         }
 2030 
 2031         /*
 2032          * Clear any pending interrupts.
 2033          */
 2034         bt_intr_locked(bt);
 2035         
 2036         if (error != 0)
 2037                 return (error);
 2038 
 2039         /*
 2040          * If the command was rejected by the controller, tell the caller.
 2041          */
 2042         if ((saved_status & CMD_INVALID) != 0) {
 2043                 /*
 2044                  * Some early adapters may not recover properly from
 2045                  * an invalid command.  If it appears that the controller
 2046                  * has wedged (i.e. status was not cleared by our interrupt
 2047                  * reset above), perform a soft reset.
 2048                  */
 2049                 if (bootverbose)
 2050                         device_printf(bt->dev, "Invalid Command 0x%x\n",
 2051                                 opcode);
 2052                 DELAY(1000);
 2053                 status = bt_inb(bt, STATUS_REG);
 2054                 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY|
 2055                               CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0
 2056                  || (status & (HA_READY|INIT_REQUIRED))
 2057                   != (HA_READY|INIT_REQUIRED)) {
 2058                         btreset(bt, /*hard_reset*/FALSE);
 2059                 }
 2060                 return (EINVAL);
 2061         }
 2062 
 2063         if (param_len > 0) {
 2064                 /* The controller did not accept the full argument list */
 2065                 return (E2BIG);
 2066         }
 2067 
 2068         if (reply_len != reply_buf_size) {
 2069                 /* Too much or too little data received */
 2070                 return (EMSGSIZE);
 2071         }
 2072 
 2073         /* We were successful */
 2074         return (0);
 2075 }
 2076 
 2077 static int
 2078 btinitmboxes(struct bt_softc *bt) {
 2079         init_32b_mbox_params_t init_mbox;
 2080         int error;
 2081 
 2082         bzero(bt->in_boxes, sizeof(bt_mbox_in_t) * bt->num_boxes);
 2083         bzero(bt->out_boxes, sizeof(bt_mbox_out_t) * bt->num_boxes);
 2084         bt->cur_inbox = bt->in_boxes;
 2085         bt->last_inbox = bt->in_boxes + bt->num_boxes - 1;
 2086         bt->cur_outbox = bt->out_boxes;
 2087         bt->last_outbox = bt->out_boxes + bt->num_boxes - 1;
 2088 
 2089         /* Tell the adapter about them */
 2090         init_mbox.num_boxes = bt->num_boxes;
 2091         init_mbox.base_addr[0] = bt->mailbox_physbase & 0xFF;
 2092         init_mbox.base_addr[1] = (bt->mailbox_physbase >> 8) & 0xFF;
 2093         init_mbox.base_addr[2] = (bt->mailbox_physbase >> 16) & 0xFF;
 2094         init_mbox.base_addr[3] = (bt->mailbox_physbase >> 24) & 0xFF;
 2095         error = bt_cmd(bt, BOP_INITIALIZE_32BMBOX, (u_int8_t *)&init_mbox,
 2096                        /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL,
 2097                        /*reply_len*/0, DEFAULT_CMD_TIMEOUT);
 2098 
 2099         if (error != 0)
 2100                 printf("btinitmboxes: Initialization command failed\n");
 2101         else if (bt->strict_rr != 0) {
 2102                 /*
 2103                  * If the controller supports
 2104                  * strict round robin mode,
 2105                  * enable it
 2106                  */
 2107                 u_int8_t param;
 2108 
 2109                 param = 0;
 2110                 error = bt_cmd(bt, BOP_ENABLE_STRICT_RR, &param, 1,
 2111                                /*reply_buf*/NULL, /*reply_len*/0,
 2112                                DEFAULT_CMD_TIMEOUT);
 2113 
 2114                 if (error != 0) {
 2115                         printf("btinitmboxes: Unable to enable strict RR\n");
 2116                         error = 0;
 2117                 } else if (bootverbose) {
 2118                         device_printf(bt->dev,
 2119                             "Using Strict Round Robin Mailbox Mode\n");
 2120                 }
 2121         }
 2122         
 2123         return (error);
 2124 }
 2125 
 2126 /*
 2127  * Update the XPT's idea of the negotiated transfer
 2128  * parameters for a particular target.
 2129  */
 2130 static void
 2131 btfetchtransinfo(struct bt_softc *bt, struct ccb_trans_settings *cts)
 2132 {
 2133         setup_data_t    setup_info;
 2134         u_int           target;
 2135         u_int           targ_offset;
 2136         u_int           targ_mask;
 2137         u_int           sync_period;
 2138         u_int           sync_offset;
 2139         u_int           bus_width;
 2140         int             error;
 2141         u_int8_t        param;
 2142         targ_syncinfo_t sync_info;
 2143         struct ccb_trans_settings_scsi *scsi =
 2144             &cts->proto_specific.scsi;
 2145         struct ccb_trans_settings_spi *spi =
 2146             &cts->xport_specific.spi;
 2147 
 2148         spi->valid = 0;
 2149         scsi->valid = 0;
 2150 
 2151         target = cts->ccb_h.target_id;
 2152         targ_offset = (target & 0x7);
 2153         targ_mask = (0x01 << targ_offset);
 2154 
 2155         /*
 2156          * Inquire Setup Information.  This command retreives the
 2157          * Wide negotiation status for recent adapters as well as
 2158          * the sync info for older models.
 2159          */
 2160         param = sizeof(setup_info);
 2161         error = bt_cmd(bt, BOP_INQUIRE_SETUP_INFO, &param, /*paramlen*/1,
 2162                        (u_int8_t*)&setup_info, sizeof(setup_info),
 2163                        DEFAULT_CMD_TIMEOUT);
 2164 
 2165         if (error != 0) {
 2166                 device_printf(bt->dev,
 2167                     "btfetchtransinfo - Inquire Setup Info Failed %x\n",
 2168                     error);
 2169                 return;
 2170         }
 2171 
 2172         sync_info = (target < 8) ? setup_info.low_syncinfo[targ_offset]
 2173                                  : setup_info.high_syncinfo[targ_offset];
 2174 
 2175         if (sync_info.sync == 0)
 2176                 sync_offset = 0;
 2177         else
 2178                 sync_offset = sync_info.offset;
 2179 
 2180 
 2181         bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 2182         if (strcmp(bt->firmware_ver, "5.06L") >= 0) {
 2183                 u_int wide_active;
 2184 
 2185                 wide_active =
 2186                     (target < 8) ? (setup_info.low_wide_active & targ_mask)
 2187                                  : (setup_info.high_wide_active & targ_mask);
 2188 
 2189                 if (wide_active)
 2190                         bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 2191         } else if ((bt->wide_permitted & targ_mask) != 0) {
 2192                 struct ccb_getdev cgd;
 2193 
 2194                 /*
 2195                  * Prior to rev 5.06L, wide status isn't provided,
 2196                  * so we "guess" that wide transfers are in effect
 2197                  * if the user settings allow for wide and the inquiry
 2198                  * data for the device indicates that it can handle
 2199                  * wide transfers.
 2200                  */
 2201                 xpt_setup_ccb(&cgd.ccb_h, cts->ccb_h.path, /*priority*/1);
 2202                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 2203                 xpt_action((union ccb *)&cgd);
 2204                 if ((cgd.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
 2205                  && (cgd.inq_data.flags & SID_WBus16) != 0)
 2206                         bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 2207         }
 2208 
 2209         if (bt->firmware_ver[0] >= '3') {
 2210                 /*
 2211                  * For adapters that can do fast or ultra speeds,
 2212                  * use the more exact Target Sync Information command.
 2213                  */
 2214                 target_sync_info_data_t sync_info;
 2215 
 2216                 param = sizeof(sync_info);
 2217                 error = bt_cmd(bt, BOP_TARG_SYNC_INFO, &param, /*paramlen*/1,
 2218                                (u_int8_t*)&sync_info, sizeof(sync_info),
 2219                                DEFAULT_CMD_TIMEOUT);
 2220                 
 2221                 if (error != 0) {
 2222                         device_printf(bt->dev,
 2223                             "btfetchtransinfo - Inquire Sync "
 2224                             "Info Failed 0x%x\n", error);
 2225                         return;
 2226                 }
 2227                 sync_period = sync_info.sync_rate[target] * 100;
 2228         } else {
 2229                 sync_period = 2000 + (500 * sync_info.period);
 2230         }
 2231 
 2232         cts->protocol = PROTO_SCSI;
 2233         cts->protocol_version = SCSI_REV_2;
 2234         cts->transport = XPORT_SPI;
 2235         cts->transport_version = 2;
 2236 
 2237         spi->sync_period = sync_period;
 2238         spi->valid |= CTS_SPI_VALID_SYNC_RATE;
 2239         spi->sync_offset = sync_offset;
 2240         spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
 2241 
 2242         spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
 2243         spi->bus_width = bus_width;
 2244 
 2245         if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
 2246                 scsi->valid = CTS_SCSI_VALID_TQ;
 2247                 spi->valid |= CTS_SPI_VALID_DISC;
 2248         } else
 2249                 scsi->valid = 0;
 2250         
 2251         xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts);
 2252 }
 2253 
 2254 static void
 2255 btmapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 2256 {
 2257         struct bt_softc* bt;
 2258 
 2259         bt = (struct bt_softc*)arg;
 2260         bt->mailbox_physbase = segs->ds_addr;
 2261 }
 2262 
 2263 static void
 2264 btmapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 2265 {
 2266         struct bt_softc* bt;
 2267 
 2268         bt = (struct bt_softc*)arg;
 2269         bt->bt_ccb_physbase = segs->ds_addr;
 2270 }
 2271 
 2272 static void
 2273 btmapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 2274 {
 2275 
 2276         struct bt_softc* bt;
 2277 
 2278         bt = (struct bt_softc*)arg;
 2279         SLIST_FIRST(&bt->sg_maps)->sg_physaddr = segs->ds_addr;
 2280 }
 2281 
 2282 static void
 2283 btpoll(struct cam_sim *sim)
 2284 {
 2285         bt_intr_locked(cam_sim_softc(sim));
 2286 }
 2287 
 2288 void
 2289 bttimeout(void *arg)
 2290 {
 2291         struct bt_ccb   *bccb;
 2292         union  ccb      *ccb;
 2293         struct bt_softc *bt;
 2294 
 2295         bccb = (struct bt_ccb *)arg;
 2296         ccb = bccb->ccb;
 2297         bt = (struct bt_softc *)ccb->ccb_h.ccb_bt_ptr;
 2298         mtx_assert(&bt->lock, MA_OWNED);
 2299         xpt_print_path(ccb->ccb_h.path);
 2300         printf("CCB %p - timed out\n", (void *)bccb);
 2301 
 2302         if ((bccb->flags & BCCB_ACTIVE) == 0) {
 2303                 xpt_print_path(ccb->ccb_h.path);
 2304                 printf("CCB %p - timed out CCB already completed\n",
 2305                        (void *)bccb);
 2306                 return;
 2307         }
 2308 
 2309         /*
 2310          * In order to simplify the recovery process, we ask the XPT
 2311          * layer to halt the queue of new transactions and we traverse
 2312          * the list of pending CCBs and remove their timeouts. This
 2313          * means that the driver attempts to clear only one error
 2314          * condition at a time.  In general, timeouts that occur
 2315          * close together are related anyway, so there is no benefit
 2316          * in attempting to handle errors in parallel.  Timeouts will
 2317          * be reinstated when the recovery process ends.
 2318          */
 2319         if ((bccb->flags & BCCB_DEVICE_RESET) == 0) {
 2320                 struct ccb_hdr *ccb_h;
 2321 
 2322                 if ((bccb->flags & BCCB_RELEASE_SIMQ) == 0) {
 2323                         xpt_freeze_simq(bt->sim, /*count*/1);
 2324                         bccb->flags |= BCCB_RELEASE_SIMQ;
 2325                 }
 2326 
 2327                 ccb_h = LIST_FIRST(&bt->pending_ccbs);
 2328                 while (ccb_h != NULL) {
 2329                         struct bt_ccb *pending_bccb;
 2330 
 2331                         pending_bccb = (struct bt_ccb *)ccb_h->ccb_bccb_ptr;
 2332                         callout_stop(&pending_bccb->timer);
 2333                         ccb_h = LIST_NEXT(ccb_h, sim_links.le);
 2334                 }
 2335         }
 2336 
 2337         if ((bccb->flags & BCCB_DEVICE_RESET) != 0
 2338          || bt->cur_outbox->action_code != BMBO_FREE
 2339          || ((bccb->hccb.tag_enable == TRUE)
 2340           && (bt->firmware_ver[0] < '5'))) {
 2341                 /*
 2342                  * Try a full host adapter/SCSI bus reset.
 2343                  * We do this only if we have already attempted
 2344                  * to clear the condition with a BDR, or we cannot
 2345                  * attempt a BDR for lack of mailbox resources
 2346                  * or because of faulty firmware.  It turns out
 2347                  * that firmware versions prior to 5.xx treat BDRs
 2348                  * as untagged commands that cannot be sent until
 2349                  * all outstanding tagged commands have been processed.
 2350                  * This makes it somewhat difficult to use a BDR to
 2351                  * clear up a problem with an uncompleted tagged command.
 2352                  */
 2353                 ccb->ccb_h.status = CAM_CMD_TIMEOUT;
 2354                 btreset(bt, /*hardreset*/TRUE);
 2355                 device_printf(bt->dev, "No longer in timeout\n");
 2356         } else {
 2357                 /*    
 2358                  * Send a Bus Device Reset message:
 2359                  * The target that is holding up the bus may not
 2360                  * be the same as the one that triggered this timeout
 2361                  * (different commands have different timeout lengths),
 2362                  * but we have no way of determining this from our
 2363                  * timeout handler.  Our strategy here is to queue a
 2364                  * BDR message to the target of the timed out command.
 2365                  * If this fails, we'll get another timeout 2 seconds
 2366                  * later which will attempt a bus reset.
 2367                  */
 2368                 bccb->flags |= BCCB_DEVICE_RESET;
 2369                 callout_reset(&bccb->timer, 2 * hz, bttimeout, bccb);
 2370 
 2371                 bt->recovery_bccb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
 2372 
 2373                 /* No Data Transfer */
 2374                 bt->recovery_bccb->hccb.datain = TRUE;
 2375                 bt->recovery_bccb->hccb.dataout = TRUE;
 2376                 bt->recovery_bccb->hccb.btstat = 0;
 2377                 bt->recovery_bccb->hccb.sdstat = 0;
 2378                 bt->recovery_bccb->hccb.target_id = ccb->ccb_h.target_id;
 2379 
 2380                 /* Tell the adapter about this command */
 2381                 bt->cur_outbox->ccb_addr = btccbvtop(bt, bt->recovery_bccb);
 2382                 bt->cur_outbox->action_code = BMBO_START;
 2383                 bt_outb(bt, COMMAND_REG, BOP_START_MBOX);
 2384                 btnextoutbox(bt);
 2385         }
 2386 }
 2387 
 2388 MODULE_VERSION(bt, 1);
 2389 MODULE_DEPEND(bt, cam, 1, 1, 1);

Cache object: 3b45fb335e22bcb7067423c944dfe477


[ 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.