Lines Matching defs:aic

52 #include <dev/aic/aic6360reg.h>
53 #include <dev/aic/aicvar.h>
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);
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);
80 aic_get_scb(struct aic_softc *aic)
85 mtx_assert(&aic->lock, MA_OWNED);
86 if ((scb = SLIST_FIRST(&aic->free_scbs)) != NULL)
87 SLIST_REMOVE_HEAD(&aic->free_scbs, link);
92 aic_free_scb(struct aic_softc *aic, struct aic_scb *scb)
96 mtx_assert(&aic->lock, MA_OWNED);
97 if ((aic->flags & AIC_RESOURCE_SHORTAGE) != 0 &&
100 aic->flags &= ~AIC_RESOURCE_SHORTAGE;
103 SLIST_INSERT_HEAD(&aic->free_scbs, scb, link);
109 struct aic_softc *aic;
113 aic = (struct aic_softc *)cam_sim_softc(sim);
114 mtx_assert(&aic->lock, MA_OWNED);
122 if ((scb = aic_get_scb(aic)) == NULL) {
123 aic->flags |= AIC_RESOURCE_SHORTAGE;
124 xpt_freeze_simq(aic->sim, /*count*/1);
132 ccb->ccb_h.ccb_aic_ptr = aic;
142 aic_free_scb(aic, scb);
154 aic_free_scb(aic, scb);
174 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
181 (aic->flags & AIC_DISC_ENABLE) != 0) {
198 if (ti->goal.period > aic->min_period) {
201 } else if (ti->goal.period < aic->max_period)
202 ti->goal.period = aic->max_period;
224 struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id];
268 aic_reset(aic, /*initiate_reset*/TRUE);
283 cpi->initiator_id = aic->initiator;
310 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
313 mtx_assert(&aic->lock, MA_OWNED);
315 aic_free_scb(aic, scb);
322 TAILQ_INSERT_TAIL(&aic->pending_ccbs, &ccb->ccb_h, sim_links.tqe);
327 aic_start(aic);
334 aic_start(struct aic_softc *aic)
339 if (aic->state != AIC_IDLE)
342 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
343 ti = &aic->tinfo[ccb_h->target_id];
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);
354 aic_outb(aic, SIMODE0, ENSELDI);
355 aic_outb(aic, SIMODE1, ENSCSIRST);
356 aic_outb(aic, SCSISEQ, ENRESELI);
363 aic_select(struct aic_softc *aic)
365 struct aic_scb *scb = aic->nexus;
370 aic->state = AIC_SELECTING;
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));
377 aic_outb(aic, SIMODE0, ENSELDI|ENSELDO);
378 aic_outb(aic, SIMODE1, ENSCSIRST|ENSELTIMO);
379 aic_outb(aic, SCSISEQ, ENRESELI|ENSELO|ENAUTOATNO);
387 aic_selected(struct aic_softc *aic)
389 struct aic_scb *scb = aic->nexus;
391 struct aic_tinfo *ti = &aic->tinfo[scb->target];
396 aic->state = AIC_HASNEXUS;
399 aic->msg_buf[0] = MSG_BUS_DEV_RESET;
400 aic->msg_len = 1;
401 aic->msg_outq = AIC_MSG_MSGBUF;
403 aic->msg_outq = AIC_MSG_IDENTIFY;
406 aic->msg_outq |= AIC_MSG_TAG_Q;
410 aic->msg_outq |= AIC_MSG_SDTR;
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);
426 aic_reselected(struct aic_softc *aic)
436 if (aic->nexus) {
437 TAILQ_INSERT_HEAD(&aic->pending_ccbs,
438 &aic->nexus->ccb->ccb_h, sim_links.tqe);
439 aic->nexus = NULL;
442 selid = aic_inb(aic, SELID) & ~(1 << aic->initiator);
446 aic_reset(aic, /*initiate_reset*/TRUE);
450 aic->state = AIC_RESELECTED;
451 aic->target = ffs(selid) - 1;
452 aic->lun = -1;
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);
466 aic_sched_msgout(struct aic_softc *aic, u_int8_t msg)
469 aic->msg_buf[0] = msg;
470 aic->msg_len = 1;
472 aic->msg_outq |= AIC_MSG_MSGBUF;
473 aic_outb(aic, SCSISIGO, aic_inb(aic, SCSISIGI) | ATNO);
480 aic_spiordy(struct aic_softc *aic)
482 while (!(aic_inb(aic, DMASTAT) & INTSTAT) &&
483 !(aic_inb(aic, SSTAT0) & SPIORDY))
485 return !(aic_inb(aic, DMASTAT) & INTSTAT);
492 aic_reconnect(struct aic_softc *aic, int tag)
501 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
503 if (scb->target == aic->target && scb->lun == aic->lun &&
511 aic_sched_msgout(aic, MSG_ABORT);
513 aic_sched_msgout(aic, MSG_ABORT_TAG);
514 xpt_async(AC_UNSOL_RESEL, aic->path, NULL);
519 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
520 aic->nexus = scb;
522 aic->state = AIC_HASNEXUS;
529 aic_msgin(struct aic_softc *aic)
535 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
536 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
538 aic->flags &= ~AIC_DROP_MSGIN;
539 aic->msg_len = 0;
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);
551 if ((aic->flags & AIC_DROP_MSGIN)) {
552 aic_inb(aic, SCSIDAT);
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);
562 switch (aic->msg_buf[2]) {
573 if (aic->msg_buf[1] != msglen) {
574 aic->flags |= AIC_DROP_MSGIN;
575 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
578 } else if (aic->msg_buf[0] >= 0x20 && aic->msg_buf[0] <= 0x2f)
586 if (aic->msg_len == msglen) {
587 aic_handle_msgin(aic);
588 aic->msg_len = 0;
591 (void) aic_inb(aic, SCSIDAT);
592 } while (aic_spiordy(aic));
594 aic_outb(aic, SXFRCTL0, CHEN);
595 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
602 aic_handle_msgin(struct aic_softc *aic)
610 if (aic->state == AIC_RESELECTED) {
611 if (!MSG_ISIDENTIFY(aic->msg_buf[0])) {
612 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
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);
619 aic->state = AIC_RECONNECTING;
623 if (aic->state == AIC_RECONNECTING) {
624 if (aic->msg_buf[0] != MSG_SIMPLE_Q_TAG) {
625 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
628 aic_reconnect(aic, aic->msg_buf[1]);
632 switch (aic->msg_buf[0]) {
635 scb = aic->nexus;
662 aic->flags |= AIC_BUSFREE_OK;
667 aic_done(aic, scb);
668 aic->flags |= AIC_BUSFREE_OK;
672 switch (aic->msg_buf[2]) {
674 scb = aic->nexus;
675 ti = &aic->tinfo[scb->target];
677 ti->current.period = aic->msg_buf[3];
678 ti->current.offset = aic->msg_buf[4];
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]);
688 aic_sched_msgout(aic, 0);
693 aic_outb(aic, SCSIRATE, ti->scsirate);
709 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
714 scb = aic->nexus;
716 TAILQ_INSERT_TAIL(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
718 aic->flags |= AIC_BUSFREE_OK;
719 aic->nexus = NULL;
723 switch (aic->msg_outq & -aic->msg_outq) {
725 scb = aic->nexus;
726 ti = &aic->tinfo[scb->target];
731 scb = aic->nexus;
732 ti = &aic->tinfo[scb->target];
737 aic_outb(aic, SCSIRATE, ti->scsirate);
762 aic_sched_msgout(aic, MSG_MESSAGE_REJECT);
771 aic_msgout(struct aic_softc *aic)
780 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
781 aic_outb(aic, SXFRCTL0, CHEN|SPIOEN);
789 if (aic->prev_phase == PH_MSGOUT)
790 aic->msg_outq = aic->msg_sent;
793 int q = aic->msg_outq;
794 if (msgidx > 0 && msgidx == aic->msg_len) {
797 aic->msg_sent |= q;
798 aic->msg_outq ^= q;
799 q = aic->msg_outq;
806 scb = aic->nexus;
808 ti = &aic->tinfo[scb->target];
809 aic->msg_buf[0] = MSG_IDENTIFY(scb->lun,
812 aic->msg_len = 1;
815 scb = aic->nexus;
817 aic->msg_buf[0] = ccb->csio.tag_action;
818 aic->msg_buf[1] = scb->tag;
819 aic->msg_len = 2;
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;
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;
845 if ((q & (q - 1)) == 0 && msgidx == aic->msg_len - 1)
846 aic_outb(aic, CLRSINT1, CLRATNO);
848 aic_outb(aic, SCSIDAT, aic->msg_buf[msgidx++]);
849 } while (aic_spiordy(aic));
851 aic_outb(aic, SXFRCTL0, CHEN);
852 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
859 aic_datain(struct aic_softc *aic)
861 struct aic_scb *scb = aic->nexus;
867 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
868 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
871 if (aic->flags & AIC_DWIO_ENABLE)
873 aic_outb(aic, DMACNTRL0, dmacntrl0);
878 dmastat = aic_inb(aic, DMASTAT);
889 while (!(aic_inb(aic, SSTAT2) & SEMPTY))
891 n = aic_inb(aic, FIFOSTAT);
894 if (aic->flags & AIC_DWIO_ENABLE) {
896 aic_insl(aic, DMADATALONG, scb->data_ptr, n>>2);
903 aic_insw(aic, DMADATA, scb->data_ptr, n >> 1);
910 aic_outb(aic, DMACNTRL0, ENDMA|B8MODE);
911 aic_insb(aic, DMADATA, scb->data_ptr, n);
914 aic_outb(aic, DMACNTRL0, dmacntrl0);
921 aic_outb(aic, SXFRCTL0, CHEN);
922 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
929 aic_dataout(struct aic_softc *aic)
931 struct aic_scb *scb = aic->nexus;
937 aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE);
938 aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN);
941 if (aic->flags & AIC_DWIO_ENABLE)
943 aic_outb(aic, DMACNTRL0, dmacntrl0);
948 dmastat = aic_inb(aic, DMASTAT);
955 if (aic->flags & AIC_DWIO_ENABLE) {
957 aic_outsl(aic, DMADATALONG, scb->data_ptr,n>>2);
964 aic_outsw(aic, DMADATA, scb->data_ptr, n >> 1);
971 aic_outb(aic, DMACNTRL0, ENDMA|WRITE|B8MODE);
972 aic_outsb(aic, DMADATA, scb->data_ptr, n);
975 aic_outb(aic, DMACNTRL0, dmacntrl0);
981 dmastat = aic_inb(aic, DMASTAT);
982 sstat2 = aic_inb(aic, SSTAT2);
987 n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf);
991 aic_outb(aic, SXFRCTL0, CHEN|CLRCH);
992 aic_outb(aic, DMACNTRL0, RSTFIFO);
997 aic_outb(aic, SXFRCTL0, CHEN);
998 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1005 aic_cmd(struct aic_softc *aic)
1007 struct aic_scb *scb = aic->nexus;
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)
1033 aic_outb(aic, SXFRCTL0, CHEN);
1034 aic_outb(aic, SIMODE1, ENSCSIRST|ENBUSFREE|ENREQINIT);
1042 aic_done(struct aic_softc *aic, struct aic_scb *scb)
1059 cam_sim_path(aic->sim),
1068 ccb_h = TAILQ_FIRST(&aic->pending_ccbs);
1076 TAILQ_REMOVE(&aic->pending_ccbs,
1078 aic_done(aic, pending_scb);
1087 ccb_h = TAILQ_FIRST(&aic->nexus_ccbs);
1095 TAILQ_REMOVE(&aic->nexus_ccbs,
1097 aic_done(aic, nexus_scb);
1107 if (aic->nexus == scb || scb->flags & SCB_DISCONNECTED)
1108 aic->tinfo[scb->target].lubusy &= ~(1 << scb->lun);
1110 if (aic->nexus == scb) {
1111 aic->nexus = NULL;
1113 aic_free_scb(aic, scb);
1128 struct aic_softc *aic = (struct aic_softc *)ccb->ccb_h.ccb_aic_ptr;
1130 mtx_assert(&aic->lock, MA_OWNED);
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);
1143 if ((scb->flags & SCB_DEVICE_RESET) == 0 && aic->nexus == scb) {
1148 xpt_freeze_simq(aic->sim, /*count*/1);
1152 TAILQ_FOREACH(ccb_h, &aic->pending_ccbs, sim_links.tqe) {
1157 TAILQ_FOREACH(ccb_h, &aic->nexus_ccbs, sim_links.tqe) {
1164 aic_sched_msgout(aic, MSG_BUS_DEV_RESET);
1166 if (aic->nexus == scb) {
1168 aic_done(aic, scb);
1170 aic_reset(aic, /*initiate_reset*/TRUE);
1177 struct aic_softc *aic = (struct aic_softc *)arg;
1179 mtx_lock(&aic->lock);
1180 aic_intr_locked(aic);
1181 mtx_unlock(&aic->lock);
1185 aic_intr_locked(struct aic_softc *aic)
1191 if (!(aic_inb(aic, DMASTAT) & INTSTAT))
1194 aic_outb(aic, DMACNTRL0, 0);
1196 sstat0 = aic_inb(aic, SSTAT0);
1197 sstat1 = aic_inb(aic, SSTAT1);
1201 aic_outb(aic, CLRSINT1, CLRSCSIRSTI);
1202 aic_reset(aic, /*initiate_reset*/FALSE);
1207 aic_outb(aic, CLRSINT1, CLRSCSIPERR);
1208 aic_sched_msgout(aic, MSG_PARITY_ERROR);
1209 aic_outb(aic, DMACNTRL0, INTEN);
1213 if (aic_inb(aic, SSTAT4)) {
1214 aic_outb(aic, CLRSERR, CLRSYNCERR|CLRFWERR|CLRFRERR);
1215 aic_reset(aic, /*initiate_reset*/TRUE);
1219 if (aic->state <= AIC_SELECTING) {
1221 aic_reselected(aic);
1222 aic_outb(aic, DMACNTRL0, INTEN);
1227 aic_selected(aic);
1228 aic_outb(aic, DMACNTRL0, INTEN);
1233 scb = aic->nexus;
1236 aic_done(aic, scb);
1238 sstat1 = aic_inb(aic, SSTAT1);
1239 aic->flags |= AIC_BUSFREE_OK;
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) {
1251 aic_done(aic, scb);
1260 aic_done(aic, scb);
1263 aic->flags &= ~AIC_BUSFREE_OK;
1264 aic->tinfo[scb->target].lubusy &=
1266 aic_select(aic);
1267 aic_outb(aic, DMACNTRL0, INTEN);
1271 aic->flags &= ~AIC_BUSFREE_OK;
1272 aic->state = AIC_IDLE;
1273 aic_start(aic);
1274 aic_outb(aic, DMACNTRL0, INTEN);
1279 u_int8_t phase = aic_inb(aic, SCSISIGI) & PH_MASK;
1280 aic_outb(aic, SCSISIGO, phase);
1281 aic_outb(aic, CLRSINT1, CLRPHASECHG);
1285 aic_msgout(aic);
1288 aic_msgin(aic);
1291 scb = aic->nexus;
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);
1299 aic_cmd(aic);
1302 aic_datain(aic);
1305 aic_dataout(aic);
1308 aic->prev_phase = phase;
1309 aic_outb(aic, DMACNTRL0, INTEN);
1315 aic_outb(aic, DMACNTRL0, INTEN);
1322 aic_chip_reset(struct aic_softc *aic)
1328 aic_outb(aic, SCSITEST, 0);
1329 aic_outb(aic, TEST, 0);
1332 aic_outb(aic, SXFRCTL0, CHEN|CLRCH|CLRSTCNT);
1335 aic_outb(aic, DMACNTRL0, RSTFIFO);
1336 aic_outb(aic, DMACNTRL1, 0);
1339 aic_outb(aic, SCSISEQ, 0);
1340 aic_outb(aic, SXFRCTL1, 0);
1343 aic_outb(aic, SIMODE0, 0);
1344 aic_outb(aic, SIMODE1, 0);
1347 aic_outb(aic, CLRSINT0, 0x7f);
1348 aic_outb(aic, CLRSINT1, 0xef);
1351 aic_outb(aic, SCSIRATE, 0);
1354 aic_outb(aic, CLRSERR, 0x07);
1357 aic_outb(aic, SCSIID, aic->initiator << OID_S);
1358 aic_outb(aic, BRSTCNTRL, EISA_BRST_TIM);
1365 aic_scsi_reset(struct aic_softc *aic)
1367 aic_outb(aic, SCSISEQ, SCSIRSTO);
1369 aic_outb(aic, SCSISEQ, 0);
1377 aic_reset(struct aic_softc *aic, int initiate_reset)
1384 aic_scsi_reset(aic);
1385 aic_chip_reset(aic);
1387 xpt_async(AC_BUS_RESET, aic->path, NULL);
1389 while ((ccb_h = TAILQ_FIRST(&aic->pending_ccbs)) != NULL) {
1390 TAILQ_REMOVE(&aic->pending_ccbs, ccb_h, sim_links.tqe);
1392 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1395 while ((ccb_h = TAILQ_FIRST(&aic->nexus_ccbs)) != NULL) {
1396 TAILQ_REMOVE(&aic->nexus_ccbs, ccb_h, sim_links.tqe);
1398 aic_done(aic, (struct aic_scb *)ccb_h->ccb_scb_ptr);
1401 if (aic->nexus) {
1402 ccb_h = &aic->nexus->ccb->ccb_h;
1404 aic_done(aic, aic->nexus);
1407 aic->state = AIC_IDLE;
1408 aic_outb(aic, DMACNTRL0, INTEN);
1425 aic_init(struct aic_softc *aic)
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;
1441 aic_chip_reset(aic);
1442 aic_scsi_reset(aic);
1445 aic->chip_type = AIC6260;
1446 aic_insb(aic, ID, chip_id, sizeof(chip_id) - 1);
1450 aic->chip_type = aic_chip_ids[i].type;
1455 porta = aic_inb(aic, PORTA);
1456 portb = aic_inb(aic, PORTB);
1458 aic->initiator = PORTA_ID(porta);
1460 aic->flags |= AIC_PARITY_ENABLE;
1462 aic->flags |= AIC_DISC_ENABLE;
1464 aic->flags |= AIC_DMA_ENABLE;
1471 if (aic->chip_type > AIC6260 || aic_inb(aic, REV)) {
1473 aic->flags |= AIC_FAST_ENABLE;
1474 aic->flags |= AIC_DWIO_ENABLE;
1477 if (aic->flags & AIC_FAST_ENABLE)
1478 aic->max_period = AIC_FAST_SYNC_PERIOD;
1480 aic->max_period = AIC_SYNC_PERIOD;
1481 aic->min_period = AIC_MIN_SYNC_PERIOD;
1484 scb = &aic->scbs[i];
1486 callout_init_mtx(&scb->timer, &aic->lock, 0);
1487 aic_free_scb(aic, scb);
1491 if (i == aic->initiator)
1493 ti = &aic->tinfo[i];
1496 if (aic->flags & AIC_DISC_ENABLE)
1498 ti->user.period = aic->max_period;
1503 aic_outb(aic, DMACNTRL0, INTEN);
1507 aic_probe(struct aic_softc *aic)
1512 aic_outb(aic, DMACNTRL0, 0);
1515 aic_outb(aic, DMACNTRL1, 0); /* Reset stack pointer */
1517 aic_outb(aic, STACK, i);
1520 aic_outb(aic, DMACNTRL1, 0);
1521 for (i = 0; i < STSIZE && aic_inb(aic, STACK) == i; i++)
1530 aic_attach(struct aic_softc *aic)
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) {
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);
1558 if (xpt_create_path(&aic->path, /*periph*/NULL,
1559 cam_sim_path(aic->sim), CAM_TARGET_WILDCARD,
1561 xpt_bus_deregister(cam_sim_path(aic->sim));
1562 cam_sim_free(aic->sim, /*free_devq*/TRUE);
1563 mtx_unlock(&aic->lock);
1567 aic_init(aic);
1569 device_printf(aic->dev, "%s", aic_chip_names[aic->chip_type]);
1570 if (aic->flags & AIC_DMA_ENABLE)
1572 if (aic->flags & AIC_DISC_ENABLE)
1574 if (aic->flags & AIC_PARITY_ENABLE)
1576 if (aic->flags & AIC_FAST_ENABLE)
1579 mtx_unlock(&aic->lock);
1580 gone_in_dev(aic->dev, 12, "aic(4) driver");
1585 aic_detach(struct aic_softc *aic)
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);
1597 scb = &aic->scbs[i];