aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin T. Gibbs <gibbs@FreeBSD.org>2000-07-24 22:27:40 +0000
committerJustin T. Gibbs <gibbs@FreeBSD.org>2000-07-24 22:27:40 +0000
commitc27eebfde8c04a4e0d30bde64ad064898e2eb8c9 (patch)
treefe38954cea889ad85733a92ef20e8dbb9ee9a8d6
parentfbf29924ba6cd3bda0984acda024b0bdeda48d0e (diff)
downloadsrc-c27eebfde8c04a4e0d30bde64ad064898e2eb8c9.tar.gz
src-c27eebfde8c04a4e0d30bde64ad064898e2eb8c9.zip
Notes
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c118
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h7
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq16
3 files changed, 92 insertions, 49 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c
index 3859c190042c..8ac28db9db92 100644
--- a/sys/dev/aic7xxx/aic7xxx.c
+++ b/sys/dev/aic7xxx/aic7xxx.c
@@ -168,8 +168,10 @@
(0x01 << (SCB_GET_TARGET_OFFSET(ahc, scb)))
#define TCL_TARGET_OFFSET(tcl) \
((((tcl) >> 4) & TID) >> 4)
+#define TCL_LUN(tcl) \
+ (tcl & (AHC_NUM_LUNS - 1))
#define BUILD_TCL(scsiid, lun) \
- ((lun) | (((scsiid) & TID) >> 4))
+ ((lun) | (((scsiid) & TID) << 4))
#define BUILD_SCSIID(ahc, sim, target_id, our_id) \
((((target_id) << TID_SHIFT) & TID) | (our_id) \
| (SIM_IS_SCSIBUS_B(ahc, sim) ? TWIN_CHNLB : 0))
@@ -394,8 +396,8 @@ static void ahc_queue_lstate_event(struct ahc_softc *ahc,
u_int event_arg);
static void ahc_send_lstate_events(struct ahc_softc *ahc,
struct tmode_lstate *lstate);
-static void restart_sequencer(struct ahc_softc *ahc);
-static __inline u_int ahc_index_busy_tcl(struct ahc_softc *ahc,
+static void restart_sequencer(struct ahc_softc *ahc);
+static u_int ahc_index_busy_tcl(struct ahc_softc *ahc,
u_int tcl, int unbusy);
static __inline void ahc_freeze_ccb(union ccb* ccb);
@@ -468,16 +470,29 @@ restart_sequencer(struct ahc_softc *ahc)
unpause_sequencer(ahc);
}
-static __inline u_int
+static u_int
ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl, int unbusy)
{
u_int scbid;
u_int target_offset;
- target_offset = TCL_TARGET_OFFSET(tcl);
- scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
- if (unbusy)
- ahc_outb(ahc, BUSY_TARGETS + target_offset, SCB_LIST_NULL);
+ if ((ahc->features & AHC_SCB_BTT) != 0) {
+ u_int saved_scbptr;
+
+ saved_scbptr = ahc_inb(ahc, SCBPTR);
+ ahc_outb(ahc, SCBPTR, TCL_LUN(tcl));
+ scbid = ahc_inb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl));
+ if (unbusy)
+ ahc_outb(ahc, SCB_64_BTT + TCL_TARGET_OFFSET(tcl),
+ SCB_LIST_NULL);
+ ahc_outb(ahc, SCBPTR, saved_scbptr);
+ } else {
+ target_offset = TCL_TARGET_OFFSET(tcl);
+ scbid = ahc_inb(ahc, BUSY_TARGETS + target_offset);
+ if (unbusy)
+ ahc_outb(ahc, BUSY_TARGETS + target_offset,
+ SCB_LIST_NULL);
+ }
return (scbid);
}
@@ -1199,10 +1214,10 @@ ahc_reset(struct ahc_softc *ahc)
* not, STPWEN will be false (the value after a POST)
* and this action will be harmless.
*
- * We must actually always initialize STPWEN to 1
- * before we restore the saved value. STPWEN is
- * initialized to a tri-state condition which is
- * only be cleared by turning it on.
+ * We must always initialize STPWEN to 1 before we
+ * restore the saved value. STPWEN is initialized
+ * to a tri-state condition which is only be cleared
+ * by turning it on.
*/
ahc_outb(ahc, SXFRCTL1, sxfrctl1|STPWEN);
ahc_outb(ahc, SXFRCTL1, sxfrctl1);
@@ -4518,23 +4533,6 @@ ahc_init(struct ahc_softc *ahc)
if (ahcinitscbdata(ahc) != 0)
return (ENOMEM);
- /* There are no untagged SCBs active yet. */
- /* XXX will need to change for SCB ram approach */
- for (i = 0; i < 16; i++)
- ahc_index_busy_tcl(ahc, BUILD_TCL(i << 4, 0), /*unbusy*/TRUE);
-
- /* All of our queues are empty */
- for (i = 0; i < 256; i++)
- ahc->qoutfifo[i] = SCB_LIST_NULL;
-
- for (i = 0; i < 256; i++)
- ahc->qinfifo[i] = SCB_LIST_NULL;
-
- if ((ahc->features & AHC_MULTI_TID) != 0) {
- ahc_outb(ahc, TARGID, 0);
- ahc_outb(ahc, TARGID + 1, 0);
- }
-
/*
* Allocate a tstate to house information for our
* initiator presence on the bus as well as the user
@@ -4747,6 +4745,36 @@ ahc_init(struct ahc_softc *ahc)
ahc->user_discenable = discenable;
ahc->user_tagenable = tagenable;
+ /* There are no untagged SCBs active yet. */
+ for (i = 0; i < 16; i++) {
+ ahc_index_busy_tcl(ahc, BUILD_TCL(i << 4, 0), /*unbusy*/TRUE);
+ if ((ahc->features & AHC_SCB_BTT) != 0) {
+ int lun;
+
+ /*
+ * The SCB based BTT allows an entry per
+ * target and lun pair.
+ */
+ for (lun = 1; lun < AHC_NUM_LUNS; lun++) {
+ ahc_index_busy_tcl(ahc,
+ BUILD_TCL(i << 4, lun),
+ /*unbusy*/TRUE);
+ }
+ }
+ }
+
+ /* All of our queues are empty */
+ for (i = 0; i < 256; i++)
+ ahc->qoutfifo[i] = SCB_LIST_NULL;
+
+ for (i = 0; i < 256; i++)
+ ahc->qinfifo[i] = SCB_LIST_NULL;
+
+ if ((ahc->features & AHC_MULTI_TID) != 0) {
+ ahc_outb(ahc, TARGID, 0);
+ ahc_outb(ahc, TARGID + 1, 0);
+ }
+
/*
* Tell the sequencer where it can find our arrays in memory.
*/
@@ -5320,7 +5348,7 @@ ahc_action(struct cam_sim *sim, union ccb *ccb)
found = ahc_reset_channel(ahc, SIM_CHANNEL(ahc, sim),
/*initiate reset*/TRUE);
splx(s);
- if (1 || bootverbose) {
+ if (bootverbose) {
xpt_print_path(SIM_PATH(ahc, sim));
printf("SCSI bus reset delivered. "
"%d SCBs aborted.\n", found);
@@ -6577,14 +6605,36 @@ ahc_abort_scbs(struct ahc_softc *ahc, int target, char channel,
for (;i < maxtarget; i++) {
u_int scbid;
- /* XXX Will need lun loop for SCB ram version */
scbid = ahc_index_busy_tcl(ahc, BUILD_TCL(i << 4, 0),
/*unbusy*/FALSE);
scbp = &ahc->scb_data->scbarray[scbid];
if (scbid < ahc->scb_data->numscbs
- && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role))
- ahc_index_busy_tcl(ahc, BUILD_TCL(i << 4, 0),
- /*unbusy*/TRUE);
+ && ahc_match_scb(ahc, scbp, target, channel, lun, tag, role)) {
+ u_int minlun;
+ u_int maxlun;
+
+ if (lun == CAM_LUN_WILDCARD) {
+
+ /*
+ * Unless we are using an SCB based
+ * busy targets table, there is only
+ * one table entry for all luns of
+ * a target.
+ */
+ minlun = 0;
+ maxlun = 1;
+ if ((ahc->flags & AHC_SCB_BTT) != 0)
+ maxlun = AHC_NUM_LUNS;
+ } else {
+ minlun = lun;
+ maxlun = lun + 1;
+ }
+ while (minlun < maxlun) {
+ ahc_index_busy_tcl(ahc, BUILD_TCL(i << 4,
+ minlun), /*unbusy*/TRUE);
+ minlun++;
+ }
+ }
}
/*
diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h
index e491e22ca0b3..6845299b5bfa 100644
--- a/sys/dev/aic7xxx/aic7xxx.h
+++ b/sys/dev/aic7xxx/aic7xxx.h
@@ -56,12 +56,9 @@
/*
* The maximum number of supported luns.
- * Although the identify message only supports 64 luns in SPI3, you
- * can have 2^64 luns when information unit transfers are enabled.
- * The max we can do sanely given the 8bit nature of the RISC engine
- * on these chips is 256.
+ * The identify message supports up to 64 luns in SPI3.
*/
-#define AHC_NUM_LUNS 256
+#define AHC_NUM_LUNS 64
/*
* The maximum transfer per S/G segment.
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index d2df34ddc299..00b28b3c79d8 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -1112,13 +1112,13 @@ p_command_embedded:
}
if ((ahc->features & AHC_CMD_CHAN) != 0) {
bmov DFDAT, SCB_CDB_STORE, 12;
+ if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
+ or DFCNTRL, FIFOFLUSH;
+ }
} else {
- /*
- * At most 12 bytes, but we copy 16 to fill
- * the 64bit words in the FIFO
- */
- call copy_to_fifo_8;
- call copy_to_fifo_8;
+ call copy_to_fifo_6;
+ call copy_to_fifo_6;
+ or DFCNTRL, FIFOFLUSH;
}
p_command_loop:
test SSTAT0, SDONE jnz . + 2;
@@ -1849,10 +1849,6 @@ dfdat_in_2_continued:
mov DINDIR,DFDAT ret;
}
-copy_to_fifo_8:
- mov DFDAT,SINDIR;
-copy_to_fifo_7:
- mov DFDAT,SINDIR;
copy_to_fifo_6:
mov DFDAT,SINDIR;
copy_to_fifo_5: