Merge branch 'vendor/GDB' into gdb7
[dragonfly.git] / sys / dev / disk / aha / aha.c
1 /*
2  * Generic register and struct definitions for the Adaptech 154x/164x
3  * SCSI host adapters. Product specific probe and attach routines can
4  * be found in:
5  *      aha 1540/1542B/1542C/1542CF/1542CP      aha_isa.c
6  *
7  * Copyright (c) 1998 M. Warner Losh.
8  * All Rights Reserved.
9  *
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  * Derived from bt.c written by:
33  *
34  * Copyright (c) 1998 Justin T. Gibbs.
35  * All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions, and the following disclaimer,
42  *    without modification, immediately at the beginning of the file.
43  * 2. The name of the author may not be used to endorse or promote products
44  *    derived from this software without specific prior written permission.
45  *
46  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
50  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  *
58  * $FreeBSD: src/sys/dev/aha/aha.c,v 1.34.2.1 2000/08/02 22:24:39 peter Exp $
59  * $DragonFly: src/sys/dev/disk/aha/aha.c,v 1.20 2008/05/18 20:30:21 pavalos Exp $
60  */
61
62 #include <sys/param.h>
63 #include <sys/bus.h>
64 #include <sys/systm.h> 
65 #include <sys/malloc.h>
66 #include <sys/buf.h>
67 #include <sys/kernel.h>
68 #include <sys/thread2.h>
69  
70 #include <machine/clock.h>
71
72 #include <bus/cam/cam.h>
73 #include <bus/cam/cam_ccb.h>
74 #include <bus/cam/cam_sim.h>
75 #include <bus/cam/cam_xpt_sim.h>
76 #include <bus/cam/cam_debug.h>
77
78 #include <bus/cam/scsi/scsi_message.h>
79
80 #include <vm/vm.h>
81 #include <vm/pmap.h>
82
83 #include "ahareg.h"
84
85 struct aha_softc *aha_softcs[NAHATOT];
86
87 #define PRVERB(x) do { if (bootverbose) device_printf x; } while(0)
88
89 /* Macro to determine that a rev is potentially a new valid one
90  * so that the driver doesn't keep breaking on new revs as it
91  * did for the CF and CP.
92  */
93 #define PROBABLY_NEW_BOARD(REV) (REV > 0x43 && REV < 0x56)
94
95 /* MailBox Management functions */
96 static __inline void    ahanextinbox(struct aha_softc *aha);
97 static __inline void    ahanextoutbox(struct aha_softc *aha);
98
99 #define aha_name(aha)   device_get_nameunit(aha->dev)
100
101 static __inline void
102 ahanextinbox(struct aha_softc *aha)
103 {
104         if (aha->cur_inbox == aha->last_inbox)
105                 aha->cur_inbox = aha->in_boxes;
106         else
107                 aha->cur_inbox++;
108 }
109
110 static __inline void
111 ahanextoutbox(struct aha_softc *aha)
112 {
113         if (aha->cur_outbox == aha->last_outbox)
114                 aha->cur_outbox = aha->out_boxes;
115         else
116                 aha->cur_outbox++;
117 }
118
119 #define ahautoa24(u,s3)                 \
120         (s3)[0] = ((u) >> 16) & 0xff;   \
121         (s3)[1] = ((u) >> 8) & 0xff;    \
122         (s3)[2] = (u) & 0xff;
123
124 #define aha_a24tou(s3) \
125         (((s3)[0] << 16) | ((s3)[1] << 8) | (s3)[2])
126
127 /* CCB Mangement functions */
128 static __inline u_int32_t               ahaccbvtop(struct aha_softc *aha,
129                                                   struct aha_ccb *accb);
130 static __inline struct aha_ccb*         ahaccbptov(struct aha_softc *aha,
131                                                   u_int32_t ccb_addr);
132
133 static __inline u_int32_t
134 ahaccbvtop(struct aha_softc *aha, struct aha_ccb *accb)
135 {
136         return (aha->aha_ccb_physbase
137               + (u_int32_t)((caddr_t)accb - (caddr_t)aha->aha_ccb_array));
138 }
139 static __inline struct aha_ccb *
140 ahaccbptov(struct aha_softc *aha, u_int32_t ccb_addr)
141 {
142         return (aha->aha_ccb_array +
143               + ((struct aha_ccb*)(intptr_t)ccb_addr -
144                 (struct aha_ccb*)(intptr_t)aha->aha_ccb_physbase));
145 }
146
147 static struct aha_ccb*  ahagetccb(struct aha_softc *aha);
148 static __inline void    ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb);
149 static void             ahaallocccbs(struct aha_softc *aha);
150 static bus_dmamap_callback_t ahaexecuteccb;
151 static void             ahadone(struct aha_softc *aha, struct aha_ccb *accb,
152                                aha_mbi_comp_code_t comp_code);
153
154 /* Host adapter command functions */
155 static int      ahareset(struct aha_softc* aha, int hard_reset);
156
157 /* Initialization functions */
158 static int                      ahainitmboxes(struct aha_softc *aha);
159 static bus_dmamap_callback_t    ahamapmboxes;
160 static bus_dmamap_callback_t    ahamapccbs;
161 static bus_dmamap_callback_t    ahamapsgs;
162
163 /* Transfer Negotiation Functions */
164 static void ahafetchtransinfo(struct aha_softc *aha,
165                              struct ccb_trans_settings *cts);
166
167 /* CAM SIM entry points */
168 #define ccb_accb_ptr spriv_ptr0
169 #define ccb_aha_ptr spriv_ptr1
170 static void     ahaaction(struct cam_sim *sim, union ccb *ccb);
171 static void     ahapoll(struct cam_sim *sim);
172
173 /* Our timeout handler */
174 static timeout_t ahatimeout;
175
176 u_long aha_unit = 0;
177
178 /*
179  * Do our own re-probe protection until a configuration
180  * manager can do it for us.  This ensures that we don't
181  * reprobe a card already found by the EISA or PCI probes.
182  */
183 static struct aha_isa_port aha_isa_ports[] =
184 {
185         { 0x130, 4 },
186         { 0x134, 5 },
187         { 0x230, 2 },
188         { 0x234, 3 },
189         { 0x330, 0 },
190         { 0x334, 1 }
191 };
192
193 /*
194  * I/O ports listed in the order enumerated by the
195  * card for certain op codes.
196  */
197 static u_int16_t aha_board_ports[] =
198 {
199         0x330,
200         0x334,
201         0x230,
202         0x234,
203         0x130,
204         0x134
205 };
206
207 /* Exported functions */
208 struct aha_softc *
209 aha_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh)
210 {
211         struct  aha_softc *aha;
212
213         int unit = device_get_unit(dev);
214         if (unit != AHA_TEMP_UNIT) {
215                 if (unit >= NAHATOT) {
216                         device_printf(dev, "unit number (%d) too high\n", unit);
217                         return NULL;
218                 }
219
220                 /*
221                  * Allocate a storage area for us
222                  */
223                 if (aha_softcs[unit]) {    
224                         device_printf(dev, "memory already allocated\n");
225                         return NULL;    
226                 }
227         }
228
229         aha = kmalloc(sizeof(struct aha_softc), M_DEVBUF, M_INTWAIT | M_ZERO);
230         SLIST_INIT(&aha->free_aha_ccbs);
231         LIST_INIT(&aha->pending_ccbs);
232         SLIST_INIT(&aha->sg_maps);
233         aha->dev = dev;
234         aha->tag = tag;
235         aha->bsh = bsh;
236         aha->ccb_sg_opcode = INITIATOR_SG_CCB_WRESID;
237         aha->ccb_ccb_opcode = INITIATOR_CCB_WRESID;
238
239         if (unit != AHA_TEMP_UNIT) {
240                 aha_softcs[unit] = aha;
241         }
242         return (aha);
243 }
244
245 void
246 aha_free(struct aha_softc *aha)
247 {
248         int unit = device_get_unit(aha->dev);
249
250         switch (aha->init_level) {
251         default:
252         case 8:
253         {
254                 struct sg_map_node *sg_map;
255
256                 while ((sg_map = SLIST_FIRST(&aha->sg_maps))!= NULL) {
257                         SLIST_REMOVE_HEAD(&aha->sg_maps, links);
258                         bus_dmamap_unload(aha->sg_dmat,
259                                           sg_map->sg_dmamap);
260                         bus_dmamem_free(aha->sg_dmat, sg_map->sg_vaddr,
261                                         sg_map->sg_dmamap);
262                         kfree(sg_map, M_DEVBUF);
263                 }
264                 bus_dma_tag_destroy(aha->sg_dmat);
265         }
266                 /* fall through */
267         case 7:
268                 bus_dmamap_unload(aha->ccb_dmat, aha->ccb_dmamap);
269                 /* fall through */
270         case 6:
271                 bus_dmamap_destroy(aha->ccb_dmat, aha->ccb_dmamap);
272                 bus_dmamem_free(aha->ccb_dmat, aha->aha_ccb_array,
273                                 aha->ccb_dmamap);
274                 /* fall through */
275         case 5:
276                 bus_dma_tag_destroy(aha->ccb_dmat);
277                 /* fall through */
278         case 4:
279                 bus_dmamap_unload(aha->mailbox_dmat, aha->mailbox_dmamap);
280                 /* fall through */
281         case 3:
282                 bus_dmamem_free(aha->mailbox_dmat, aha->in_boxes,
283                                 aha->mailbox_dmamap);
284                 bus_dmamap_destroy(aha->mailbox_dmat, aha->mailbox_dmamap);
285                 /* fall through */
286         case 2:
287                 bus_dma_tag_destroy(aha->buffer_dmat);
288                 /* fall through */
289         case 1:
290                 bus_dma_tag_destroy(aha->mailbox_dmat);
291                 /* fall through */
292         case 0:
293                 break;
294         }
295         if (unit != AHA_TEMP_UNIT) {
296                 aha_softcs[unit] = NULL;
297         }
298         kfree(aha, M_DEVBUF);
299 }
300
301 /*
302  * Probe the adapter and verify that the card is an Adaptec.
303  */
304 int
305 aha_probe(struct aha_softc* aha)
306 {
307         u_int    status;
308         u_int    intstat;
309         int      error;
310         board_id_data_t board_id;
311
312         /*
313          * See if the three I/O ports look reasonable.
314          * Touch the minimal number of registers in the
315          * failure case.
316          */
317         status = aha_inb(aha, STATUS_REG);
318         if ((status == 0)
319          || (status & (DIAG_ACTIVE|CMD_REG_BUSY|
320                        STATUS_REG_RSVD)) != 0) {
321                 PRVERB((aha->dev, "status reg test failed %x\n", status));
322                 return (ENXIO);
323         }
324
325         intstat = aha_inb(aha, INTSTAT_REG);
326         if ((intstat & INTSTAT_REG_RSVD) != 0) {
327                 PRVERB((aha->dev, "Failed Intstat Reg Test\n"));
328                 return (ENXIO);
329         }
330
331         /*
332          * Looking good so far.  Final test is to reset the
333          * adapter and fetch the board ID and ensure we aren't
334          * looking at a BusLogic.
335          */
336         if ((error = ahareset(aha, /*hard_reset*/TRUE)) != 0) {
337                 PRVERB((aha->dev, "Failed Reset\n"));
338                 return (ENXIO);
339         }
340
341         /*
342          * Get the board ID.  We use this to see if we're dealing with
343          * a buslogic card or a aha card (or clone).
344          */
345         error = aha_cmd(aha, AOP_INQUIRE_BOARD_ID, NULL, /*parmlen*/0,
346                        (u_int8_t*)&board_id, sizeof(board_id),
347                        DEFAULT_CMD_TIMEOUT);
348         if (error != 0) {
349                 PRVERB((aha->dev, "INQUIRE failed %x\n", error));
350                 return (ENXIO);
351         }
352         aha->fw_major = board_id.firmware_rev_major;
353         aha->fw_minor = board_id.firmware_rev_minor;
354         aha->boardid = board_id.board_type;
355
356         /*
357          * The Buslogic cards have an id of either 0x41 or 0x42.  So
358          * if those come up in the probe, we test the geometry register
359          * of the board.  Adaptec boards that are this old will not have
360          * this register, and return 0xff, while buslogic cards will return
361          * something different.
362          *
363          * It appears that for reasons unknow, for the for the
364          * aha-1542B cards, we need to wait a little bit before trying
365          * to read the geometry register.  I picked 10ms since we have
366          * reports that a for loop to 1000 did the trick, and this
367          * errs on the side of conservatism.  Besides, no one will
368          * notice a 10mS delay here, even the 1542B card users :-)
369          *
370          * Some compatible cards return 0 here.  Some cards also
371          * seem to return 0x7f.
372          *
373          * XXX I'm not sure how this will impact other cloned cards 
374          *
375          * This really should be replaced with the esetup command, since
376          * that appears to be more reliable.  This becomes more and more
377          * true over time as we discover more cards that don't read the
378          * geometry register consistantly.
379          */
380         if (aha->boardid <= 0x42) {
381                 /* Wait 10ms before reading */
382                 DELAY(10000);
383                 status = aha_inb(aha, GEOMETRY_REG);
384                 if (status != 0xff && status != 0x00 && status != 0x7f) {
385                         PRVERB((aha->dev, "Geometry Register test failed 0x%x\n", status));
386                         return (ENXIO);
387                 }
388         }
389         
390         return (0);
391 }
392
393 /*
394  * Pull the boards setup information and record it in our softc.
395  */
396 int
397 aha_fetch_adapter_info(struct aha_softc *aha)
398 {
399         setup_data_t    setup_info;
400         config_data_t config_data;
401         u_int8_t length_param;
402         int      error;
403         struct  aha_extbios extbios;
404         
405         switch (aha->boardid) {
406         case BOARD_1540_16HEAD_BIOS:
407                 ksnprintf(aha->model, sizeof(aha->model), "1540 16 head BIOS");
408                 break;
409         case BOARD_1540_64HEAD_BIOS:
410                 ksnprintf(aha->model, sizeof(aha->model), "1540 64 head BIOS");
411                 break;
412         case BOARD_1542:
413                 ksnprintf(aha->model, sizeof(aha->model), "1540/1542 64 head BIOS");
414                 break;
415         case BOARD_1640:
416                 ksnprintf(aha->model, sizeof(aha->model), "1640");
417                 break;
418         case BOARD_1740:
419                 ksnprintf(aha->model, sizeof(aha->model), "1740A/1742A/1744");
420                 break;
421         case BOARD_1542C:
422                 ksnprintf(aha->model, sizeof(aha->model), "1542C");
423                 break;
424         case BOARD_1542CF:
425                 ksnprintf(aha->model, sizeof(aha->model), "1542CF");
426                 break;
427         case BOARD_1542CP:
428                 ksnprintf(aha->model, sizeof(aha->model), "1542CP");
429                 break;
430         default:
431                 ksnprintf(aha->model, sizeof(aha->model), "Unknown");
432                 break;
433         }
434         /*
435          * If we are a new type of 1542 board (anything newer than a 1542C)
436          * then disable the extended bios so that the
437          * mailbox interface is unlocked.
438          * This is also true for the 1542B Version 3.20. First Adaptec
439          * board that supports >1Gb drives.
440          * No need to check the extended bios flags as some of the
441          * extensions that cause us problems are not flagged in that byte.
442          */
443         if (PROBABLY_NEW_BOARD(aha->boardid) ||
444                 (aha->boardid == 0x41
445                 && aha->fw_major == 0x31 && 
446                 aha->fw_minor >= 0x34)) {
447                 error = aha_cmd(aha, AOP_RETURN_EXT_BIOS_INFO, NULL,
448                         /*paramlen*/0, (u_char *)&extbios, sizeof(extbios),
449                         DEFAULT_CMD_TIMEOUT);
450                 error = aha_cmd(aha, AOP_MBOX_IF_ENABLE, (u_int8_t *)&extbios,
451                         /*paramlen*/2, NULL, 0, DEFAULT_CMD_TIMEOUT);
452         }
453         if (aha->boardid < 0x41)
454                 device_printf(aha->dev, "Warning: aha-1542A won't likely work.\n");
455
456         aha->max_sg = 17;               /* Need >= 17 to do 64k I/O */
457         aha->diff_bus = 0;
458         aha->extended_lun = 0;
459         aha->extended_trans = 0;
460         aha->max_ccbs = 16;
461         /* Determine Sync/Wide/Disc settings */
462         length_param = sizeof(setup_info);
463         error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, &length_param,
464                        /*paramlen*/1, (u_int8_t*)&setup_info,
465                        sizeof(setup_info), DEFAULT_CMD_TIMEOUT);
466         if (error != 0) {
467                 device_printf(aha->dev, "aha_fetch_adapter_info - Failed "
468                        "Get Setup Info\n");
469                 return (error);
470         }
471         if (setup_info.initiate_sync != 0) {
472                 aha->sync_permitted = ALL_TARGETS;
473         }
474         aha->disc_permitted = ALL_TARGETS;
475
476         /* We need as many mailboxes as we can have ccbs */
477         aha->num_boxes = aha->max_ccbs;
478
479         /* Determine our SCSI ID */
480         
481         error = aha_cmd(aha, AOP_INQUIRE_CONFIG, NULL, /*parmlen*/0,
482                        (u_int8_t*)&config_data, sizeof(config_data),
483                        DEFAULT_CMD_TIMEOUT);
484         if (error != 0) {
485                 device_printf(aha->dev, "aha_fetch_adapter_info - Failed Get Config\n");
486                 return (error);
487         }
488         aha->scsi_id = config_data.scsi_id;
489         return (0);
490 }
491
492 /*
493  * Start the board, ready for normal operation
494  */
495 int
496 aha_init(struct aha_softc* aha)
497 {
498         /* Announce the Adapter */
499         device_printf(aha->dev, "AHA-%s FW Rev. %c.%c (ID=%x) ",
500                aha->model, aha->fw_major, aha->fw_minor, aha->boardid);
501
502         if (aha->diff_bus != 0)
503                 kprintf("Diff ");
504         kprintf("SCSI Host Adapter, SCSI ID %d, %d CCBs\n", aha->scsi_id,
505                aha->max_ccbs);
506
507         /*
508          * Create our DMA tags.  These tags define the kinds of device
509          * accessible memory allocations and memory mappings we will 
510          * need to perform during normal operation.
511          *
512          * Unless we need to further restrict the allocation, we rely
513          * on the restrictions of the parent dmat, hence the common
514          * use of MAXADDR and MAXSIZE.
515          */
516
517         /* DMA tag for mapping buffers into device visible space. */
518         if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0,
519                                /*lowaddr*/BUS_SPACE_MAXADDR,
520                                /*highaddr*/BUS_SPACE_MAXADDR,
521                                /*filter*/NULL, /*filterarg*/NULL,
522                                /*maxsize*/MAXBSIZE, /*nsegments*/AHA_NSEG,
523                                /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
524                                /*flags*/BUS_DMA_ALLOCNOW,
525                                &aha->buffer_dmat) != 0) {
526                 goto error_exit;
527         }
528
529         aha->init_level++;
530         /* DMA tag for our mailboxes */
531         if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0,
532                                /*lowaddr*/BUS_SPACE_MAXADDR,
533                                /*highaddr*/BUS_SPACE_MAXADDR,
534                                /*filter*/NULL, /*filterarg*/NULL,
535                                aha->num_boxes * (sizeof(aha_mbox_in_t)
536                                                + sizeof(aha_mbox_out_t)),
537                                /*nsegments*/1,
538                                /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
539                                /*flags*/0, &aha->mailbox_dmat) != 0) {
540                 goto error_exit;
541         }
542
543         aha->init_level++;
544
545         /* Allocation for our mailboxes */
546         if (bus_dmamem_alloc(aha->mailbox_dmat, (void **)&aha->out_boxes,
547                              BUS_DMA_NOWAIT, &aha->mailbox_dmamap) != 0) {
548                 goto error_exit;
549         }
550
551         aha->init_level++;
552
553         /* And permanently map them */
554         bus_dmamap_load(aha->mailbox_dmat, aha->mailbox_dmamap,
555                         aha->out_boxes,
556                         aha->num_boxes * (sizeof(aha_mbox_in_t)
557                                        + sizeof(aha_mbox_out_t)),
558                         ahamapmboxes, aha, /*flags*/0);
559
560         aha->init_level++;
561
562         aha->in_boxes = (aha_mbox_in_t *)&aha->out_boxes[aha->num_boxes];
563
564         ahainitmboxes(aha);
565
566         /* DMA tag for our ccb structures */
567         if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0,
568                                /*lowaddr*/BUS_SPACE_MAXADDR,
569                                /*highaddr*/BUS_SPACE_MAXADDR,
570                                /*filter*/NULL, /*filterarg*/NULL,
571                                aha->max_ccbs * sizeof(struct aha_ccb),
572                                /*nsegments*/1,
573                                /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
574                                /*flags*/0, &aha->ccb_dmat) != 0) {
575                 goto error_exit;
576         }
577
578         aha->init_level++;
579
580         /* Allocation for our ccbs */
581         if (bus_dmamem_alloc(aha->ccb_dmat, (void **)&aha->aha_ccb_array,
582                              BUS_DMA_NOWAIT, &aha->ccb_dmamap) != 0) {
583                 goto error_exit;
584         }
585
586         aha->init_level++;
587
588         /* And permanently map them */
589         bus_dmamap_load(aha->ccb_dmat, aha->ccb_dmamap,
590                         aha->aha_ccb_array,
591                         aha->max_ccbs * sizeof(struct aha_ccb),
592                         ahamapccbs, aha, /*flags*/0);
593
594         aha->init_level++;
595
596         /* DMA tag for our S/G structures.  We allocate in page sized chunks */
597         if (bus_dma_tag_create(aha->parent_dmat, /*alignment*/1, /*boundary*/0,
598                                /*lowaddr*/BUS_SPACE_MAXADDR,
599                                /*highaddr*/BUS_SPACE_MAXADDR,
600                                /*filter*/NULL, /*filterarg*/NULL,
601                                PAGE_SIZE, /*nsegments*/1,
602                                /*maxsegsz*/BUS_SPACE_MAXSIZE_24BIT,
603                                /*flags*/0, &aha->sg_dmat) != 0) {
604                 goto error_exit;
605         }
606
607         aha->init_level++;
608
609         /* Perform initial CCB allocation */
610         bzero(aha->aha_ccb_array, aha->max_ccbs * sizeof(struct aha_ccb));
611         ahaallocccbs(aha);
612
613         if (aha->num_ccbs == 0) {
614                 device_printf(aha->dev,
615                     "aha_init - Unable to allocate initial ccbs\n");
616                 goto error_exit;
617         }
618
619         /*
620          * Note that we are going and return (to probe)
621          */
622         return 0;
623
624 error_exit:
625
626         return (ENXIO);
627 }
628
629 int
630 aha_attach(struct aha_softc *aha)
631 {
632         int tagged_dev_openings;
633         struct cam_devq *devq;
634
635         /*
636          * We don't do tagged queueing, since the aha cards don't
637          * support it.
638          */
639         tagged_dev_openings = 0;
640
641         /*
642          * Create the device queue for our SIM.
643          */
644         devq = cam_simq_alloc(aha->max_ccbs - 1);
645         if (devq == NULL)
646                 return (ENOMEM);
647
648         /*
649          * Construct our SIM entry
650          */
651         aha->sim = cam_sim_alloc(ahaaction, ahapoll, "aha", aha, device_get_unit(aha->dev),
652                                 &sim_mplock, 2, tagged_dev_openings, devq);
653         cam_simq_release(devq);
654         if (aha->sim == NULL) {
655                 return (ENOMEM);
656         }
657         
658         if (xpt_bus_register(aha->sim, 0) != CAM_SUCCESS) {
659                 cam_sim_free(aha->sim);
660                 return (ENXIO);
661         }
662         
663         if (xpt_create_path(&aha->path, /*periph*/NULL,
664                             cam_sim_path(aha->sim), CAM_TARGET_WILDCARD,
665                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
666                 xpt_bus_deregister(cam_sim_path(aha->sim));
667                 cam_sim_free(aha->sim);
668                 return (ENXIO);
669         }
670                 
671         return (0);
672 }
673
674 void
675 aha_find_probe_range(int ioport, int *port_index, int *max_port_index)
676 {
677         if (ioport > 0) {
678                 int i;
679
680                 for (i = 0;i < AHA_NUM_ISAPORTS; i++)
681                         if (ioport <= aha_isa_ports[i].addr)
682                                 break;
683                 if ((i >= AHA_NUM_ISAPORTS)
684                  || (ioport != aha_isa_ports[i].addr)) {
685                         kprintf("\n"
686 "aha_isa_probe: Invalid baseport of 0x%x specified.\n"
687 "aha_isa_probe: Nearest valid baseport is 0x%x.\n"
688 "aha_isa_probe: Failing probe.\n",
689                                ioport,
690                                (i < AHA_NUM_ISAPORTS)
691                                     ? aha_isa_ports[i].addr
692                                     : aha_isa_ports[AHA_NUM_ISAPORTS - 1].addr);
693                         *port_index = *max_port_index = -1;
694                         return;
695                 }
696                 *port_index = *max_port_index = aha_isa_ports[i].bio;
697         } else {
698                 *port_index = 0;
699                 *max_port_index = AHA_NUM_ISAPORTS - 1;
700         }
701 }
702
703 int
704 aha_iop_from_bio(isa_compat_io_t bio_index)
705 {
706         if (bio_index >= 0 && bio_index < AHA_NUM_ISAPORTS)
707                 return (aha_board_ports[bio_index]);
708         return (-1);
709 }
710
711 static void
712 ahaallocccbs(struct aha_softc *aha)
713 {
714         struct aha_ccb *next_ccb;
715         struct sg_map_node *sg_map;
716         bus_addr_t physaddr;
717         aha_sg_t *segs;
718         int newcount;
719         int i;
720
721         next_ccb = &aha->aha_ccb_array[aha->num_ccbs];
722
723         sg_map = kmalloc(sizeof(*sg_map), M_DEVBUF, M_INTWAIT);
724
725         /* Allocate S/G space for the next batch of CCBS */
726         if (bus_dmamem_alloc(aha->sg_dmat, (void **)&sg_map->sg_vaddr,
727                              BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) {
728                 kfree(sg_map, M_DEVBUF);
729                 return;
730         }
731
732         SLIST_INSERT_HEAD(&aha->sg_maps, sg_map, links);
733
734         bus_dmamap_load(aha->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr,
735                         PAGE_SIZE, ahamapsgs, aha, /*flags*/0);
736         
737         segs = sg_map->sg_vaddr;
738         physaddr = sg_map->sg_physaddr;
739
740         newcount = (PAGE_SIZE / (AHA_NSEG * sizeof(aha_sg_t)));
741         for (i = 0; aha->num_ccbs < aha->max_ccbs && i < newcount; i++) {
742                 int error;
743
744                 next_ccb->sg_list = segs;
745                 next_ccb->sg_list_phys = physaddr;
746                 next_ccb->flags = ACCB_FREE;
747                 error = bus_dmamap_create(aha->buffer_dmat, /*flags*/0,
748                                           &next_ccb->dmamap);
749                 if (error != 0)
750                         break;
751                 SLIST_INSERT_HEAD(&aha->free_aha_ccbs, next_ccb, links);
752                 segs += AHA_NSEG;
753                 physaddr += (AHA_NSEG * sizeof(aha_sg_t));
754                 next_ccb++;
755                 aha->num_ccbs++;
756         }
757
758         /* Reserve a CCB for error recovery */
759         if (aha->recovery_accb == NULL) {
760                 aha->recovery_accb = SLIST_FIRST(&aha->free_aha_ccbs);
761                 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
762         }
763 }
764
765 static __inline void
766 ahafreeccb(struct aha_softc *aha, struct aha_ccb *accb)
767 {
768         crit_enter();
769         if ((accb->flags & ACCB_ACTIVE) != 0)
770                 LIST_REMOVE(&accb->ccb->ccb_h, sim_links.le);
771         if (aha->resource_shortage != 0
772          && (accb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
773                 accb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
774                 aha->resource_shortage = FALSE;
775         }
776         accb->flags = ACCB_FREE;
777         SLIST_INSERT_HEAD(&aha->free_aha_ccbs, accb, links);
778         aha->active_ccbs--;
779         crit_exit();
780 }
781
782 static struct aha_ccb*
783 ahagetccb(struct aha_softc *aha)
784 {
785         struct  aha_ccb* accb;
786
787         crit_enter();
788         if ((accb = SLIST_FIRST(&aha->free_aha_ccbs)) != NULL) {
789                 SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
790                 aha->active_ccbs++;
791         } else if (aha->num_ccbs < aha->max_ccbs) {
792                 ahaallocccbs(aha);
793                 accb = SLIST_FIRST(&aha->free_aha_ccbs);
794                 if (accb == NULL)
795                         device_printf(aha->dev, "Can't malloc ACCB\n");
796                 else {
797                         SLIST_REMOVE_HEAD(&aha->free_aha_ccbs, links);
798                         aha->active_ccbs++;
799                 }
800         }
801         crit_exit();
802
803         return (accb);
804 }
805
806 static void
807 ahaaction(struct cam_sim *sim, union ccb *ccb)
808 {
809         struct  aha_softc *aha;
810
811         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahaaction\n"));
812         
813         aha = (struct aha_softc *)cam_sim_softc(sim);
814         
815         switch (ccb->ccb_h.func_code) {
816         /* Common cases first */
817         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
818         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
819         {
820                 struct  aha_ccb *accb;
821                 struct  aha_hccb *hccb;
822
823                 /*
824                  * get a accb to use.
825                  */
826                 if ((accb = ahagetccb(aha)) == NULL) {
827                         crit_enter();
828                         aha->resource_shortage = TRUE;
829                         crit_exit();
830                         xpt_freeze_simq(aha->sim, /*count*/1);
831                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
832                         xpt_done(ccb);
833                         return;
834                 }
835                 
836                 hccb = &accb->hccb;
837
838                 /*
839                  * So we can find the ACCB when an abort is requested
840                  */
841                 accb->ccb = ccb;
842                 ccb->ccb_h.ccb_accb_ptr = accb;
843                 ccb->ccb_h.ccb_aha_ptr = aha;
844
845                 /*
846                  * Put all the arguments for the xfer in the accb
847                  */
848                 hccb->target = ccb->ccb_h.target_id;
849                 hccb->lun = ccb->ccb_h.target_lun;
850                 hccb->ahastat = 0;
851                 hccb->sdstat = 0;
852
853                 if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
854                         struct ccb_scsiio *csio;
855                         struct ccb_hdr *ccbh;
856
857                         csio = &ccb->csio;
858                         ccbh = &csio->ccb_h;
859                         hccb->opcode = aha->ccb_ccb_opcode;
860                         hccb->datain = (ccb->ccb_h.flags & CAM_DIR_IN) != 0;
861                         hccb->dataout = (ccb->ccb_h.flags & CAM_DIR_OUT) != 0;
862                         hccb->cmd_len = csio->cdb_len;
863                         if (hccb->cmd_len > sizeof(hccb->scsi_cdb)) {
864                                 ccb->ccb_h.status = CAM_REQ_INVALID;
865                                 ahafreeccb(aha, accb);
866                                 xpt_done(ccb);
867                                 return;
868                         }
869                         hccb->sense_len = csio->sense_len;
870                         if ((ccbh->flags & CAM_CDB_POINTER) != 0) {
871                                 if ((ccbh->flags & CAM_CDB_PHYS) == 0) {
872                                         bcopy(csio->cdb_io.cdb_ptr,
873                                               hccb->scsi_cdb, hccb->cmd_len);
874                                 } else {
875                                         /* I guess I could map it in... */
876                                         ccbh->status = CAM_REQ_INVALID;
877                                         ahafreeccb(aha, accb);
878                                         xpt_done(ccb);
879                                         return;
880                                 }
881                         } else {
882                                 bcopy(csio->cdb_io.cdb_bytes,
883                                       hccb->scsi_cdb, hccb->cmd_len);
884                         }
885                         /*
886                          * If we have any data to send with this command,
887                          * map it into bus space.
888                          */
889                         /* Only use S/G if there is a transfer */
890                         if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
891                                 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) {
892                                         /*
893                                          * We've been given a pointer
894                                          * to a single buffer.
895                                          */
896                                         if ((ccbh->flags & CAM_DATA_PHYS)==0) {
897                                                 int error;
898
899                                                 crit_enter();
900                                                 error = bus_dmamap_load(
901                                                     aha->buffer_dmat,
902                                                     accb->dmamap,
903                                                     csio->data_ptr,
904                                                     csio->dxfer_len,
905                                                     ahaexecuteccb,
906                                                     accb,
907                                                     /*flags*/0);
908                                                 if (error == EINPROGRESS) {
909                                                         /*
910                                                          * So as to maintain
911                                                          * ordering, freeze the
912                                                          * controller queue
913                                                          * until our mapping is
914                                                          * returned.
915                                                          */
916                                                         xpt_freeze_simq(aha->sim,
917                                                                         1);
918                                                         csio->ccb_h.status |=
919                                                             CAM_RELEASE_SIMQ;
920                                                 }
921                                                 crit_exit();
922                                         } else {
923                                                 struct bus_dma_segment seg; 
924
925                                                 /* Pointer to physical buffer */
926                                                 seg.ds_addr =
927                                                     (bus_addr_t)csio->data_ptr;
928                                                 seg.ds_len = csio->dxfer_len;
929                                                 ahaexecuteccb(accb, &seg, 1, 0);
930                                         }
931                                 } else {
932                                         struct bus_dma_segment *segs;
933
934                                         if ((ccbh->flags & CAM_DATA_PHYS) != 0)
935                                                 panic("ahaaction - Physical "
936                                                       "segment pointers "
937                                                       "unsupported");
938
939                                         if ((ccbh->flags&CAM_SG_LIST_PHYS)==0)
940                                                 panic("ahaaction - Virtual "
941                                                       "segment addresses "
942                                                       "unsupported");
943
944                                         /* Just use the segments provided */
945                                         segs = (struct bus_dma_segment *)
946                                             csio->data_ptr;
947                                         ahaexecuteccb(accb, segs,
948                                                      csio->sglist_cnt, 0);
949                                 }
950                         } else {
951                                 ahaexecuteccb(accb, NULL, 0, 0);
952                         }
953                 } else {
954                         hccb->opcode = INITIATOR_BUS_DEV_RESET;
955                         /* No data transfer */
956                         hccb->datain = TRUE;
957                         hccb->dataout = TRUE;
958                         hccb->cmd_len = 0;
959                         hccb->sense_len = 0;
960                         ahaexecuteccb(accb, NULL, 0, 0);
961                 }
962                 break;
963         }
964         case XPT_EN_LUN:                /* Enable LUN as a target */
965         case XPT_TARGET_IO:             /* Execute target I/O request */
966         case XPT_ACCEPT_TARGET_IO:      /* Accept Host Target Mode CDB */
967         case XPT_CONT_TARGET_IO:        /* Continue Host Target I/O Connection*/
968         case XPT_ABORT:                 /* Abort the specified CCB */
969                 /* XXX Implement */
970                 ccb->ccb_h.status = CAM_REQ_INVALID;
971                 xpt_done(ccb);
972                 break;
973         case XPT_SET_TRAN_SETTINGS:
974         {
975                 /* XXX Implement */
976                 ccb->ccb_h.status = CAM_PROVIDE_FAIL;
977                 xpt_done(ccb);
978                 break;
979         }
980         case XPT_GET_TRAN_SETTINGS:
981         /* Get default/user set transfer settings for the target */
982         {
983                 struct  ccb_trans_settings *cts = &ccb->cts;
984                 u_int   target_mask = 0x01 << ccb->ccb_h.target_id;
985                 struct ccb_trans_settings_scsi *scsi =
986                     &cts->proto_specific.scsi;
987                 struct ccb_trans_settings_spi *spi =
988                     &cts->xport_specific.spi;
989
990                 cts->protocol = PROTO_SCSI;
991                 cts->protocol_version = SCSI_REV_2;
992                 cts->transport = XPORT_SPI;
993                 cts->transport_version = 2;
994                 if (cts->type == CTS_TYPE_USER_SETTINGS) {
995                         spi->flags = 0;
996                         if ((aha->disc_permitted & target_mask) != 0)
997                                 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
998                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
999                         if ((aha->sync_permitted & target_mask) != 0) {
1000                                 if (aha->boardid >= BOARD_1542CF)
1001                                         spi->sync_period = 25;
1002                                 else
1003                                         spi->sync_period = 50;
1004                         } else {
1005                                 spi->sync_period = 0;
1006                         }
1007
1008                         if (spi->sync_period != 0)
1009                                 spi->sync_offset = 15;
1010
1011                         spi->valid = CTS_SPI_VALID_SYNC_RATE
1012                                    | CTS_SPI_VALID_SYNC_OFFSET
1013                                    | CTS_SPI_VALID_BUS_WIDTH
1014                                    | CTS_SPI_VALID_DISC;
1015                         scsi->valid = CTS_SCSI_VALID_TQ;
1016                 } else {
1017                         ahafetchtransinfo(aha, cts);
1018                 }
1019
1020                 ccb->ccb_h.status = CAM_REQ_CMP;
1021                 xpt_done(ccb);
1022                 break;
1023         }
1024         case XPT_CALC_GEOMETRY:
1025         {
1026                 struct    ccb_calc_geometry *ccg;
1027                 u_int32_t size_mb;
1028                 u_int32_t secs_per_cylinder;
1029
1030                 ccg = &ccb->ccg;
1031                 size_mb = ccg->volume_size
1032                         / ((1024L * 1024L) / ccg->block_size);
1033                 
1034                 if (size_mb >= 1024 && (aha->extended_trans != 0)) {
1035                         if (size_mb >= 2048) {
1036                                 ccg->heads = 255;
1037                                 ccg->secs_per_track = 63;
1038                         } else {
1039                                 ccg->heads = 128;
1040                                 ccg->secs_per_track = 32;
1041                         }
1042                 } else {
1043                         ccg->heads = 64;
1044                         ccg->secs_per_track = 32;
1045                 }
1046                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1047                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1048                 ccb->ccb_h.status = CAM_REQ_CMP;
1049                 xpt_done(ccb);
1050                 break;
1051         }
1052         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
1053         {
1054                 ahareset(aha, /*hardreset*/TRUE);
1055                 ccb->ccb_h.status = CAM_REQ_CMP;
1056                 xpt_done(ccb);
1057                 break;
1058         }
1059         case XPT_TERM_IO:               /* Terminate the I/O process */
1060                 /* XXX Implement */
1061                 ccb->ccb_h.status = CAM_REQ_INVALID;
1062                 xpt_done(ccb);
1063                 break;
1064         case XPT_PATH_INQ:              /* Path routing inquiry */
1065         {
1066                 struct ccb_pathinq *cpi = &ccb->cpi;
1067                 
1068                 cpi->version_num = 1; /* XXX??? */
1069                 cpi->hba_inquiry = PI_SDTR_ABLE;
1070                 cpi->target_sprt = 0;
1071                 cpi->hba_misc = 0;
1072                 cpi->hba_eng_cnt = 0;
1073                 cpi->max_target = 7;
1074                 cpi->max_lun = 7;
1075                 cpi->initiator_id = aha->scsi_id;
1076                 cpi->bus_id = cam_sim_bus(sim);
1077                 cpi->base_transfer_speed = 3300;
1078                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1079                 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
1080                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1081                 cpi->unit_number = cam_sim_unit(sim);
1082                 cpi->transport = XPORT_SPI;
1083                 cpi->transport_version = 2;
1084                 cpi->protocol = PROTO_SCSI;
1085                 cpi->protocol_version = SCSI_REV_2;
1086                 cpi->ccb_h.status = CAM_REQ_CMP;
1087                 xpt_done(ccb);
1088                 break;
1089         }
1090         default:
1091                 ccb->ccb_h.status = CAM_REQ_INVALID;
1092                 xpt_done(ccb);
1093                 break;
1094         }
1095 }
1096
1097 static void
1098 ahaexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
1099 {
1100         struct   aha_ccb *accb;
1101         union    ccb *ccb;
1102         struct   aha_softc *aha;
1103         u_int32_t paddr;
1104
1105         accb = (struct aha_ccb *)arg;
1106         ccb = accb->ccb;
1107         aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
1108
1109         if (error != 0) {
1110                 if (error != EFBIG)
1111                         device_printf(aha->dev,
1112                             "Unexpected error 0x%x returned from "
1113                             "bus_dmamap_load\n", error);
1114                 if (ccb->ccb_h.status == CAM_REQ_INPROG) {
1115                         xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
1116                         ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
1117                 }
1118                 ahafreeccb(aha, accb);
1119                 xpt_done(ccb);
1120                 return;
1121         }
1122                 
1123         if (nseg != 0) {
1124                 aha_sg_t *sg;
1125                 bus_dma_segment_t *end_seg;
1126                 bus_dmasync_op_t op;
1127
1128                 end_seg = dm_segs + nseg;
1129
1130                 /* Copy the segments into our SG list */
1131                 sg = accb->sg_list;
1132                 while (dm_segs < end_seg) {
1133                         ahautoa24(dm_segs->ds_len, sg->len);
1134                         ahautoa24(dm_segs->ds_addr, sg->addr);
1135                         sg++;
1136                         dm_segs++;
1137                 }
1138
1139                 if (nseg > 1) {
1140                         accb->hccb.opcode = aha->ccb_sg_opcode;
1141                         ahautoa24((sizeof(aha_sg_t) * nseg),
1142                                   accb->hccb.data_len);
1143                         ahautoa24(accb->sg_list_phys, accb->hccb.data_addr);
1144                 } else {
1145                         bcopy(accb->sg_list->len, accb->hccb.data_len, 3);
1146                         bcopy(accb->sg_list->addr, accb->hccb.data_addr, 3);
1147                 }
1148
1149                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1150                         op = BUS_DMASYNC_PREREAD;
1151                 else
1152                         op = BUS_DMASYNC_PREWRITE;
1153
1154                 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op);
1155
1156         } else {
1157                 accb->hccb.opcode = INITIATOR_CCB;
1158                 ahautoa24(0, accb->hccb.data_len);
1159                 ahautoa24(0, accb->hccb.data_addr);
1160         }
1161
1162         crit_enter();
1163
1164         /*
1165          * Last time we need to check if this CCB needs to
1166          * be aborted.
1167          */
1168         if (ccb->ccb_h.status != CAM_REQ_INPROG) {
1169                 if (nseg != 0)
1170                         bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
1171                 ahafreeccb(aha, accb);
1172                 xpt_done(ccb);
1173                 crit_exit();
1174                 return;
1175         }
1176                 
1177         accb->flags = ACCB_ACTIVE;
1178         ccb->ccb_h.status |= CAM_SIM_QUEUED;
1179         LIST_INSERT_HEAD(&aha->pending_ccbs, &ccb->ccb_h, sim_links.le);
1180
1181         callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
1182             ahatimeout, accb);
1183
1184         /* Tell the adapter about this command */
1185         if (aha->cur_outbox->action_code != AMBO_FREE) {
1186                 /*
1187                  * We should never encounter a busy mailbox.
1188                  * If we do, warn the user, and treat it as
1189                  * a resource shortage.  If the controller is
1190                  * hung, one of the pending transactions will
1191                  * timeout causing us to start recovery operations.
1192                  */
1193                 device_printf(aha->dev,
1194                     "Encountered busy mailbox with %d out of %d "
1195                     "commands active!!!", aha->active_ccbs, aha->max_ccbs);
1196                 callout_stop(&ccb->ccb_h.timeout_ch);
1197                 if (nseg != 0)
1198                         bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
1199                 ahafreeccb(aha, accb);
1200                 aha->resource_shortage = TRUE;
1201                 xpt_freeze_simq(aha->sim, /*count*/1);
1202                 ccb->ccb_h.status = CAM_REQUEUE_REQ;
1203                 xpt_done(ccb);
1204                 crit_exit();
1205                 return;
1206         }
1207         paddr = ahaccbvtop(aha, accb);
1208         ahautoa24(paddr, aha->cur_outbox->ccb_addr);
1209         aha->cur_outbox->action_code = AMBO_START;      
1210         aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
1211
1212         ahanextoutbox(aha);
1213         crit_exit();
1214 }
1215
1216 void
1217 aha_intr(void *arg)
1218 {
1219         struct  aha_softc *aha;
1220         u_int   intstat;
1221
1222         aha = (struct aha_softc *)arg;
1223         while (((intstat = aha_inb(aha, INTSTAT_REG)) & INTR_PENDING) != 0) {
1224                 if ((intstat & CMD_COMPLETE) != 0) {
1225                         aha->latched_status = aha_inb(aha, STATUS_REG);
1226                         aha->command_cmp = TRUE;
1227                 }
1228
1229                 aha_outb(aha, CONTROL_REG, RESET_INTR);
1230
1231                 if ((intstat & IMB_LOADED) != 0) {
1232                         while (aha->cur_inbox->comp_code != AMBI_FREE) {
1233                                 u_int32_t       paddr;
1234                                 paddr = aha_a24tou(aha->cur_inbox->ccb_addr);
1235                                 ahadone(aha,
1236                                        ahaccbptov(aha, paddr),
1237                                        aha->cur_inbox->comp_code);
1238                                 aha->cur_inbox->comp_code = AMBI_FREE;
1239                                 ahanextinbox(aha);
1240                         }
1241                 }
1242
1243                 if ((intstat & SCSI_BUS_RESET) != 0) {
1244                         ahareset(aha, /*hardreset*/FALSE);
1245                 }
1246         }
1247 }
1248
1249 static void
1250 ahadone(struct aha_softc *aha, struct aha_ccb *accb, aha_mbi_comp_code_t comp_code)
1251 {
1252         union  ccb        *ccb;
1253         struct ccb_scsiio *csio;
1254
1255         ccb = accb->ccb;
1256         csio = &accb->ccb->csio;
1257
1258         if ((accb->flags & ACCB_ACTIVE) == 0) {
1259                 device_printf(aha->dev,
1260                     "ahadone - Attempt to free non-active ACCB %p\n",
1261                      (void *)accb);
1262                 return;
1263         }
1264
1265         if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1266                 bus_dmasync_op_t op;
1267
1268                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1269                         op = BUS_DMASYNC_POSTREAD;
1270                 else
1271                         op = BUS_DMASYNC_POSTWRITE;
1272                 bus_dmamap_sync(aha->buffer_dmat, accb->dmamap, op);
1273                 bus_dmamap_unload(aha->buffer_dmat, accb->dmamap);
1274         }
1275
1276         if (accb == aha->recovery_accb) {
1277                 /*
1278                  * The recovery ACCB does not have a CCB associated
1279                  * with it, so short circuit the normal error handling.
1280                  * We now traverse our list of pending CCBs and process
1281                  * any that were terminated by the recovery CCBs action.
1282                  * We also reinstate timeouts for all remaining, pending,
1283                  * CCBs.
1284                  */
1285                 struct cam_path *path;
1286                 struct ccb_hdr *ccb_h;
1287                 cam_status error;
1288
1289                 /* Notify all clients that a BDR occured */
1290                 error = xpt_create_path(&path, /*periph*/NULL,
1291                                         cam_sim_path(aha->sim),
1292                                         accb->hccb.target,
1293                                         CAM_LUN_WILDCARD);
1294                 
1295                 if (error == CAM_REQ_CMP)
1296                         xpt_async(AC_SENT_BDR, path, NULL);
1297
1298                 ccb_h = LIST_FIRST(&aha->pending_ccbs);
1299                 while (ccb_h != NULL) {
1300                         struct aha_ccb *pending_accb;
1301
1302                         pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
1303                         if (pending_accb->hccb.target == accb->hccb.target) {
1304                                 pending_accb->hccb.ahastat = AHASTAT_HA_BDR;
1305                                 ccb_h = LIST_NEXT(ccb_h, sim_links.le);
1306                                 ahadone(aha, pending_accb, AMBI_ERROR);
1307                         } else {
1308                                 callout_reset(&ccb_h->timeout_ch,
1309                                     (ccb_h->timeout * hz) / 1000,
1310                                     ahatimeout, pending_accb);
1311                                 ccb_h = LIST_NEXT(ccb_h, sim_links.le);
1312                         }
1313                 }
1314                 device_printf(aha->dev, "No longer in timeout\n");
1315                 return;
1316         }
1317
1318         callout_stop(&ccb->ccb_h.timeout_ch);
1319
1320         switch (comp_code) {
1321         case AMBI_FREE:
1322                 device_printf(aha->dev,
1323                     "ahadone - CCB completed with free status!\n");
1324                 break;
1325         case AMBI_NOT_FOUND:
1326                 device_printf(aha->dev,
1327                     "ahadone - CCB Abort failed to find CCB\n");
1328                 break;
1329         case AMBI_ABORT:
1330         case AMBI_ERROR:
1331                 /* An error occured */
1332                 if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
1333                         csio->resid = 0;
1334                 else
1335                         csio->resid = aha_a24tou(accb->hccb.data_len);
1336                 switch(accb->hccb.ahastat) {
1337                 case AHASTAT_DATARUN_ERROR:
1338                 {
1339                         if (csio->resid <= 0) {
1340                                 csio->ccb_h.status = CAM_DATA_RUN_ERR;
1341                                 break;
1342                         }
1343                         /* FALLTHROUGH */
1344                 }
1345                 case AHASTAT_NOERROR:
1346                         csio->scsi_status = accb->hccb.sdstat;
1347                         csio->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
1348                         switch(csio->scsi_status) {
1349                         case SCSI_STATUS_CHECK_COND:
1350                         case SCSI_STATUS_CMD_TERMINATED:
1351                                 csio->ccb_h.status |= CAM_AUTOSNS_VALID;
1352                                 /*
1353                                  * The aha writes the sense data at different
1354                                  * offsets based on the scsi cmd len
1355                                  */
1356                                 bcopy((caddr_t) &accb->hccb.scsi_cdb +
1357                                         accb->hccb.cmd_len, 
1358                                         (caddr_t) &csio->sense_data,
1359                                         accb->hccb.sense_len);
1360                                 break;
1361                         default:
1362                                 break;
1363                         case SCSI_STATUS_OK:
1364                                 csio->ccb_h.status = CAM_REQ_CMP;
1365                                 break;
1366                         }
1367                         break;
1368                 case AHASTAT_SELTIMEOUT:
1369                         csio->ccb_h.status = CAM_SEL_TIMEOUT;
1370                         break;
1371                 case AHASTAT_UNEXPECTED_BUSFREE:
1372                         csio->ccb_h.status = CAM_UNEXP_BUSFREE;
1373                         break;
1374                 case AHASTAT_INVALID_PHASE:
1375                         csio->ccb_h.status = CAM_SEQUENCE_FAIL;
1376                         break;
1377                 case AHASTAT_INVALID_ACTION_CODE:
1378                         panic("%s: Inavlid Action code", aha_name(aha));
1379                         break;
1380                 case AHASTAT_INVALID_OPCODE:
1381                         if (accb->hccb.opcode < INITIATOR_CCB_WRESID)
1382                                 panic("%s: Invalid CCB Opcode %x hccb = %p",
1383                                         aha_name(aha), accb->hccb.opcode,
1384                                         &accb->hccb);
1385                         device_printf(aha->dev,
1386                             "AHA-1540A detected, compensating\n");
1387                         aha->ccb_sg_opcode = INITIATOR_SG_CCB;
1388                         aha->ccb_ccb_opcode = INITIATOR_CCB;
1389                         xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
1390                         csio->ccb_h.status = CAM_REQUEUE_REQ;
1391                         break;
1392                 case AHASTAT_LINKED_CCB_LUN_MISMATCH:
1393                         /* We don't even support linked commands... */
1394                         panic("%s: Linked CCB Lun Mismatch", aha_name(aha));
1395                         break;
1396                 case AHASTAT_INVALID_CCB_OR_SG_PARAM:
1397                         panic("%s: Invalid CCB or SG list", aha_name(aha));
1398                         break;
1399                 case AHASTAT_HA_SCSI_BUS_RESET:
1400                         if ((csio->ccb_h.status & CAM_STATUS_MASK)
1401                             != CAM_CMD_TIMEOUT)
1402                                 csio->ccb_h.status = CAM_SCSI_BUS_RESET;
1403                         break;
1404                 case AHASTAT_HA_BDR:
1405                         if ((accb->flags & ACCB_DEVICE_RESET) == 0)
1406                                 csio->ccb_h.status = CAM_BDR_SENT;
1407                         else
1408                                 csio->ccb_h.status = CAM_CMD_TIMEOUT;
1409                         break;
1410                 }
1411                 if (csio->ccb_h.status != CAM_REQ_CMP) {
1412                         xpt_freeze_devq(csio->ccb_h.path, /*count*/1);
1413                         csio->ccb_h.status |= CAM_DEV_QFRZN;
1414                 }
1415                 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
1416                         ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1417                 ahafreeccb(aha, accb);
1418                 xpt_done(ccb);
1419                 break;
1420         case AMBI_OK:
1421                 /* All completed without incident */
1422                 /* XXX DO WE NEED TO COPY SENSE BYTES HERE???? XXX */
1423                 /* I don't think so since it works???? */
1424                 ccb->ccb_h.status |= CAM_REQ_CMP;
1425                 if ((accb->flags & ACCB_RELEASE_SIMQ) != 0)
1426                         ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
1427                 ahafreeccb(aha, accb);
1428                 xpt_done(ccb);
1429                 break;
1430         }
1431 }
1432
1433 static int
1434 ahareset(struct aha_softc* aha, int hard_reset)
1435 {
1436         struct   ccb_hdr *ccb_h;
1437         u_int    status;
1438         u_int    timeout;
1439         u_int8_t reset_type;
1440
1441         if (hard_reset != 0)
1442                 reset_type = HARD_RESET;
1443         else
1444                 reset_type = SOFT_RESET;
1445         aha_outb(aha, CONTROL_REG, reset_type);
1446
1447         /* Wait 5sec. for Diagnostic start */
1448         timeout = 5 * 10000;
1449         while (--timeout) {
1450                 status = aha_inb(aha, STATUS_REG);
1451                 if ((status & DIAG_ACTIVE) != 0)
1452                         break;
1453                 DELAY(100);
1454         }
1455         if (timeout == 0) {
1456                 PRVERB((aha->dev, "ahareset - Diagnostic Active failed to "
1457                     "assert. status = 0x%x\n", status));
1458                 return (ETIMEDOUT);
1459         }
1460
1461         /* Wait 10sec. for Diagnostic end */
1462         timeout = 10 * 10000;
1463         while (--timeout) {
1464                 status = aha_inb(aha, STATUS_REG);
1465                 if ((status & DIAG_ACTIVE) == 0)
1466                         break;
1467                 DELAY(100);
1468         }
1469         if (timeout == 0) {
1470                 panic("%s: ahareset - Diagnostic Active failed to drop. "
1471                        "status = 0x%x\n", aha_name(aha), status);
1472                 return (ETIMEDOUT);
1473         }
1474
1475         /* Wait for the host adapter to become ready or report a failure */
1476         timeout = 10000;
1477         while (--timeout) {
1478                 status = aha_inb(aha, STATUS_REG);
1479                 if ((status & (DIAG_FAIL|HA_READY|DATAIN_REG_READY)) != 0)
1480                         break;
1481                 DELAY(100);
1482         }
1483         if (timeout == 0) {
1484                 device_printf(aha->dev, "ahareset - Host adapter failed to "
1485                     "come ready. status = 0x%x\n", status);
1486                 return (ETIMEDOUT);
1487         }
1488
1489         /* If the diagnostics failed, tell the user */
1490         if ((status & DIAG_FAIL) != 0
1491          || (status & HA_READY) == 0) {
1492                 device_printf(aha->dev, "ahareset - Adapter failed diagnostics\n");
1493                 if ((status & DATAIN_REG_READY) != 0)
1494                         device_printf(aha->dev, "ahareset - Host Adapter "
1495                             "Error code = 0x%x\n", aha_inb(aha, DATAIN_REG));
1496                 return (ENXIO);
1497         }
1498
1499         /* If we've allocated mailboxes, initialize them */
1500         if (aha->init_level > 4)
1501                 ahainitmboxes(aha);
1502
1503         /* If we've attached to the XPT, tell it about the event */
1504         if (aha->path != NULL)
1505                 xpt_async(AC_BUS_RESET, aha->path, NULL);
1506
1507         /*
1508          * Perform completion processing for all outstanding CCBs.
1509          */
1510         while ((ccb_h = LIST_FIRST(&aha->pending_ccbs)) != NULL) {
1511                 struct aha_ccb *pending_accb;
1512
1513                 pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
1514                 pending_accb->hccb.ahastat = AHASTAT_HA_SCSI_BUS_RESET;
1515                 ahadone(aha, pending_accb, AMBI_ERROR);
1516         }
1517
1518         return (0);
1519 }
1520
1521 /*
1522  * Send a command to the adapter.
1523  */
1524 int
1525 aha_cmd(struct aha_softc *aha, aha_op_t opcode, u_int8_t *params, 
1526         u_int param_len, u_int8_t *reply_data, u_int reply_len, 
1527         u_int cmd_timeout)
1528 {
1529         u_int   timeout;
1530         u_int   status;
1531         u_int   saved_status;
1532         u_int   intstat;
1533         u_int   reply_buf_size;
1534         int     cmd_complete;
1535         int     error;
1536
1537         /* No data returned to start */
1538         reply_buf_size = reply_len;
1539         reply_len = 0;
1540         intstat = 0;
1541         cmd_complete = 0;
1542         saved_status = 0;
1543         error = 0;
1544
1545         /*
1546          * All commands except for the "start mailbox" and the "enable
1547          * outgoing mailbox read interrupt" commands cannot be issued
1548          * while there are pending transactions.  Freeze our SIMQ
1549          * and wait for all completions to occur if necessary.
1550          */
1551         timeout = 100000;
1552         crit_enter();
1553         while (LIST_FIRST(&aha->pending_ccbs) != NULL && --timeout) {
1554                 /* Fire the interrupt handler in case interrupts are blocked */
1555                 aha_intr(aha);
1556                 crit_exit();
1557                 DELAY(100);
1558                 crit_enter();
1559         }
1560         crit_exit();
1561
1562         if (timeout == 0) {
1563                 device_printf(aha->dev, "aha_cmd: Timeout waiting for adapter idle\n");
1564                 return (ETIMEDOUT);
1565         }
1566         aha->command_cmp = 0;
1567         /*
1568          * Wait up to 10 sec. for the adapter to become
1569          * ready to accept commands.
1570          */
1571         timeout = 100000;
1572         while (--timeout) {
1573
1574                 status = aha_inb(aha, STATUS_REG);
1575                 if ((status & HA_READY) != 0
1576                  && (status & CMD_REG_BUSY) == 0)
1577                         break;
1578                 /*
1579                  * Throw away any pending data which may be
1580                  * left over from earlier commands that we
1581                  * timedout on.
1582                  */
1583                 if ((status & DATAIN_REG_READY) != 0)
1584                         (void)aha_inb(aha, DATAIN_REG);
1585                 DELAY(100);
1586         }
1587         if (timeout == 0) {
1588                 device_printf(aha->dev, "aha_cmd: Timeout waiting for adapter "
1589                     "ready, status = 0x%x\n", status);
1590                 return (ETIMEDOUT);
1591         }
1592
1593         /*
1594          * Send the opcode followed by any necessary parameter bytes.
1595          */
1596         aha_outb(aha, COMMAND_REG, opcode);
1597
1598         /*
1599          * Wait for up to 1sec to get the parameter list sent
1600          */
1601         timeout = 10000;
1602         while (param_len && --timeout) {
1603                 DELAY(100);
1604                 crit_enter();
1605                 status = aha_inb(aha, STATUS_REG);
1606                 intstat = aha_inb(aha, INTSTAT_REG);
1607                 crit_exit();
1608
1609                 if ((intstat & (INTR_PENDING|CMD_COMPLETE))
1610                  == (INTR_PENDING|CMD_COMPLETE)) {
1611                         saved_status = status;
1612                         cmd_complete = 1;
1613                         break;
1614                 }
1615
1616                 if (aha->command_cmp != 0) {
1617                         saved_status = aha->latched_status;
1618                         cmd_complete = 1;
1619                         break;
1620                 }
1621                 if ((status & DATAIN_REG_READY) != 0)
1622                         break;
1623                 if ((status & CMD_REG_BUSY) == 0) {
1624                         aha_outb(aha, COMMAND_REG, *params++);
1625                         param_len--;
1626                         timeout = 10000;
1627                 }
1628         }
1629         if (timeout == 0) {
1630                 device_printf(aha->dev, "aha_cmd: Timeout sending parameters, "
1631                        "status = 0x%x\n", status);
1632                 error = ETIMEDOUT;
1633         }
1634
1635         /*
1636          * For all other commands, we wait for any output data
1637          * and the final comand completion interrupt.
1638          */
1639         while (cmd_complete == 0 && --cmd_timeout) {
1640
1641                 crit_enter();
1642                 status = aha_inb(aha, STATUS_REG);
1643                 intstat = aha_inb(aha, INTSTAT_REG);
1644                 crit_exit();
1645
1646                 if (aha->command_cmp != 0) {
1647                         cmd_complete = 1;
1648                         saved_status = aha->latched_status;
1649                 } else if ((intstat & (INTR_PENDING|CMD_COMPLETE))
1650                         == (INTR_PENDING|CMD_COMPLETE)) {
1651                         /*
1652                          * Our poll (in case interrupts are blocked)
1653                          * saw the CMD_COMPLETE interrupt.
1654                          */
1655                         cmd_complete = 1;
1656                         saved_status = status;
1657                 }
1658                 if ((status & DATAIN_REG_READY) != 0) {
1659                         u_int8_t data;
1660
1661                         data = aha_inb(aha, DATAIN_REG);
1662                         if (reply_len < reply_buf_size) {
1663                                 *reply_data++ = data;
1664                         } else {
1665                                 device_printf(aha->dev, "aha_cmd - Discarded reply data "
1666                                        "byte for opcode 0x%x\n", opcode);
1667                         }
1668                         /*
1669                          * Reset timeout to ensure at least a second
1670                          * between response bytes.
1671                          */
1672                         cmd_timeout = MAX(cmd_timeout, 10000);
1673                         reply_len++;
1674                 }
1675                 DELAY(100);
1676         }
1677         if (cmd_timeout == 0) {
1678                 device_printf(aha->dev, "aha_cmd: Timeout: status = 0x%x, "
1679                     "intstat = 0x%x, reply_len = %d\n", status, intstat,
1680                     reply_len);
1681                 return (ETIMEDOUT);
1682         }
1683
1684         /*
1685          * Clear any pending interrupts.  Block interrupts so our
1686          * interrupt handler is not re-entered.
1687          */
1688         crit_enter();
1689         aha_intr(aha);
1690         crit_exit();
1691         
1692         if (error != 0)
1693                 return (error);
1694
1695         /*
1696          * If the command was rejected by the controller, tell the caller.
1697          */
1698         if ((saved_status & CMD_INVALID) != 0) {
1699                 PRVERB((aha->dev, "Invalid Command 0x%x\n", opcode));
1700                 /*
1701                  * Some early adapters may not recover properly from
1702                  * an invalid command.  If it appears that the controller
1703                  * has wedged (i.e. status was not cleared by our interrupt
1704                  * reset above), perform a soft reset.
1705                  */
1706                 DELAY(1000);
1707                 status = aha_inb(aha, STATUS_REG);
1708                 if ((status & (CMD_INVALID|STATUS_REG_RSVD|DATAIN_REG_READY|
1709                               CMD_REG_BUSY|DIAG_FAIL|DIAG_ACTIVE)) != 0
1710                  || (status & (HA_READY|INIT_REQUIRED))
1711                   != (HA_READY|INIT_REQUIRED)) {
1712                         ahareset(aha, /*hard_reset*/FALSE);
1713                 }
1714                 return (EINVAL);
1715         }
1716
1717         if (param_len > 0) {
1718                 /* The controller did not accept the full argument list */
1719                 PRVERB((aha->dev, "Controller did not accept full argument "
1720                     "list (%d > 0)\n", param_len));
1721                 return (E2BIG);
1722         }
1723
1724         if (reply_len != reply_buf_size) {
1725                 /* Too much or too little data received */
1726                 PRVERB((aha->dev,"data received mistmatch (%d != %d)\n",
1727                     reply_len, reply_buf_size));
1728                 return (EMSGSIZE);
1729         }
1730
1731         /* We were successful */
1732         return (0);
1733 }
1734
1735 static int
1736 ahainitmboxes(struct aha_softc *aha) 
1737 {
1738         int error;
1739         init_24b_mbox_params_t init_mbox;
1740
1741         bzero(aha->in_boxes, sizeof(aha_mbox_in_t) * aha->num_boxes);
1742         bzero(aha->out_boxes, sizeof(aha_mbox_out_t) * aha->num_boxes);
1743         aha->cur_inbox = aha->in_boxes;
1744         aha->last_inbox = aha->in_boxes + aha->num_boxes - 1;
1745         aha->cur_outbox = aha->out_boxes;
1746         aha->last_outbox = aha->out_boxes + aha->num_boxes - 1;
1747
1748         /* Tell the adapter about them */
1749         init_mbox.num_mboxes = aha->num_boxes;
1750         ahautoa24(aha->mailbox_physbase, init_mbox.base_addr);
1751         error = aha_cmd(aha, AOP_INITIALIZE_MBOX, (u_int8_t *)&init_mbox,
1752                        /*parmlen*/sizeof(init_mbox), /*reply_buf*/NULL,
1753                        /*reply_len*/0, DEFAULT_CMD_TIMEOUT);
1754
1755         if (error != 0)
1756                 device_printf(aha->dev,
1757                     "ahainitmboxes: Initialization command failed\n");
1758         return (error);
1759 }
1760
1761 /*
1762  * Update the XPT's idea of the negotiated transfer
1763  * parameters for a particular target.
1764  */
1765 static void
1766 ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts)
1767 {
1768         setup_data_t    setup_info;
1769         u_int           target;
1770         u_int           targ_offset;
1771         u_int           sync_period;
1772         int             error;
1773         u_int8_t        param;
1774         targ_syncinfo_t sync_info;
1775         struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
1776
1777         target = cts->ccb_h.target_id;
1778         targ_offset = (target & 0x7);
1779
1780         /*
1781          * Inquire Setup Information.  This command retreives
1782          * the sync info for older models.
1783          */
1784         param = sizeof(setup_info);
1785         error = aha_cmd(aha, AOP_INQUIRE_SETUP_INFO, &param, /*paramlen*/1,
1786                        (u_int8_t*)&setup_info, sizeof(setup_info),
1787                        DEFAULT_CMD_TIMEOUT);
1788
1789         if (error != 0) {
1790                 device_printf(aha->dev,
1791                     "ahafetchtransinfo - Inquire Setup Info Failed %d\n",
1792                     error);
1793                 return;
1794         }
1795
1796         sync_info = setup_info.syncinfo[targ_offset];
1797
1798         if (sync_info.sync == 0)
1799                 spi->sync_offset = 0;
1800         else
1801                 spi->sync_offset = sync_info.offset;
1802
1803         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1804
1805         if (aha->boardid >= BOARD_1542CF)
1806                 sync_period = 1000;
1807         else
1808                 sync_period = 2000;
1809         sync_period += 500 * sync_info.period;
1810
1811         /* Convert ns value to standard SCSI sync rate */
1812         if (spi->sync_offset != 0)
1813                 spi->sync_period = scsi_calc_syncparam(sync_period);
1814         else
1815                 spi->sync_period = 0;
1816
1817         spi->valid = CTS_SPI_VALID_SYNC_RATE
1818                    | CTS_SPI_VALID_SYNC_OFFSET
1819                    | CTS_SPI_VALID_BUS_WIDTH;
1820         xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts);
1821 }
1822
1823 static void
1824 ahamapmboxes(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1825 {
1826         struct aha_softc* aha;
1827
1828         aha = (struct aha_softc*)arg;
1829         aha->mailbox_physbase = segs->ds_addr;
1830 }
1831
1832 static void
1833 ahamapccbs(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1834 {
1835         struct aha_softc* aha;
1836
1837         aha = (struct aha_softc*)arg;
1838         aha->aha_ccb_physbase = segs->ds_addr;
1839 }
1840
1841 static void
1842 ahamapsgs(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1843 {
1844
1845         struct aha_softc* aha;
1846
1847         aha = (struct aha_softc*)arg;
1848         SLIST_FIRST(&aha->sg_maps)->sg_physaddr = segs->ds_addr;
1849 }
1850
1851 static void
1852 ahapoll(struct cam_sim *sim)
1853 {
1854         aha_intr(cam_sim_softc(sim));
1855 }
1856
1857 static void
1858 ahatimeout(void *arg)
1859 {
1860         struct aha_ccb  *accb;
1861         union  ccb      *ccb;
1862         struct aha_softc *aha;
1863         u_int32_t       paddr;
1864
1865         accb = (struct aha_ccb *)arg;
1866         ccb = accb->ccb;
1867         aha = (struct aha_softc *)ccb->ccb_h.ccb_aha_ptr;
1868         xpt_print_path(ccb->ccb_h.path);
1869         kprintf("CCB %p - timed out\n", (void *)accb);
1870
1871         crit_enter();
1872
1873         if ((accb->flags & ACCB_ACTIVE) == 0) {
1874                 xpt_print_path(ccb->ccb_h.path);
1875                 kprintf("CCB %p - timed out CCB already completed\n",
1876                        (void *)accb);
1877                 crit_exit();
1878                 return;
1879         }
1880
1881         /*
1882          * In order to simplify the recovery process, we ask the XPT
1883          * layer to halt the queue of new transactions and we traverse
1884          * the list of pending CCBs and remove their timeouts. This
1885          * means that the driver attempts to clear only one error
1886          * condition at a time.  In general, timeouts that occur
1887          * close together are related anyway, so there is no benefit
1888          * in attempting to handle errors in parrallel.  Timeouts will
1889          * be reinstated when the recovery process ends.
1890          */
1891         if ((accb->flags & ACCB_DEVICE_RESET) == 0) {
1892                 struct ccb_hdr *ccb_h;
1893
1894                 if ((accb->flags & ACCB_RELEASE_SIMQ) == 0) {
1895                         xpt_freeze_simq(aha->sim, /*count*/1);
1896                         accb->flags |= ACCB_RELEASE_SIMQ;
1897                 }
1898
1899                 ccb_h = LIST_FIRST(&aha->pending_ccbs);
1900                 while (ccb_h != NULL) {
1901                         struct aha_ccb *pending_accb;
1902
1903                         pending_accb = (struct aha_ccb *)ccb_h->ccb_accb_ptr;
1904                         callout_stop(&ccb_h->timeout_ch);
1905                         ccb_h = LIST_NEXT(ccb_h, sim_links.le);
1906                 }
1907         }
1908
1909         if ((accb->flags & ACCB_DEVICE_RESET) != 0
1910          || aha->cur_outbox->action_code != AMBO_FREE) {
1911                 /*
1912                  * Try a full host adapter/SCSI bus reset.
1913                  * We do this only if we have already attempted
1914                  * to clear the condition with a BDR, or we cannot
1915                  * attempt a BDR for lack of mailbox resources.
1916                  */
1917                 ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1918                 ahareset(aha, /*hardreset*/TRUE);
1919                 device_printf(aha->dev, "No longer in timeout\n");
1920         } else {
1921                 /*    
1922                  * Send a Bus Device Reset message:
1923                  * The target that is holding up the bus may not
1924                  * be the same as the one that triggered this timeout
1925                  * (different commands have different timeout lengths),
1926                  * but we have no way of determining this from our
1927                  * timeout handler.  Our strategy here is to queue a
1928                  * BDR message to the target of the timed out command.
1929                  * If this fails, we'll get another timeout 2 seconds
1930                  * later which will attempt a bus reset.
1931                  */
1932                 accb->flags |= ACCB_DEVICE_RESET;
1933                 callout_reset(&ccb->ccb_h.timeout_ch, 2 * hz, ahatimeout, accb);
1934                 aha->recovery_accb->hccb.opcode = INITIATOR_BUS_DEV_RESET;
1935
1936                 /* No Data Transfer */
1937                 aha->recovery_accb->hccb.datain = TRUE;
1938                 aha->recovery_accb->hccb.dataout = TRUE;
1939                 aha->recovery_accb->hccb.ahastat = 0;
1940                 aha->recovery_accb->hccb.sdstat = 0;
1941                 aha->recovery_accb->hccb.target = ccb->ccb_h.target_id;
1942
1943                 /* Tell the adapter about this command */
1944                 paddr = ahaccbvtop(aha, aha->recovery_accb);
1945                 ahautoa24(paddr, aha->cur_outbox->ccb_addr);
1946                 aha->cur_outbox->action_code = AMBO_START;
1947                 aha_outb(aha, COMMAND_REG, AOP_START_MBOX);
1948                 ahanextoutbox(aha);
1949         }
1950
1951         crit_exit();
1952 }
1953
1954 int
1955 aha_detach(struct aha_softc *aha)
1956 {
1957         xpt_async(AC_LOST_DEVICE, aha->path, NULL);
1958         xpt_free_path(aha->path);
1959         xpt_bus_deregister(cam_sim_path(aha->sim));
1960         cam_sim_free(aha->sim);
1961         return (0);
1962 }