Lines Matching defs:aic

28 __FBSDID("$FreeBSD: releng/11.0/sys/dev/aic/aic.c 298431 2016-04-21 19:40:10Z pfg $");
50 #include <dev/aic/aic6360reg.h>
51 #include <dev/aic/aicvar.h>
56 static void aic_intr_locked(struct aic_softc *aic);
57 static void aic_start(struct aic_softc *aic);
58 static void aic_select(struct aic_softc *aic);
59 static void aic_selected(struct aic_softc *aic);
60 static void aic_reselected(struct aic_softc *aic);
61 static void aic_reconnect(struct aic_softc *aic, int tag);
62 static void aic_cmd(struct aic_softc *aic);
63 static void aic_msgin(struct aic_softc *aic);
64 static void aic_handle_msgin(struct aic_softc *aic);
65 static void aic_msgout(struct aic_softc *aic);
66 static void aic_datain(struct aic_softc *aic);
67 static void aic_dataout(struct aic_softc *aic);
68 static void aic_done(struct aic_softc *aic, struct aic_scb *scb);
71 static void aic_scsi_reset(struct aic_softc *aic);
72 static void aic_chip_reset(struct aic_softc *aic);
73 static void aic_reset(struct aic_softc *aic, int initiate_reset);
78 aic_get_scb(struct aic_softc *aic)
83 mtx_assert(&aic->lock, MA_OWNED);
84 if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL)
85 SLIST_REMOVE_HEAD(&aic->free_scbs, link);
90 aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
94 mtx_assert(&aic->lock, MA_OWNED);
95 if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
98 aic->flags &= ~AIC_RESOURCE_SHORTAGE;
101 SLIST_INSERT_HEAD(&aic->free_scbs, scb, link);
107 struct aic_softc *aic;
111 aic = (struct aic_softc *)cam_sim_softc(sim);
112 mtx_assert(&aic->lock, MA_OWNED);
120 if ((scb = aic_get_scb(aic)) == NULL) {
121 aic->flags |= AIC_RESOURCE_SHORTAGE;
122 xpt_freeze_simq(aic->sim, /*count*/1);
130 ccb->ccb_h.ccb_aic_ptr = aic;
140 aic_free_scb(aic, scb);
152 aic_free_scb(aic, scb);
172 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
179 (aic->flags & AIC_DISC_ENABLE) != 0) {
196 if (ti->goal.period > aic->min_period) {
199 } else if (ti->goal.period < aic->max_period)
200 ti->goal.period = aic->max_period;
222 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
266 aic_reset(aic, /*initiate_reset*/TRUE);
281 cpi->initiator_id = aic->initiator;
308 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
311 mtx_assert(&aic->lock, MA_OWNED);
313 aic_free_scb(aic, scb);
320 TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
325 aic_start(aic);
332 aic_start(struct aic_softc *aic)
337 if (aic->state != AIC_IDLE)
340 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
341 ti = &aic->tinfo[ccb_h->target_id];
343 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
344 aic->nexus = (struct aic_scb *)ccb_h->ccb_scb_ptr;
345 aic_select(aic);
352 aic_outb(aic, SIMODE0, ENSELDI);
353 aic_outb(aic, SIMODE1, ENSCSIRST);
354 aic_outb(aic, SCSISEQ, ENRESELI);
361 aic_select(struct aic_softc *aic)
363 struct aic_scb *scb = aic->nexus;
368 aic->state = AIC_SELECTING;
370 aic_outb(aic, DMACNTRL1, 0);
371 aic_outb(aic, SCSIID, aic->initiator << OID_S | scb->target);
372 aic_outb(aic, SXFRCTL1, STIMO_256ms | ENSTIMER |
373 (aic->flags & AIC_PARITY_ENABLE ? ENSPCHK : 0));
375 aic_outb(aic, SIMODE0, ENSELDI|ENSELDO);
376 aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO);
377 aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO);
385 aic_selected(struct aic_softc *aic)
387 struct aic_scb *scb = aic->nexus;
389 struct aic_tinfo *ti = &aic->tinfo[scb->target];
394 aic->state = AIC_HASNEXUS;
397 aic->msg_buf[0] = MSG_BUS_DEV_RESET;
398 aic->msg_len = 1;
399 aic->msg_outq = AIC_MSG_MSGBUF;
401 aic->msg_outq = AIC_MSG_IDENTIFY;
404 aic->msg_outq |= AIC_MSG_TAG_Q;
408 aic->msg_outq |= AIC_MSG_SDTR;
411 aic_outb(aic, CLRSINT0, CLRSELDO);
412 aic_outb(aic, CLRSINT1, CLRBUSFREE);
413 aic_outb(aic, SCSISEQ, ENAUTOATNP);
414 aic_outb(aic, SIMODE0, 0);
415 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
416 aic_outb(aic, SCSIRATE, ti->scsirate);
424 aic_reselected(struct aic_softc *aic)
434 if (aic->nexus) {
435 TAILQ_INSERT_HEAD(&aic->pending_ccbs,
436 &aic->nexus->ccb->ccb_h, sim_links.tqe);
437 aic->nexus = NULL;
440 selid = aic_inb(aic, SELID) & ~(1 << aic->initiator);
444 aic_reset(aic, /*initiate_reset*/TRUE);
448 aic->state = AIC_RESELECTED;
449 aic->target = ffs(selid) - 1;
450 aic->lun = -1;
452 aic_outb(aic, CLRSINT0, CLRSELDI);
453 aic_outb(aic, CLRSINT1, CLRBUSFREE);
454 aic_outb(aic, SIMODE0, 0);
455 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
456 aic_outb(aic, SCSISEQ, ENAUTOATNP);
457 aic_outb(aic, SCSIRATE, aic->tinfo[aic->target].scsirate);
464 aic_sched_msgout(struct aic_softc *aic, u_int8_t msg)
467 aic->msg_buf[0] = msg;
468 aic->msg_len = 1;
470 aic->msg_outq |= AIC_MSG_MSGBUF;
471 aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO);
478 aic_spiordy(struct aic_softc *aic)
480 while (!(aic_inb(aic, DMASTAT) & INTSTAT) &&
481 !(aic_inb(aic, SSTAT0) & SPIORDY))
483 return !(aic_inb(aic, DMASTAT) & INTSTAT);
490 aic_reconnect(struct aic_softc *aic, int tag)
499 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
501 if (scb->target == aic->target && scb->lun == aic->lun &&
509 aic_sched_msgout(aic, MSG_ABORT);
511 aic_sched_msgout(aic, MSG_ABORT_TAG);
512 xpt_async(AC_UNSOL_RESEL, aic->path, NULL);
517 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
518 aic->nexus = scb;
520 aic->state = AIC_HASNEXUS;
527 aic_msgin(struct aic_softc *aic)
533 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
534 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
536 aic->flags &= ~AIC_DROP_MSGIN;
537 aic->msg_len = 0;
544 if (aic_inb(aic, SSTAT1) & SCSIPERR) {
545 aic_outb(aic, CLRSINT1, CLRSCSIPERR);
546 aic->flags |= AIC_DROP_MSGIN;
547 aic_sched_msgout(aic, MSG_PARITY_ERROR);
549 if ((aic->flags & AIC_DROP_MSGIN)) {
550 aic_inb(aic, SCSIDAT);
554 aic->msg_buf[aic->msg_len++] = aic_inb(aic, SCSIBUS);
555 if (aic->msg_buf[0] == MSG_EXTENDED) {
556 if (aic->msg_len < 2) {
557 (void) aic_inb(aic, SCSIDAT);
560 switch (aic->msg_buf[2]) {
571 if (aic->msg_buf[1] != msglen) {
572 aic->flags |= AIC_DROP_MSGIN;
573 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
576 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f)
584 if (aic->msg_len == msglen) {
585 aic_handle_msgin(aic);
586 aic->msg_len = 0;
589 (void) aic_inb(aic, SCSIDAT);
590 } while (aic_spiordy(aic));
592 aic_outb(aic, SXFRCTL0, CHEN);
593 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
600 aic_handle_msgin(struct aic_softc *aic)
608 if (aic->state == AIC_RESELECTED) {
609 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) {
610 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
613 aic->lun = aic->msg_buf[0] & MSG_IDENTIFY_LUNMASK;
614 if (aic->tinfo[aic->target].lubusy & (1 << aic->lun))
615 aic_reconnect(aic, -1);
617 aic->state = AIC_RECONNECTING;
621 if (aic->state == AIC_RECONNECTING) {
622 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) {
623 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
626 aic_reconnect(aic, aic->msg_buf[1]);
630 switch (aic->msg_buf[0]) {
633 scb = aic->nexus;
660 aic->flags |= AIC_BUSFREE_OK;
665 aic_done(aic, scb);
666 aic->flags |= AIC_BUSFREE_OK;
670 switch (aic->msg_buf[2]) {
672 scb = aic->nexus;
673 ti = &aic->tinfo[scb->target];
675 ti->current.period = aic->msg_buf[3];
676 ti->current.offset = aic->msg_buf[4];
678 ti->current.period = aic->msg_buf[3] =
679 max(ti->goal.period, aic->msg_buf[3]);
680 ti->current.offset = aic->msg_buf[4] =
681 min(ti->goal.offset, aic->msg_buf[4]);
686 aic_sched_msgout(aic, 0);
691 aic_outb(aic, SCSIRATE, ti->scsirate);
707 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
712 scb = aic->nexus;
714 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
716 aic->flags |= AIC_BUSFREE_OK;
717 aic->nexus = NULL;
721 switch (aic->msg_outq & -aic->msg_outq) {
723 scb = aic->nexus;
724 ti = &aic->tinfo[scb->target];
729 scb = aic->nexus;
730 ti = &aic->tinfo[scb->target];
735 aic_outb(aic, SCSIRATE, ti->scsirate);
760 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
769 aic_msgout(struct aic_softc *aic)
778 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
779 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
787 if (aic->prev_phase == PH_MSGOUT)
788 aic->msg_outq = aic->msg_sent;
791 int q = aic->msg_outq;
792 if (msgidx > 0 && msgidx == aic->msg_len) {
795 aic->msg_sent |= q;
796 aic->msg_outq ^= q;
797 q = aic->msg_outq;
804 scb = aic->nexus;
806 ti = &aic->tinfo[scb->target];
807 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun,
810 aic->msg_len = 1;
813 scb = aic->nexus;
815 aic->msg_buf[0] = ccb->csio.tag_action;
816 aic->msg_buf[1] = scb->tag;
817 aic->msg_len = 2;
820 scb = aic->nexus;
821 ti = &aic->tinfo[scb->target];
822 aic->msg_buf[0] = MSG_EXTENDED;
823 aic->msg_buf[1] = MSG_EXT_SDTR_LEN;
824 aic->msg_buf[2] = MSG_EXT_SDTR;
825 aic->msg_buf[3] = ti->goal.period;
826 aic->msg_buf[4] = ti->goal.offset;
827 aic->msg_len = MSG_EXT_SDTR_LEN + 2;
832 if (aic->msg_buf[0] == MSG_BUS_DEV_RESET ||
833 aic->msg_buf[0] == MSG_ABORT ||
834 aic->msg_buf[0] == MSG_ABORT_TAG)
835 aic->flags |= AIC_BUSFREE_OK;
843 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1)
844 aic_outb(aic, CLRSINT1, CLRATNO);
846 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]);
847 } while (aic_spiordy(aic));
849 aic_outb(aic, SXFRCTL0, CHEN);
850 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
857 aic_datain(struct aic_softc *aic)
859 struct aic_scb *scb = aic->nexus;
865 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
866 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
869 if (aic->flags & AIC_DWIO_ENABLE)
871 aic_outb(aic, DMACNTRL0, dmacntrl0);
876 dmastat = aic_inb(aic, DMASTAT);
887 while (!(aic_inb(aic, SSTAT2) & SEMPTY))
889 n = aic_inb(aic, FIFOSTAT);
892 if (aic->flags & AIC_DWIO_ENABLE) {
894 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2);
901 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1);
908 aic_outb(aic, DMACNTRL0, ENDMA|B8MODE);
909 aic_insb(aic, DMADATA, scb->data_ptr, n);
912 aic_outb(aic, DMACNTRL0, dmacntrl0);
919 aic_outb(aic, SXFRCTL0, CHEN);
920 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
927 aic_dataout(struct aic_softc *aic)
929 struct aic_scb *scb = aic->nexus;
935 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
936 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
939 if (aic->flags & AIC_DWIO_ENABLE)
941 aic_outb(aic, DMACNTRL0, dmacntrl0);
946 dmastat = aic_inb(aic, DMASTAT);
953 if (aic->flags & AIC_DWIO_ENABLE) {
955 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2);
962 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1);
969 aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE);
970 aic_outsb(aic, DMADATA, scb->data_ptr, n);
973 aic_outb(aic, DMACNTRL0, dmacntrl0);
979 dmastat = aic_inb(aic, DMASTAT);
980 sstat2 = aic_inb(aic, SSTAT2);
985 n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf);
989 aic_outb(aic, SXFRCTL0, CHEN|CLRCH);
990 aic_outb(aic, DMACNTRL0, RSTFIFO);
995 aic_outb(aic, SXFRCTL0, CHEN);
996 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1003 aic_cmd(struct aic_softc *aic)
1005 struct aic_scb *scb = aic->nexus;
1024 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
1025 aic_outb(aic, DMACNTRL0, ENDMA|WRITE);
1026 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
1027 aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1);
1028 while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 &&
1029 (aic_inb(aic, DMASTAT) & INTSTAT) == 0)
1031 aic_outb(aic, SXFRCTL0, CHEN);
1032 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1040 aic_done(struct aic_softc *aic, struct aic_scb *scb)
1057 cam_sim_path(aic->sim),
1066 ccb_h = TAILQ_FIRST(&aic->pending_ccbs);
1074 TAILQ_REMOVE(&aic->pending_ccbs,
1076 aic_done(aic, pending_scb);
1085 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs);
1093 TAILQ_REMOVE(&aic->nexus_ccbs,
1095 aic_done(aic, nexus_scb);
1105 if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED)
1106 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun);
1108 if (aic->nexus == scb) {
1109 aic->nexus = NULL;
1111 aic_free_scb(aic, scb);
1126 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
1128 mtx_assert(&aic->lock, MA_OWNED);
1131 if (aic->nexus && aic->nexus != scb)
1132 printf(", nexus %p", aic->nexus->ccb);
1133 printf(", phase 0x%x, state %d\n", aic_inb(aic, SCSISIGI), aic->state);
1141 if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
1146 xpt_freeze_simq(aic->sim, /*count*/1);
1150 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
1155 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
1162 aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
1164 if (aic->nexus == scb) {
1166 aic_done(aic, scb);
1168 aic_reset(aic, /*initiate_reset*/TRUE);
1175 struct aic_softc *aic = (struct aic_softc *)arg;
1177 mtx_lock(&aic->lock);
1178 aic_intr_locked(aic);
1179 mtx_unlock(&aic->lock);
1183 aic_intr_locked(struct aic_softc *aic)
1189 if (!(aic_inb(aic, DMASTAT) & INTSTAT))
1192 aic_outb(aic, DMACNTRL0, 0);
1194 sstat0 = aic_inb(aic, SSTAT0);
1195 sstat1 = aic_inb(aic, SSTAT1);
1199 aic_outb(aic, CLRSINT1, CLRSCSIRSTI);
1200 aic_reset(aic, /*initiate_reset*/FALSE);
1205 aic_outb(aic, CLRSINT1, CLRSCSIPERR);
1206 aic_sched_msgout(aic, MSG_PARITY_ERROR);
1207 aic_outb(aic, DMACNTRL0, INTEN);
1211 if (aic_inb(aic, SSTAT4)) {
1212 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR);
1213 aic_reset(aic, /*initiate_reset*/TRUE);
1217 if (aic->state <= AIC_SELECTING) {
1219 aic_reselected(aic);
1220 aic_outb(aic, DMACNTRL0, INTEN);
1225 aic_selected(aic);
1226 aic_outb(aic, DMACNTRL0, INTEN);
1231 scb = aic->nexus;
1234 aic_done(aic, scb);
1236 sstat1 = aic_inb(aic, SSTAT1);
1237 aic->flags |= AIC_BUSFREE_OK;
1242 aic_outb(aic, SCSISEQ, 0);
1243 aic_outb(aic, CLRSINT0, sstat0);
1244 aic_outb(aic, CLRSINT1, sstat1);
1245 if ((scb = aic->nexus)) {
1246 if ((aic->flags & AIC_BUSFREE_OK) == 0) {
1249 aic_done(aic, scb);
1258 aic_done(aic, scb);
1261 aic->flags &= ~AIC_BUSFREE_OK;
1262 aic->tinfo[scb->target].lubusy &=
1264 aic_select(aic);
1265 aic_outb(aic, DMACNTRL0, INTEN);
1269 aic->flags &= ~AIC_BUSFREE_OK;
1270 aic->state = AIC_IDLE;
1271 aic_start(aic);
1272 aic_outb(aic, DMACNTRL0, INTEN);
1277 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK;
1278 aic_outb(aic, SCSISIGO, phase);
1279 aic_outb(aic, CLRSINT1, CLRPHASECHG);
1283 aic_msgout(aic);
1286 aic_msgin(aic);
1289 scb = aic->nexus;
1291 aic_outb(aic, DMACNTRL0, 0);
1292 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
1293 scb->status = aic_inb(aic, SCSIDAT);
1294 aic_outb(aic, SXFRCTL0, CHEN);
1297 aic_cmd(aic);
1300 aic_datain(aic);
1303 aic_dataout(aic);
1306 aic->prev_phase = phase;
1307 aic_outb(aic, DMACNTRL0, INTEN);
1313 aic_outb(aic, DMACNTRL0, INTEN);
1320 aic_chip_reset(struct aic_softc *aic)
1326 aic_outb(aic, SCSITEST, 0);
1327 aic_outb(aic, TEST, 0);
1330 aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT);
1333 aic_outb(aic, DMACNTRL0, RSTFIFO);
1334 aic_outb(aic, DMACNTRL1, 0);
1337 aic_outb(aic, SCSISEQ, 0);
1338 aic_outb(aic, SXFRCTL1, 0);
1341 aic_outb(aic, SIMODE0, 0);
1342 aic_outb(aic, SIMODE1, 0);
1345 aic_outb(aic, CLRSINT0, 0x7f);
1346 aic_outb(aic, CLRSINT1, 0xef);
1349 aic_outb(aic, SCSIRATE, 0);
1352 aic_outb(aic, CLRSERR, 0x07);
1355 aic_outb(aic, SCSIID, aic->initiator << OID_S);
1356 aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM);
1363 aic_scsi_reset(struct aic_softc *aic)
1365 aic_outb(aic, SCSISEQ, SCSIRSTO);
1367 aic_outb(aic, SCSISEQ, 0);
1375 aic_reset(struct aic_softc *aic, int initiate_reset)
1382 aic_scsi_reset(aic);
1383 aic_chip_reset(aic);
1385 xpt_async(AC_BUS_RESET, aic->path, NULL);
1387 while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) {
1388 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
1390 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1393 while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) {
1394 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
1396 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1399 if (aic->nexus) {
1400 ccb_h = &aic->nexus->ccb->ccb_h;
1402 aic_done(aic, aic->nexus);
1405 aic->state = AIC_IDLE;
1406 aic_outb(aic, DMACNTRL0, INTEN);
1423 aic_init(struct aic_softc *aic)
1431 TAILQ_INIT(&aic->pending_ccbs);
1432 TAILQ_INIT(&aic->nexus_ccbs);
1433 SLIST_INIT(&aic->free_scbs);
1434 aic->nexus = NULL;
1435 aic->state = AIC_IDLE;
1436 aic->prev_phase = -1;
1437 aic->flags = 0;
1439 aic_chip_reset(aic);
1440 aic_scsi_reset(aic);
1443 aic->chip_type = AIC6260;
1444 aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1);
1448 aic->chip_type = aic_chip_ids[i].type;
1453 porta = aic_inb(aic, PORTA);
1454 portb = aic_inb(aic, PORTB);
1456 aic->initiator = PORTA_ID(porta);
1458 aic->flags |= AIC_PARITY_ENABLE;
1460 aic->flags |= AIC_DISC_ENABLE;
1462 aic->flags |= AIC_DMA_ENABLE;
1469 if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) {
1471 aic->flags |= AIC_FAST_ENABLE;
1472 aic->flags |= AIC_DWIO_ENABLE;
1475 if (aic->flags & AIC_FAST_ENABLE)
1476 aic->max_period = AIC_FAST_SYNC_PERIOD;
1478 aic->max_period = AIC_SYNC_PERIOD;
1479 aic->min_period = AIC_MIN_SYNC_PERIOD;
1482 scb = &aic->scbs[i];
1484 callout_init_mtx(&scb->timer, &aic->lock, 0);
1485 aic_free_scb(aic, scb);
1489 if (i == aic->initiator)
1491 ti = &aic->tinfo[i];
1494 if (aic->flags & AIC_DISC_ENABLE)
1496 ti->user.period = aic->max_period;
1501 aic_outb(aic, DMACNTRL0, INTEN);
1505 aic_probe(struct aic_softc *aic)
1510 aic_outb(aic, DMACNTRL0, 0);
1513 aic_outb(aic, DMACNTRL1, 0); /* Reset stack pointer */
1515 aic_outb(aic, STACK, i);
1518 aic_outb(aic, DMACNTRL1, 0);
1519 for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++)
1528 aic_attach(struct aic_softc *aic)
1542 aic->sim = cam_sim_alloc(aic_action, aic_poll, "aic", aic,
1543 device_get_unit(aic->dev), &aic->lock, 2, 256, devq);
1544 if (aic->sim == NULL) {
1549 mtx_lock(&aic->lock);
1550 if (xpt_bus_register(aic->sim, aic->dev, 0) != CAM_SUCCESS) {
1551 cam_sim_free(aic->sim, /*free_devq*/TRUE);
1552 mtx_unlock(&aic->lock);
1556 if (xpt_create_path(&aic->path, /*periph*/NULL,
1557 cam_sim_path(aic->sim), CAM_TARGET_WILDCARD,
1559 xpt_bus_deregister(cam_sim_path(aic->sim));
1560 cam_sim_free(aic->sim, /*free_devq*/TRUE);
1561 mtx_unlock(&aic->lock);
1565 aic_init(aic);
1567 device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]);
1568 if (aic->flags & AIC_DMA_ENABLE)
1570 if (aic->flags & AIC_DISC_ENABLE)
1572 if (aic->flags & AIC_PARITY_ENABLE)
1574 if (aic->flags & AIC_FAST_ENABLE)
1577 mtx_unlock(&aic->lock);
1582 aic_detach(struct aic_softc *aic)
1587 mtx_lock(&aic->lock);
1588 xpt_async(AC_LOST_DEVICE, aic->path, NULL);
1589 xpt_free_path(aic->path);
1590 xpt_bus_deregister(cam_sim_path(aic->sim));
1591 cam_sim_free(aic->sim, /*free_devq*/TRUE);
1592 mtx_unlock(&aic->lock);
1594 scb = &aic->scbs[i];