Merge branch 'vendor/ZLIB'
[dragonfly.git] / sys / dev / disk / aic / aic.c
1 /*-
2  * Copyright (c) 1999 Luoqi Chen.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/sys/dev/aic/aic.c,v 1.8 2000/01/14 23:42:35 imp Exp $
27  * $DragonFly: src/sys/dev/disk/aic/aic.c,v 1.14 2008/05/18 20:30:21 pavalos Exp $
28  */
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/bus.h>
34 #include <sys/thread2.h>
35
36 #include <bus/cam/cam.h>
37 #include <bus/cam/cam_ccb.h>
38 #include <bus/cam/cam_sim.h>
39 #include <bus/cam/cam_xpt_sim.h>
40 #include <bus/cam/cam_debug.h>
41
42 #include <bus/cam/scsi/scsi_message.h>
43
44 #include "aic6360reg.h"
45 #include "aicvar.h"
46
47 static void aic_action (struct cam_sim *sim, union ccb *ccb);
48 static void aic_execute_scb (void *arg, bus_dma_segment_t *dm_segs,
49                                 int nseg, int error);
50 static void aic_start (struct aic_softc *aic);
51 static void aic_select (struct aic_softc *aic);
52 static void aic_selected (struct aic_softc *aic);
53 static void aic_reselected (struct aic_softc *aic);
54 static void aic_reconnect (struct aic_softc *aic, int tag);
55 static void aic_cmd (struct aic_softc *aic);
56 static void aic_msgin (struct aic_softc *aic);
57 static void aic_handle_msgin (struct aic_softc *aic);
58 static void aic_msgout (struct aic_softc *aic);
59 static void aic_datain (struct aic_softc *aic);
60 static void aic_dataout (struct aic_softc *aic);
61 static void aic_done (struct aic_softc *aic, struct aic_scb *scb);
62 static void aic_poll (struct cam_sim *sim);
63 static void aic_timeout (void *arg);
64 static void aic_scsi_reset (struct aic_softc *aic);
65 static void aic_chip_reset (struct aic_softc *aic);
66 static void aic_reset (struct aic_softc *aic, int initiate_reset);
67
68 devclass_t aic_devclass;
69
70 static struct aic_scb *free_scbs;
71
72 static struct aic_scb *
73 aic_get_scb(struct aic_softc *aic)
74 {
75         struct aic_scb *scb;
76
77         crit_enter();
78
79         if ((scb = free_scbs) != NULL)
80                 free_scbs = (struct aic_scb *)free_scbs->ccb;
81
82         crit_exit();
83         return (scb);
84 }
85
86 static void
87 aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
88 {
89         crit_enter();
90
91         if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
92             (scb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
93                 scb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
94                 aic->flags &= ~AIC_RESOURCE_SHORTAGE;
95         }
96         scb->flags = 0;
97         scb->ccb = (union ccb *)free_scbs;
98         free_scbs = scb;
99
100         crit_exit();
101 }
102
103 static void
104 aic_action(struct cam_sim *sim, union ccb *ccb)
105 {
106         struct aic_softc *aic;
107
108         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("aic_action\n"));
109
110         aic = (struct aic_softc *)cam_sim_softc(sim);
111
112         switch (ccb->ccb_h.func_code) {
113         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
114         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
115         {               
116                 struct aic_scb *scb;
117
118                 if ((scb = aic_get_scb(aic)) == NULL) {
119                         crit_enter();
120                         aic->flags |= AIC_RESOURCE_SHORTAGE;
121                         crit_exit();
122                         xpt_freeze_simq(aic->sim, /*count*/1);
123                         ccb->ccb_h.status = CAM_REQUEUE_REQ;
124                         xpt_done(ccb);
125                         return;
126                 }
127
128                 scb->ccb = ccb;
129                 ccb->ccb_h.ccb_scb_ptr = scb;
130                 ccb->ccb_h.ccb_aic_ptr = aic;
131
132                 scb->target = ccb->ccb_h.target_id;
133                 scb->lun = ccb->ccb_h.target_lun;
134
135                 if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
136                         scb->cmd_len = ccb->csio.cdb_len;
137                         if (ccb->ccb_h.flags & CAM_CDB_POINTER) {
138                                 if (ccb->ccb_h.flags & CAM_CDB_PHYS) {
139                                         ccb->ccb_h.status = CAM_REQ_INVALID;
140                                         aic_free_scb(aic, scb);
141                                         xpt_done(ccb);
142                                         return;
143                                 }
144                                 scb->cmd_ptr = ccb->csio.cdb_io.cdb_ptr;
145                         } else {
146                                 scb->cmd_ptr = ccb->csio.cdb_io.cdb_bytes;
147                         }
148                         if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
149                                 if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) ||
150                                     (ccb->ccb_h.flags & CAM_DATA_PHYS)) {
151                                         ccb->ccb_h.status = CAM_REQ_INVALID;
152                                         aic_free_scb(aic, scb);
153                                         xpt_done(ccb);
154                                         return;
155                                 }
156                                 scb->data_ptr = ccb->csio.data_ptr;
157                                 scb->data_len = ccb->csio.dxfer_len;
158                         } else {
159                                 scb->data_ptr = NULL;
160                                 scb->data_len = 0;
161                         }
162                         aic_execute_scb(scb, NULL, 0, 0);
163                 } else {
164                         scb->flags |= SCB_DEVICE_RESET;
165                         aic_execute_scb(scb, NULL, 0, 0);
166                 }
167                 break;
168         }
169         case XPT_SET_TRAN_SETTINGS:
170         {
171                 struct ccb_trans_settings *cts = cts = &ccb->cts;
172                 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
173                 struct ccb_trans_settings_scsi *scsi =
174                     &cts->proto_specific.scsi;
175                 struct ccb_trans_settings_spi *spi =
176                     &cts->xport_specific.spi;
177
178                 crit_enter();
179
180                 if ((spi->valid & CTS_SPI_VALID_DISC) != 0 &&
181                     (aic->flags & AIC_DISC_ENABLE) != 0) {
182                         if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
183                                 ti->flags |= TINFO_DISC_ENB;
184                         else
185                                 ti->flags &= ~TINFO_DISC_ENB;
186                 }
187
188                 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
189                         if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
190                                 ti->flags |= TINFO_TAG_ENB;
191                         else
192                                 ti->flags &= ~TINFO_TAG_ENB;
193                 }
194
195                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) {
196                         ti->goal.period = spi->sync_period;
197
198                         if (ti->goal.period > aic->min_period) {
199                                 ti->goal.period = 0;
200                                 ti->goal.offset = 0;
201                         } else if (ti->goal.period < aic->max_period)
202                                 ti->goal.period = aic->max_period;
203                 }
204
205                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) {
206                         ti->goal.offset = spi->sync_offset;
207                         if (ti->goal.offset == 0)
208                                 ti->goal.period = 0;
209                         else if (ti->goal.offset > AIC_SYNC_OFFSET)
210                                 ti->goal.offset = AIC_SYNC_OFFSET;
211                 }
212
213                 if ((ti->goal.period != ti->current.period)
214                  || (ti->goal.offset != ti->current.offset))
215                         ti->flags |= TINFO_SDTR_NEGO;
216
217                 crit_exit();
218                 ccb->ccb_h.status = CAM_REQ_CMP;
219                 xpt_done(ccb);
220                 break;
221         }
222         case XPT_GET_TRAN_SETTINGS:
223         {
224                 struct ccb_trans_settings *cts = &ccb->cts;
225                 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
226                 struct ccb_trans_settings_scsi *scsi =
227                     &cts->proto_specific.scsi;
228                 struct ccb_trans_settings_spi *spi =
229                     &cts->xport_specific.spi;
230
231                 cts->protocol = PROTO_SCSI;
232                 cts->protocol_version = SCSI_REV_2;
233                 cts->transport = XPORT_SPI;
234                 cts->transport_version = 2;
235                 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
236                 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
237
238                 crit_enter();
239                 if ((ti->flags & TINFO_DISC_ENB) != 0)
240                         spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
241                 if ((ti->flags & TINFO_TAG_ENB) != 0)
242                         scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
243
244                 if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
245                         spi->sync_period = ti->current.period;
246                         spi->sync_offset = ti->current.offset;
247                 } else {
248                         spi->sync_period = ti->user.period;
249                         spi->sync_offset = ti->user.offset;
250                 }
251                 crit_exit();
252
253                 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
254                 spi->valid = CTS_SPI_VALID_SYNC_RATE
255                            | CTS_SPI_VALID_SYNC_OFFSET
256                            | CTS_SPI_VALID_BUS_WIDTH
257                            | CTS_SPI_VALID_DISC;
258                 scsi->valid = CTS_SCSI_VALID_TQ;
259
260                 ccb->ccb_h.status = CAM_REQ_CMP;
261                 xpt_done(ccb);
262                 break;
263         }
264         case XPT_CALC_GEOMETRY:
265         {
266                 cam_calc_geometry(&ccb->ccg, /*extended*/1);
267                 xpt_done(ccb);
268                 break;
269         }
270         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
271                 aic_reset(aic, /*initiate_reset*/TRUE);
272                 ccb->ccb_h.status = CAM_REQ_CMP;
273                 xpt_done(ccb);
274                 break;
275         case XPT_PATH_INQ:              /* Path routing inquiry */
276         {       
277                 struct ccb_pathinq *cpi = &ccb->cpi;
278
279                 cpi->version_num = 1; /* XXX??? */
280                 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
281                 cpi->target_sprt = 0;
282                 cpi->hba_misc = 0;
283                 cpi->hba_eng_cnt = 0;
284                 cpi->max_target = 7;
285                 cpi->max_lun = 7;
286                 cpi->initiator_id = aic->initiator;
287                 cpi->bus_id = cam_sim_bus(sim);
288                 cpi->base_transfer_speed = 3300;
289                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
290                 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
291                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
292                 cpi->unit_number = cam_sim_unit(sim);
293                 cpi->transport = XPORT_SPI;
294                 cpi->transport_version = 2;
295                 cpi->protocol = PROTO_SCSI;
296                 cpi->protocol_version = SCSI_REV_2;
297                 cpi->ccb_h.status = CAM_REQ_CMP;
298                 xpt_done(ccb);
299                 break;
300         }
301         default:
302                 ccb->ccb_h.status = CAM_REQ_INVALID;
303                 xpt_done(ccb);
304                 break;
305         }
306 }
307
308 static void
309 aic_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
310 {
311         struct aic_scb *scb = (struct aic_scb *)arg;
312         union ccb *ccb = scb->ccb;
313         struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
314
315         crit_enter();
316
317         if (ccb->ccb_h.status != CAM_REQ_INPROG) {
318                 crit_exit();
319                 aic_free_scb(aic, scb);
320                 xpt_done(ccb);
321                 return;
322         }
323
324         scb->flags |= SCB_ACTIVE;
325         ccb->ccb_h.status |= CAM_SIM_QUEUED;
326         TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
327
328         callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
329                       aic_timeout, scb);
330
331         aic_start(aic);
332         crit_exit();
333 }
334
335 /*
336  * Start another command if the controller is not busy.
337  */
338 static void
339 aic_start(struct aic_softc *aic)
340 {
341         struct ccb_hdr *ccb_h;
342         struct aic_tinfo *ti;
343
344         if (aic->state != AIC_IDLE)
345                 return;
346
347         TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
348                 ti = &aic->tinfo[ccb_h->target_id];
349                 if ((ti->lubusy & (1 << ccb_h->target_lun)) == 0) {
350                         TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
351                         aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr;
352                         aic_select(aic);
353                         return;
354                 }
355         }
356
357         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_start: idle\n"));
358
359         aic_outb(aic, SIMODE0, ENSELDI);
360         aic_outb(aic, SIMODE1, ENSCSIRST);
361         aic_outb(aic, SCSISEQ, ENRESELI);
362 }
363
364 /*
365  * Start a selection.
366  */
367 static void
368 aic_select(struct aic_softc *aic)
369 {
370         struct aic_scb *scb = aic->nexus;
371
372         CAM_DEBUG(scb->ccb->ccb_h.path, CAM_DEBUG_TRACE,
373                   ("aic_select - ccb %p\n", scb->ccb));
374
375         aic->state = AIC_SELECTING;
376
377         aic_outb(aic, DMACNTRL1, 0);
378         aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target);
379         aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER |
380             (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0));
381
382         aic_outb(aic, SIMODE0, ENSELDI|ENSELDO);
383         aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO);
384         aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO);
385 }
386
387 /*
388  * We have successfully selected a target, prepare for the information
389  * transfer phases.
390  */
391 static void
392 aic_selected(struct aic_softc *aic)
393 {
394         struct aic_scb *scb = aic->nexus;
395         union ccb *ccb = scb->ccb;
396         struct aic_tinfo *ti = &aic->tinfo[scb->target];
397
398         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE,
399                   ("aic_selected - ccb %p\n", ccb));
400
401         aic->state = AIC_HASNEXUS;
402
403         if (scb->flags & SCB_DEVICE_RESET) {
404                 aic->msg_buf[0] = MSG_BUS_DEV_RESET;
405                 aic->msg_len = 1;
406                 aic->msg_outq = AIC_MSG_MSGBUF;
407         } else {
408                 aic->msg_outq = AIC_MSG_IDENTIFY;
409                 if ((ti->flags & TINFO_TAG_ENB) != 0 &&
410                     (ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0)
411                         aic->msg_outq |= AIC_MSG_TAG_Q;
412                 else
413                         ti->lubusy |= 1 << scb->lun;
414                 if ((ti->flags & TINFO_SDTR_NEGO) != 0)
415                         aic->msg_outq |= AIC_MSG_SDTR;
416         }
417
418         aic_outb(aic, CLRSINT0, CLRSELDO);
419         aic_outb(aic, CLRSINT1, CLRBUSFREE);
420         aic_outb(aic, SCSISEQ, ENAUTOATNP);
421         aic_outb(aic, SIMODE0, 0);
422         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
423         aic_outb(aic, SCSIRATE, ti->scsirate);
424 }
425
426 /*
427  * We are re-selected by a target, save the target id and wait for the
428  * target to further identify itself.
429  */
430 static void
431 aic_reselected(struct aic_softc *aic)
432 {
433         u_int8_t selid;
434
435         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reselected\n"));
436
437         /*
438          * If we have started a selection, it must have lost out in
439          * the arbitration, put the command back to the pending queue.
440          */
441         if (aic->nexus) {
442                 TAILQ_INSERT_HEAD(&aic->pending_ccbs,
443                     &aic->nexus->ccb->ccb_h, sim_links.tqe);
444                 aic->nexus = NULL;
445         }
446
447         selid = aic_inb(aic, SELID) & ~(1 << aic->initiator);
448         if (selid & (selid - 1)) {
449                 /* this should never have happened */
450                 kprintf("aic_reselected: invalid selid %x\n", selid);
451                 aic_reset(aic, /*initiate_reset*/TRUE);
452                 return;
453         }
454
455         aic->state = AIC_RESELECTED;
456         aic->target = ffs(selid) - 1;
457         aic->lun = -1;
458
459         aic_outb(aic, CLRSINT0, CLRSELDI);
460         aic_outb(aic, CLRSINT1, CLRBUSFREE);
461         aic_outb(aic, SIMODE0, 0);
462         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
463         aic_outb(aic, SCSISEQ, ENAUTOATNP);
464         aic_outb(aic, SCSIRATE, aic->tinfo[aic->target].scsirate);
465 }
466
467 /*
468  * Raise ATNO to signal the target that we have a message for it.
469  */
470 static __inline void
471 aic_sched_msgout(struct aic_softc *aic, u_int8_t msg)
472 {
473         if (msg) {
474                 aic->msg_buf[0] = msg;
475                 aic->msg_len = 1;
476         }
477         aic->msg_outq |= AIC_MSG_MSGBUF;
478         aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO);
479 }
480
481 /*
482  * Wait for SPIORDY (SCSI PIO ready) flag, or a phase change.
483  */
484 static __inline int
485 aic_spiordy(struct aic_softc *aic)
486 {
487         while (!(aic_inb(aic, DMASTAT) & INTSTAT) &&
488             !(aic_inb(aic, SSTAT0) & SPIORDY))
489                 ;
490         return !(aic_inb(aic, DMASTAT) & INTSTAT);
491 }
492
493 /*
494  * Reestablish a disconnected nexus.
495  */
496 static void
497 aic_reconnect(struct aic_softc *aic, int tag)
498 {
499         struct aic_scb *scb;
500         struct ccb_hdr *ccb_h;
501
502         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reconnect\n"));
503
504         /* Find the nexus */
505         scb = NULL;
506         TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
507                 scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
508                 if (scb->target == aic->target && scb->lun == aic->lun &&
509                     (tag == -1 || scb->tag == tag))
510                         break;
511         }
512
513         /* ABORT if nothing is found */
514         if (!ccb_h) {
515                 if (tag == -1)
516                         aic_sched_msgout(aic, MSG_ABORT);
517                 else
518                         aic_sched_msgout(aic, MSG_ABORT_TAG);
519                 xpt_async(AC_UNSOL_RESEL, aic->path, NULL);
520                 return;
521         }
522
523         /* Reestablish the nexus */
524         TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
525         aic->nexus = scb;
526         scb->flags &= ~SCB_DISCONNECTED;
527         aic->state = AIC_HASNEXUS;
528 }
529
530 /*
531  * Read messages.
532  */
533 static void
534 aic_msgin(struct aic_softc *aic)
535 {
536         int msglen;
537
538         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgin\n"));
539
540         aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
541         aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
542
543         aic->flags &= ~AIC_DROP_MSGIN;
544         aic->msg_len = 0;
545         do {
546                 /*
547                  * If a parity error is detected, drop the remaining
548                  * bytes and inform the target so it could resend
549                  * the messages.
550                  */
551                 if (aic_inb(aic, SSTAT1) & SCSIPERR) {
552                         aic_outb(aic, CLRSINT1, CLRSCSIPERR);
553                         aic->flags |= AIC_DROP_MSGIN;
554                         aic_sched_msgout(aic, MSG_PARITY_ERROR);
555                 }
556                 if ((aic->flags & AIC_DROP_MSGIN)) {
557                         aic_inb(aic, SCSIDAT);
558                         continue;
559                 }
560                 /* read the message byte without ACKing on it */
561                 aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS);
562                 if (aic->msg_buf[0] == MSG_EXTENDED) {
563                         if (aic->msg_len < 2) {
564                                 (void) aic_inb(aic, SCSIDAT);
565                                 continue;
566                         }
567                         switch (aic->msg_buf[2]) {
568                         case MSG_EXT_SDTR:
569                                 msglen = MSG_EXT_SDTR_LEN;
570                                 break;
571                         case MSG_EXT_WDTR:
572                                 msglen = MSG_EXT_WDTR_LEN;
573                                 break;
574                         default:
575                                 msglen = 0;
576                                 break;
577                         }
578                         if (aic->msg_buf[1] != msglen) {
579                                 aic->flags |= AIC_DROP_MSGIN;
580                                 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
581                         }
582                         msglen += 2;
583                 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f)
584                         msglen = 2;
585                 else
586                         msglen = 1;
587                 /*
588                  * If we have a complete message, handle it before the final
589                  * ACK (in case we decide to reject the message).
590                  */
591                 if (aic->msg_len == msglen) {
592                         aic_handle_msgin(aic);
593                         aic->msg_len = 0;
594                 }
595                 /* ACK on the message byte */
596                 (void) aic_inb(aic, SCSIDAT);
597         } while (aic_spiordy(aic));
598
599         aic_outb(aic, SXFRCTL0, CHEN);
600         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
601 }
602
603 /*
604  * Handle a message.
605  */
606 static void
607 aic_handle_msgin(struct aic_softc *aic)
608 {
609         struct aic_scb *scb;
610         struct ccb_hdr *ccb_h;
611         struct aic_tinfo *ti;
612         struct ccb_trans_settings neg;
613         struct ccb_trans_settings_spi *spi = &neg.xport_specific.spi;
614
615         if (aic->state == AIC_RESELECTED) {
616                 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) {
617                         aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
618                         return;
619                 }
620                 aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK;
621                 if (aic->tinfo[aic->target].lubusy & (1 << aic->lun))
622                         aic_reconnect(aic, -1);
623                 else
624                         aic->state = AIC_RECONNECTING;
625                 return;
626         }
627
628         if (aic->state == AIC_RECONNECTING) {
629                 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) {
630                         aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
631                         return;
632                 }
633                 aic_reconnect(aic, aic->msg_buf[1]);
634                 return;
635         }
636
637         switch (aic->msg_buf[0]) {
638         case MSG_CMDCOMPLETE: {
639                 struct ccb_scsiio *csio;
640                 scb = aic->nexus;
641                 ccb_h = &scb->ccb->ccb_h;
642                 csio = &scb->ccb->csio;
643                 if ((scb->flags & SCB_SENSE) != 0) {
644                         /* auto REQUEST SENSE command */
645                         scb->flags &= ~SCB_SENSE;
646                         csio->sense_resid = scb->data_len;
647                         if (scb->status == SCSI_STATUS_OK) {
648                                 ccb_h->status |=
649                                     CAM_SCSI_STATUS_ERROR|CAM_AUTOSNS_VALID;
650                                 /*scsi_sense_print(csio);*/
651                         } else {
652                                 ccb_h->status |= CAM_AUTOSENSE_FAIL;
653                                 kprintf("ccb %p sense failed %x\n",
654                                     ccb_h, scb->status);
655                         }
656                 } else {
657                         csio->scsi_status = scb->status;
658                         csio->resid = scb->data_len;
659                         if (scb->status == SCSI_STATUS_OK) {
660                                 /* everything goes well */
661                                 ccb_h->status |= CAM_REQ_CMP;
662                         } else if ((ccb_h->flags & CAM_DIS_AUTOSENSE) == 0 &&
663                             (csio->scsi_status == SCSI_STATUS_CHECK_COND ||
664                              csio->scsi_status == SCSI_STATUS_CMD_TERMINATED)) {
665                                 /* try to retrieve sense information */
666                                 scb->flags |= SCB_SENSE;
667                                 aic->flags |= AIC_BUSFREE_OK;
668                                 return;
669                         } else
670                                 ccb_h->status |= CAM_SCSI_STATUS_ERROR;
671                 }
672                 aic_done(aic, scb);
673                 aic->flags |= AIC_BUSFREE_OK;
674                 break;
675         }
676         case MSG_EXTENDED:
677                 switch (aic->msg_buf[2]) {
678                 case MSG_EXT_SDTR:
679                         scb = aic->nexus;
680                         ti = &aic->tinfo[scb->target];
681                         if (ti->flags & TINFO_SDTR_SENT) {
682                                 ti->current.period = aic->msg_buf[3];
683                                 ti->current.offset = aic->msg_buf[4];
684                         } else {
685                                 ti->current.period = aic->msg_buf[3] =
686                                         max(ti->goal.period, aic->msg_buf[3]);
687                                 ti->current.offset = aic->msg_buf[4] =
688                                         min(ti->goal.offset, aic->msg_buf[4]);
689                                 /*
690                                  * The target initiated the negotiation,
691                                  * send back a response.
692                                  */
693                                 aic_sched_msgout(aic, 0);
694                         }
695                         ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO);
696                         ti->scsirate = ti->current.offset ? ti->current.offset |
697                             ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0;
698                         aic_outb(aic, SCSIRATE, ti->scsirate);
699                         memset(&neg, 0, sizeof (neg));
700                         neg.protocol = PROTO_SCSI;
701                         neg.protocol_version = SCSI_REV_2;
702                         neg.transport = XPORT_SPI;
703                         neg.transport_version = 2;
704                         spi->sync_period = ti->goal.period = ti->current.period;
705                         spi->sync_offset = ti->goal.offset = ti->current.offset;
706                         spi->valid = CTS_SPI_VALID_SYNC_RATE
707                                   | CTS_SPI_VALID_SYNC_OFFSET;
708                         ccb_h = &scb->ccb->ccb_h;
709                         xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1);
710                         xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg);
711                         break;
712                 case MSG_EXT_WDTR:
713                 default:
714                         aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
715                         break;
716                 }
717                 break;
718         case MSG_DISCONNECT:
719                 scb = aic->nexus;
720                 ccb_h = &scb->ccb->ccb_h;
721                 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
722                 scb->flags |= SCB_DISCONNECTED;
723                 aic->flags |= AIC_BUSFREE_OK;
724                 aic->nexus = NULL;
725                 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE, ("disconnected\n"));
726                 break;
727         case MSG_MESSAGE_REJECT:
728                 switch (aic->msg_outq & -aic->msg_outq) {
729                 case AIC_MSG_TAG_Q:
730                         scb = aic->nexus;
731                         ti = &aic->tinfo[scb->target];
732                         ti->flags &= ~TINFO_TAG_ENB;
733                         ti->lubusy |= 1 << scb->lun;
734                         break;
735                 case AIC_MSG_SDTR:
736                         scb = aic->nexus;
737                         ti = &aic->tinfo[scb->target];
738                         ti->current.period = ti->goal.period = 0;
739                         ti->current.offset = ti->goal.offset = 0;
740                         ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO);
741                         ti->scsirate = 0;
742                         aic_outb(aic, SCSIRATE, ti->scsirate);
743                         memset(&neg, 0, sizeof (neg));
744                         neg.protocol = PROTO_SCSI;
745                         neg.protocol_version = SCSI_REV_2;
746                         neg.transport = XPORT_SPI;
747                         neg.transport_version = 2;
748                         spi->sync_period = ti->current.period;
749                         spi->sync_offset = ti->current.offset;
750                         spi->valid = CTS_SPI_VALID_SYNC_RATE
751                                   | CTS_SPI_VALID_SYNC_OFFSET;
752                         ccb_h = &scb->ccb->ccb_h;
753                         xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1);
754                         xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg);
755                         break;
756                 default:
757                         break;
758                 }
759                 break;
760         case MSG_SAVEDATAPOINTER:
761                 break;  
762         case MSG_RESTOREPOINTERS:
763                 break;
764         case MSG_NOOP:
765                 break;
766         default:
767                 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
768                 break;
769         }
770 }
771
772 /*
773  * Send messages.
774  */
775 static void
776 aic_msgout(struct aic_softc *aic)
777 {
778         struct aic_scb *scb;
779         union ccb *ccb;
780         struct aic_tinfo *ti;
781         int msgidx = 0;
782
783         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_msgout\n"));
784
785         aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
786         aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
787
788         /*
789          * If the previous phase is also the message out phase,
790          * we need to retransmit all the messages, probably
791          * because the target has detected a parity error during
792          * the past transmission.
793          */
794         if (aic->prev_phase == PH_MSGOUT)
795                 aic->msg_outq = aic->msg_sent;
796
797         do {
798                 int q = aic->msg_outq;
799                 if (msgidx > 0 && msgidx == aic->msg_len) {
800                         /* complete message sent, start the next one */
801                         q &= -q;
802                         aic->msg_sent |= q;
803                         aic->msg_outq ^= q;
804                         q = aic->msg_outq;
805                         msgidx = 0;
806                 }
807                 if (msgidx == 0) {
808                         /* setup the message */
809                         switch (q & -q) {
810                         case AIC_MSG_IDENTIFY:
811                                 scb = aic->nexus;
812                                 ccb = scb->ccb;
813                                 ti = &aic->tinfo[scb->target];
814                                 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun,
815                                     (ti->flags & TINFO_DISC_ENB) &&
816                                     !(ccb->ccb_h.flags & CAM_DIS_DISCONNECT));
817                                 aic->msg_len = 1;
818                                 break;
819                         case AIC_MSG_TAG_Q:
820                                 scb = aic->nexus;
821                                 ccb = scb->ccb;
822                                 aic->msg_buf[0] = ccb->csio.tag_action;
823                                 aic->msg_buf[1] = scb->tag;
824                                 aic->msg_len = 2;
825                                 break;
826                         case AIC_MSG_SDTR:
827                                 scb = aic->nexus;
828                                 ti = &aic->tinfo[scb->target];
829                                 aic->msg_buf[0] = MSG_EXTENDED;
830                                 aic->msg_buf[1] = MSG_EXT_SDTR_LEN;
831                                 aic->msg_buf[2] = MSG_EXT_SDTR;
832                                 aic->msg_buf[3] = ti->goal.period;
833                                 aic->msg_buf[4] = ti->goal.offset;
834                                 aic->msg_len = MSG_EXT_SDTR_LEN + 2;
835                                 ti->flags |= TINFO_SDTR_SENT;
836                                 break;
837                         case AIC_MSG_MSGBUF:
838                                 /* a single message already in the buffer */
839                                 if (aic->msg_buf[0] == MSG_BUS_DEV_RESET ||
840                                     aic->msg_buf[0] == MSG_ABORT ||
841                                     aic->msg_buf[0] == MSG_ABORT_TAG)
842                                         aic->flags |= AIC_BUSFREE_OK;
843                                 break;
844                         }
845                 }
846                 /*
847                  * If this is the last message byte of all messages,
848                  * clear ATNO to signal transmission complete.
849                  */
850                 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1)
851                         aic_outb(aic, CLRSINT1, CLRATNO);
852                 /* transmit the message byte */
853                 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]);
854         } while (aic_spiordy(aic));
855
856         aic_outb(aic, SXFRCTL0, CHEN);
857         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
858 }
859
860 /*
861  * Read data bytes.
862  */
863 static void
864 aic_datain(struct aic_softc *aic)
865 {
866         struct aic_scb *scb = aic->nexus;
867         u_int8_t dmastat, dmacntrl0;
868         int n;
869
870         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_datain\n"));
871
872         aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
873         aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
874
875         dmacntrl0 = ENDMA;
876         if (aic->flags & AIC_DWIO_ENABLE)
877                 dmacntrl0 |= DWORDPIO;
878         aic_outb(aic, DMACNTRL0, dmacntrl0);
879
880         while (scb->data_len > 0) {
881                 for (;;) {
882                         /* wait for the fifo to fill up or a phase change */
883                         dmastat = aic_inb(aic, DMASTAT);
884                         if (dmastat & (INTSTAT|DFIFOFULL))
885                                 break;
886                 }
887                 if (dmastat & DFIFOFULL) {
888                         n = FIFOSIZE;
889                 } else {
890                         /*
891                          * No more data, wait for the remaining bytes in
892                          * the scsi fifo to be transfer to the host fifo.
893                          */
894                         while (!(aic_inb(aic, SSTAT2) & SEMPTY))
895                                 ;
896                         n = aic_inb(aic, FIFOSTAT);
897                 }
898                 n = imin(scb->data_len, n);
899                 if (aic->flags & AIC_DWIO_ENABLE) {
900                         if (n >= 12) {
901                                 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2);
902                                 scb->data_ptr += n & ~3;
903                                 scb->data_len -= n & ~3;
904                                 n &= 3;
905                         }
906                 } else {
907                         if (n >= 8) {
908                                 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1);
909                                 scb->data_ptr += n & ~1;
910                                 scb->data_len -= n & ~1;
911                                 n &= 1;
912                         }
913                 }
914                 if (n) {
915                         aic_outb(aic, DMACNTRL0, ENDMA|B8MODE);
916                         aic_insb(aic, DMADATA, scb->data_ptr, n);
917                         scb->data_ptr += n;
918                         scb->data_len -= n;
919                         aic_outb(aic, DMACNTRL0, dmacntrl0);
920                 }
921
922                 if (dmastat & INTSTAT)
923                         break;
924         }
925
926         aic_outb(aic, SXFRCTL0, CHEN);
927         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
928 }
929
930 /*
931  * Send data bytes.
932  */
933 static void
934 aic_dataout(struct aic_softc *aic)
935 {
936         struct aic_scb *scb = aic->nexus;
937         u_int8_t dmastat, dmacntrl0, sstat2;
938         int n;
939
940         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n"));
941
942         aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
943         aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
944
945         dmacntrl0 = ENDMA|WRITE;
946         if (aic->flags & AIC_DWIO_ENABLE)
947                 dmacntrl0 |= DWORDPIO;
948         aic_outb(aic, DMACNTRL0, dmacntrl0);
949
950         while (scb->data_len > 0) {
951                 for (;;) {
952                         /* wait for the fifo to clear up or a phase change */
953                         dmastat = aic_inb(aic, DMASTAT);
954                         if (dmastat & (INTSTAT|DFIFOEMP))
955                                 break;
956                 }
957                 if (dmastat & INTSTAT)
958                         break;
959                 n = imin(scb->data_len, FIFOSIZE);
960                 if (aic->flags & AIC_DWIO_ENABLE) {
961                         if (n >= 12) {
962                                 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2);
963                                 scb->data_ptr += n & ~3;
964                                 scb->data_len -= n & ~3;
965                                 n &= 3;
966                         }
967                 } else {
968                         if (n >= 8) {
969                                 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1);
970                                 scb->data_ptr += n & ~1;
971                                 scb->data_len -= n & ~1;
972                                 n &= 1;
973                         }
974                 }
975                 if (n) {
976                         aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE);
977                         aic_outsb(aic, DMADATA, scb->data_ptr, n);
978                         scb->data_ptr += n;
979                         scb->data_len -= n;
980                         aic_outb(aic, DMACNTRL0, dmacntrl0);
981                 }
982         }
983
984         for (;;) {
985                 /* wait until all bytes in the fifos are transmitted */
986                 dmastat = aic_inb(aic, DMASTAT);
987                 sstat2 = aic_inb(aic, SSTAT2);
988                 if ((dmastat & DFIFOEMP) && (sstat2 & SEMPTY))
989                         break;
990                 if (dmastat & INTSTAT) {
991                         /* adjust for untransmitted bytes */
992                         n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf);
993                         scb->data_ptr -= n;
994                         scb->data_len += n;
995                         /* clear the fifo */
996                         aic_outb(aic, SXFRCTL0, CHEN|CLRCH);
997                         aic_outb(aic, DMACNTRL0, RSTFIFO);
998                         break;
999                 }
1000         }
1001
1002         aic_outb(aic, SXFRCTL0, CHEN);
1003         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1004 }
1005
1006 /*
1007  * Send the scsi command.
1008  */
1009 static void
1010 aic_cmd(struct aic_softc *aic)
1011 {
1012         struct aic_scb *scb = aic->nexus;
1013         struct scsi_request_sense sense_cmd;
1014
1015         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_cmd\n"));
1016
1017         if (scb->flags & SCB_SENSE) {
1018                 /* autosense request */
1019                 sense_cmd.opcode = REQUEST_SENSE;
1020                 sense_cmd.byte2 = scb->lun << 5;
1021                 sense_cmd.length = scb->ccb->csio.sense_len;
1022                 sense_cmd.control = 0;
1023                 sense_cmd.unused[0] = 0;
1024                 sense_cmd.unused[1] = 0;
1025                 scb->cmd_ptr = (u_int8_t *)&sense_cmd;
1026                 scb->cmd_len = sizeof(sense_cmd);
1027                 scb->data_ptr = (u_int8_t *)&scb->ccb->csio.sense_data;
1028                 scb->data_len = scb->ccb->csio.sense_len;
1029         }
1030
1031         aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
1032         aic_outb(aic, DMACNTRL0, ENDMA|WRITE);
1033         aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
1034         aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1);
1035         while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 &&
1036             (aic_inb(aic, DMASTAT) & INTSTAT) == 0)
1037                 ;
1038         aic_outb(aic, SXFRCTL0, CHEN);
1039         aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1040 }
1041
1042 /*
1043  * Finish off a command. The caller is responsible to remove the ccb
1044  * from any queue.
1045  */
1046 static void
1047 aic_done(struct aic_softc *aic, struct aic_scb *scb)
1048 {
1049         union ccb *ccb = scb->ccb;
1050
1051         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE,
1052                   ("aic_done - ccb %p status %x resid %d\n",
1053                    ccb, ccb->ccb_h.status, ccb->csio.resid));
1054
1055         callout_stop(&ccb->ccb_h.timeout_ch);
1056
1057         if ((scb->flags & SCB_DEVICE_RESET) != 0 &&
1058             ccb->ccb_h.func_code != XPT_RESET_DEV) {
1059                 struct cam_path *path;
1060                 struct ccb_hdr *ccb_h;
1061                 cam_status error;
1062
1063                 error = xpt_create_path(&path, /*periph*/NULL,
1064                                         cam_sim_path(aic->sim),
1065                                         scb->target,
1066                                         CAM_LUN_WILDCARD);
1067
1068                 if (error == CAM_REQ_CMP) {
1069                         xpt_async(AC_SENT_BDR, path, NULL);
1070                         xpt_free_path(path);
1071                 }
1072
1073                 ccb_h = TAILQ_FIRST(&aic->pending_ccbs);
1074                 while (ccb_h != NULL) {
1075                         struct aic_scb *pending_scb;
1076
1077                         pending_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
1078                         if (ccb_h->target_id == scb->target) {
1079                                 ccb_h->status |= CAM_BDR_SENT;
1080                                 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1081                                 TAILQ_REMOVE(&aic->pending_ccbs,
1082                                     &pending_scb->ccb->ccb_h, sim_links.tqe);
1083                                 aic_done(aic, pending_scb);
1084                         } else {
1085                                 callout_reset(&ccb_h->timeout_ch,
1086                                     (ccb_h->timeout * hz) / 1000,
1087                                     aic_timeout, pending_scb);
1088                                 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1089                         }
1090                 }
1091
1092                 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs);
1093                 while (ccb_h != NULL) {
1094                         struct aic_scb *nexus_scb;
1095
1096                         nexus_scb = (struct aic_scb *)ccb_h->ccb_scb_ptr;
1097                         if (ccb_h->target_id == scb->target) {
1098                                 ccb_h->status |= CAM_BDR_SENT;
1099                                 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1100                                 TAILQ_REMOVE(&aic->nexus_ccbs,
1101                                     &nexus_scb->ccb->ccb_h, sim_links.tqe);
1102                                 aic_done(aic, nexus_scb);
1103                         } else {
1104                                 callout_reset(&ccb_h->timeout_ch,
1105                                     (ccb_h->timeout * hz) / 1000,
1106                                     aic_timeout, nexus_scb);
1107                                 ccb_h = TAILQ_NEXT(ccb_h, sim_links.tqe);
1108                         }
1109                 }
1110         }
1111
1112         if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED)
1113                 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun);
1114         
1115         if (aic->nexus == scb) {
1116                 aic->nexus = NULL;
1117         }
1118         aic_free_scb(aic, scb);
1119         xpt_done(ccb);
1120 }
1121
1122 static void
1123 aic_poll(struct cam_sim *sim)
1124 {
1125         aic_intr(cam_sim_softc(sim));
1126 }
1127
1128 static void
1129 aic_timeout(void *arg)
1130 {
1131         struct aic_scb *scb = (struct aic_scb *)arg;
1132         union ccb *ccb = scb->ccb;
1133         struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
1134
1135         xpt_print_path(ccb->ccb_h.path);
1136         kprintf("ccb %p - timed out", ccb);
1137         if (aic->nexus && aic->nexus != scb)
1138                 kprintf(", nexus %p", aic->nexus->ccb);
1139         kprintf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state);
1140
1141         crit_enter();
1142
1143         if ((scb->flags & SCB_ACTIVE) == 0) {
1144                 crit_exit();
1145                 xpt_print_path(ccb->ccb_h.path);
1146                 kprintf("ccb %p - timed out already completed\n", ccb);
1147                 return;
1148         }
1149
1150         if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
1151                 struct ccb_hdr *ccb_h = &scb->ccb->ccb_h;
1152
1153                 if ((ccb_h->status & CAM_RELEASE_SIMQ) == 0) {
1154                         xpt_freeze_simq(aic->sim, /*count*/1);
1155                         ccb_h->status |= CAM_RELEASE_SIMQ;
1156                 }
1157
1158                 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe)
1159                         callout_stop(&ccb_h->timeout_ch);
1160
1161                 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe)
1162                         callout_stop(&ccb_h->timeout_ch);
1163
1164                 scb->flags |= SCB_DEVICE_RESET;
1165                 callout_reset(&ccb->ccb_h.timeout_ch, 5 * hz, aic_timeout, scb);
1166                 aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
1167         } else {
1168                 if (aic->nexus == scb) {
1169                         ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1170                         aic_done(aic, scb);
1171                 }
1172                 aic_reset(aic, /*initiate_reset*/TRUE);
1173         }
1174
1175         crit_exit();
1176 }
1177
1178 void
1179 aic_intr(void *arg)
1180 {
1181         struct aic_softc *aic = (struct aic_softc *)arg;
1182         u_int8_t sstat0, sstat1;
1183         union ccb *ccb;
1184         struct aic_scb *scb;
1185
1186         if (!(aic_inb(aic, DMASTAT) & INTSTAT))
1187                 return;
1188
1189         aic_outb(aic, DMACNTRL0, 0);
1190
1191         sstat0 = aic_inb(aic, SSTAT0);
1192         sstat1 = aic_inb(aic, SSTAT1);
1193
1194         if ((sstat1 & SCSIRSTI) != 0) {
1195                 /* a device-initiated bus reset */
1196                 aic_outb(aic, CLRSINT1, CLRSCSIRSTI);
1197                 aic_reset(aic, /*initiate_reset*/FALSE);
1198                 return;
1199         }
1200
1201         if ((sstat1 & SCSIPERR) != 0) {
1202                 aic_outb(aic, CLRSINT1, CLRSCSIPERR);
1203                 aic_sched_msgout(aic, MSG_PARITY_ERROR);
1204                 aic_outb(aic, DMACNTRL0, INTEN);
1205                 return;
1206         }
1207
1208         if (aic_inb(aic, SSTAT4)) {
1209                 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR);
1210                 aic_reset(aic, /*initiate_reset*/TRUE);
1211                 return;
1212         }
1213
1214         if (aic->state <= AIC_SELECTING) {
1215                 if ((sstat0 & SELDI) != 0) {
1216                         aic_reselected(aic);
1217                         aic_outb(aic, DMACNTRL0, INTEN);
1218                         return;
1219                 }
1220
1221                 if ((sstat0 & SELDO) != 0) {
1222                         aic_selected(aic);
1223                         aic_outb(aic, DMACNTRL0, INTEN);
1224                         return;
1225                 }
1226
1227                 if ((sstat1 & SELTO) != 0) {
1228                         scb = aic->nexus;
1229                         ccb = scb->ccb;
1230                         ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1231                         aic_done(aic, scb);
1232                         while ((sstat1 & BUSFREE) == 0)
1233                                 sstat1 = aic_inb(aic, SSTAT1);
1234                         aic->flags |= AIC_BUSFREE_OK;
1235                 }
1236         }
1237
1238         if ((sstat1 & BUSFREE) != 0) {
1239                 aic_outb(aic, SCSISEQ, 0);
1240                 aic_outb(aic, CLRSINT0, sstat0);
1241                 aic_outb(aic, CLRSINT1, sstat1);
1242                 if ((scb = aic->nexus)) {
1243                         if ((aic->flags & AIC_BUSFREE_OK) == 0) {
1244                                 ccb = scb->ccb;
1245                                 ccb->ccb_h.status = CAM_UNEXP_BUSFREE;
1246                                 aic_done(aic, scb);
1247                         } else if (scb->flags & SCB_DEVICE_RESET) {
1248                                 ccb = scb->ccb;
1249                                 if (ccb->ccb_h.func_code == XPT_RESET_DEV) {
1250                                         xpt_async(AC_SENT_BDR,
1251                                             ccb->ccb_h.path, NULL);
1252                                         ccb->ccb_h.status |= CAM_REQ_CMP;
1253                                 } else
1254                                         ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1255                                 aic_done(aic, scb);
1256                         } else if (scb->flags & SCB_SENSE) {
1257                                 /* autosense request */
1258                                 aic->flags &= ~AIC_BUSFREE_OK;
1259                                 aic->tinfo[scb->target].lubusy &=
1260                                     ~(1 << scb->lun);
1261                                 aic_select(aic);
1262                                 aic_outb(aic, DMACNTRL0, INTEN);
1263                                 return;
1264                         }
1265                 }
1266                 aic->flags &= ~AIC_BUSFREE_OK;
1267                 aic->state = AIC_IDLE;
1268                 aic_start(aic);
1269                 aic_outb(aic, DMACNTRL0, INTEN);
1270                 return;
1271         }
1272
1273         if ((sstat1 & REQINIT) != 0) {
1274                 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK;
1275                 aic_outb(aic, SCSISIGO, phase);
1276                 aic_outb(aic, CLRSINT1, CLRPHASECHG);
1277
1278                 switch (phase) {
1279                 case PH_MSGOUT:
1280                         aic_msgout(aic);
1281                         break;
1282                 case PH_MSGIN:
1283                         aic_msgin(aic);
1284                         break;
1285                 case PH_STAT:
1286                         scb = aic->nexus;
1287                         ccb = scb->ccb;
1288                         aic_outb(aic, DMACNTRL0, 0);
1289                         aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
1290                         scb->status = aic_inb(aic, SCSIDAT);
1291                         aic_outb(aic, SXFRCTL0, CHEN);
1292                         break;
1293                 case PH_CMD:
1294                         aic_cmd(aic);
1295                         break;
1296                 case PH_DATAIN:
1297                         aic_datain(aic);
1298                         break;
1299                 case PH_DATAOUT:
1300                         aic_dataout(aic);
1301                         break;
1302                 }
1303                 aic->prev_phase = phase;
1304                 aic_outb(aic, DMACNTRL0, INTEN);
1305                 return;
1306         }
1307
1308         kprintf("aic_intr: unexpected intr sstat0 %x sstat1 %x\n",
1309                 sstat0, sstat1);
1310         aic_outb(aic, DMACNTRL0, INTEN);
1311 }
1312
1313 /*
1314  * Reset ourselves.
1315  */
1316 static void
1317 aic_chip_reset(struct aic_softc *aic)
1318 {
1319         /*
1320          * Doc. recommends to clear these two registers before
1321          * operations commence
1322          */
1323         aic_outb(aic, SCSITEST, 0);
1324         aic_outb(aic, TEST, 0);
1325
1326         /* Reset SCSI-FIFO and abort any transfers */
1327         aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT);
1328
1329         /* Reset HOST-FIFO */
1330         aic_outb(aic, DMACNTRL0, RSTFIFO);
1331         aic_outb(aic, DMACNTRL1, 0);
1332
1333         /* Disable all selection features */
1334         aic_outb(aic, SCSISEQ, 0);
1335         aic_outb(aic, SXFRCTL1, 0);
1336
1337         /* Disable interrupts */
1338         aic_outb(aic, SIMODE0, 0);
1339         aic_outb(aic, SIMODE1, 0);
1340
1341         /* Clear interrupts */
1342         aic_outb(aic, CLRSINT0, 0x7f);
1343         aic_outb(aic, CLRSINT1, 0xef);
1344
1345         /* Disable synchronous transfers */
1346         aic_outb(aic, SCSIRATE, 0);
1347
1348         /* Haven't seen ant errors (yet) */
1349         aic_outb(aic, CLRSERR, 0x07);
1350
1351         /* Set our SCSI-ID */
1352         aic_outb(aic, SCSIID, aic->initiator << OID_S);
1353         aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM);
1354 }
1355
1356 /*
1357  * Reset the SCSI bus
1358  */
1359 static void
1360 aic_scsi_reset(struct aic_softc *aic)
1361 {
1362         aic_outb(aic, SCSISEQ, SCSIRSTO);
1363         DELAY(500);
1364         aic_outb(aic, SCSISEQ, 0);
1365         DELAY(50);
1366 }
1367
1368 /*
1369  * Reset. Abort all pending commands.
1370  */
1371 static void
1372 aic_reset(struct aic_softc *aic, int initiate_reset)
1373 {
1374         struct ccb_hdr *ccb_h;
1375
1376         CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_reset\n"));
1377
1378         if (initiate_reset)
1379                 aic_scsi_reset(aic);
1380         aic_chip_reset(aic);
1381
1382         xpt_async(AC_BUS_RESET, aic->path, NULL);
1383
1384         while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) {
1385                 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
1386                 ccb_h->status |= CAM_SCSI_BUS_RESET;
1387                 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1388         }
1389
1390         while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) {
1391                 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
1392                 ccb_h->status |= CAM_SCSI_BUS_RESET;
1393                 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1394         }
1395
1396         if (aic->nexus) {
1397                 ccb_h = &aic->nexus->ccb->ccb_h;
1398                 ccb_h->status |= CAM_SCSI_BUS_RESET;
1399                 aic_done(aic, aic->nexus);
1400         }
1401
1402         aic->state = AIC_IDLE;
1403         aic_outb(aic, DMACNTRL0, INTEN);
1404 }
1405
1406 static char *aic_chip_names[] = {
1407         "AIC6260", "AIC6360", "AIC6370", "GM82C700",
1408 };
1409
1410 static struct {
1411         int type;
1412         char *idstring;
1413 } aic_chip_ids[] = {
1414         { AIC6360, IDSTRING_AIC6360 },
1415         { AIC6370, IDSTRING_AIC6370 },
1416         { GM82C700, IDSTRING_GM82C700 },
1417 };
1418
1419 static void
1420 aic_init(struct aic_softc *aic)
1421 {
1422         struct aic_scb *scb;
1423         struct aic_tinfo *ti;
1424         u_int8_t porta, portb;
1425         char chip_id[33];
1426         int i;
1427
1428         TAILQ_INIT(&aic->pending_ccbs);
1429         TAILQ_INIT(&aic->nexus_ccbs);
1430         aic->nexus = NULL;
1431         aic->state = AIC_IDLE;
1432         aic->prev_phase = -1;
1433         aic->flags = 0;
1434
1435         aic_chip_reset(aic);
1436         aic_scsi_reset(aic);
1437
1438         /* determine the chip type from its ID string */
1439         aic->chip_type = AIC6260;
1440         aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1);
1441         chip_id[sizeof(chip_id) - 1] = '\0';
1442         for (i = 0; i < sizeof(aic_chip_ids) / sizeof(aic_chip_ids[0]); i++) {
1443                 if (!strcmp(chip_id, aic_chip_ids[i].idstring)) {
1444                         aic->chip_type = aic_chip_ids[i].type;
1445                         break;
1446                 }
1447         }
1448
1449         porta = aic_inb(aic, PORTA);
1450         portb = aic_inb(aic, PORTB);
1451
1452         aic->initiator = PORTA_ID(porta);
1453         if (PORTA_PARITY(porta))
1454                 aic->flags |= AIC_PARITY_ENABLE;
1455         if (PORTB_DISC(portb))
1456                 aic->flags |= AIC_DISC_ENABLE;
1457         if (PORTB_DMA(portb))
1458                 aic->flags |= AIC_DMA_ENABLE;
1459
1460         /*
1461          * We can do fast SCSI (10MHz clock rate) if bit 4 of portb
1462          * is set and we've got a 6360.  The 6260 can only do standard
1463          * 5MHz SCSI.
1464          */
1465         if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) {
1466                 if (PORTB_FSYNC(portb))
1467                         aic->flags |= AIC_FAST_ENABLE;
1468                 aic->flags |= AIC_DWIO_ENABLE;
1469         }
1470
1471         if (aic->flags & AIC_FAST_ENABLE)
1472                 aic->max_period = AIC_FAST_SYNC_PERIOD;
1473         else
1474                 aic->max_period = AIC_SYNC_PERIOD;
1475         aic->min_period = AIC_MIN_SYNC_PERIOD;
1476
1477         free_scbs = NULL;
1478         for (i = 255; i >= 0; i--) {
1479                 scb = &aic->scbs[i];
1480                 scb->tag = i;
1481                 aic_free_scb(aic, scb);
1482         }
1483
1484         for (i = 0; i < 8; i++) {
1485                 if (i == aic->initiator)
1486                         continue;
1487                 ti = &aic->tinfo[i];
1488                 bzero(ti, sizeof(*ti));
1489                 ti->flags = TINFO_TAG_ENB;
1490                 if (aic->flags & AIC_DISC_ENABLE)
1491                         ti->flags |= TINFO_DISC_ENB;
1492                 ti->user.period = aic->max_period;
1493                 ti->user.offset = AIC_SYNC_OFFSET;
1494                 ti->scsirate = 0;
1495         }
1496
1497         aic_outb(aic, DMACNTRL0, INTEN);
1498 }
1499
1500 int
1501 aic_probe(struct aic_softc *aic)
1502 {
1503         int i;
1504
1505         /* Remove aic6360 from possible powerdown mode */
1506         aic_outb(aic, DMACNTRL0, 0);
1507
1508 #define STSIZE  16
1509         aic_outb(aic, DMACNTRL1, 0);    /* Reset stack pointer */
1510         for (i = 0; i < STSIZE; i++)
1511                 aic_outb(aic, STACK, i);
1512
1513         /* See if we can pull out the same sequence */
1514         aic_outb(aic, DMACNTRL1, 0);
1515         for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++)
1516                 ;
1517         if (i != STSIZE)
1518                 return (ENXIO);
1519 #undef  STSIZE
1520         return (0);
1521 }
1522
1523 int
1524 aic_attach(struct aic_softc *aic)
1525 {
1526         /*
1527          * Construct our SIM entry
1528          */
1529         aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic,
1530                                  aic->unit, &sim_mplock, 2, 256, NULL);
1531         if (aic->sim == NULL)
1532                 return (ENOMEM);
1533
1534         if (xpt_bus_register(aic->sim, 0) != CAM_SUCCESS) {
1535                 cam_sim_free(aic->sim);
1536                 return (ENXIO);
1537         }
1538
1539         if (xpt_create_path(&aic->path, /*periph*/NULL,
1540                             cam_sim_path(aic->sim), CAM_TARGET_WILDCARD,
1541                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1542                 xpt_bus_deregister(cam_sim_path(aic->sim));
1543                 cam_sim_free(aic->sim);
1544                 return (ENXIO);
1545         }
1546
1547         aic_init(aic);
1548
1549         kprintf("aic%d: %s", aic->unit, aic_chip_names[aic->chip_type]);
1550         if (aic->flags & AIC_DMA_ENABLE)
1551                 kprintf(", dma");
1552         if (aic->flags & AIC_DISC_ENABLE)
1553                 kprintf(", disconnection");
1554         if (aic->flags & AIC_PARITY_ENABLE)
1555                 kprintf(", parity check");
1556         if (aic->flags & AIC_FAST_ENABLE)
1557                 kprintf(", fast SCSI");
1558         kprintf("\n");
1559         return (0);
1560 }
1561
1562 int
1563 aic_detach(struct aic_softc *aic)
1564 {
1565         xpt_async(AC_LOST_DEVICE, aic->path, NULL);
1566         xpt_free_path(aic->path);
1567         xpt_bus_deregister(cam_sim_path(aic->sim));
1568         cam_sim_free(aic->sim);
1569         return (0);
1570 }