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