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