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