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