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