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