summaryrefslogtreecommitdiffstats
path: root/sys/dev/sym
diff options
context:
space:
mode:
authorgroudier <groudier@FreeBSD.org>2000-05-07 09:54:33 +0000
committergroudier <groudier@FreeBSD.org>2000-05-07 09:54:33 +0000
commit181073b7649a8d8a4b2c5066d83b4b53f89bd245 (patch)
treec0a6e40cc518dbb3d9c1c2d97477de84a140ee9b /sys/dev/sym
parent8b4aef321a44df187cd1c4396dbd0ce2dfd4549e (diff)
downloadFreeBSD-src-181073b7649a8d8a4b2c5066d83b4b53f89bd245.zip
FreeBSD-src-181073b7649a8d8a4b2c5066d83b4b53f89bd245.tar.gz
Work-around a couple of C1010 quirks:
- Reload SCNTL3 after selection from host (C1010-33). - Reload SCNTL4 prior to any DATA OUT phase (C1010-66). - Use max SCSI offset 31 for ST but 62 for DT.
Diffstat (limited to 'sys/dev/sym')
-rw-r--r--sys/dev/sym/sym_fw1.h2
-rw-r--r--sys/dev/sym/sym_fw2.h23
-rw-r--r--sys/dev/sym/sym_hipd.c108
3 files changed, 93 insertions, 40 deletions
diff --git a/sys/dev/sym/sym_fw1.h b/sys/dev/sym/sym_fw1.h
index 8c84f02..f671679 100644
--- a/sys/dev/sym/sym_fw1.h
+++ b/sys/dev/sym/sym_fw1.h
@@ -1019,7 +1019,7 @@ static struct SYM_FWA_SCR SYM_FWA_SCR = {
/* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */
}/*-------------------------< RESEL_TAG >------------------------*/,{
/*
- * ACK the IDENTIFY or TAG previously received.
+ * ACK the IDENTIFY previously received.
*/
SCR_CLR (SCR_ACK),
0,
diff --git a/sys/dev/sym/sym_fw2.h b/sys/dev/sym/sym_fw2.h
index 8af671e..c0a8918 100644
--- a/sys/dev/sym/sym_fw2.h
+++ b/sys/dev/sym/sym_fw2.h
@@ -78,6 +78,7 @@ struct SYM_FWA_SCR {
u32 getjob_end [ 4];
u32 select [ 8];
u32 wf_sel_done [ 2];
+ u32 sel_done [ 2];
u32 send_ident [ 2];
#ifdef SYM_CONF_IARB_SUPPORT
u32 select2 [ 8];
@@ -93,7 +94,7 @@ struct SYM_FWA_SCR {
u32 datai_done [ 26];
u32 datao_done [ 12];
u32 datai_phase [ 2];
- u32 datao_phase [ 2];
+ u32 datao_phase [ 4];
u32 msg_in [ 2];
u32 msg_in2 [ 10];
#ifdef SYM_CONF_IARB_SUPPORT
@@ -322,6 +323,16 @@ static struct SYM_FWA_SCR SYM_FWA_SCR = {
}/*-------------------------< WF_SEL_DONE >----------------------*/,{
SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)),
SIR_SEL_ATN_NO_MSG_OUT,
+}/*-------------------------< SEL_DONE >-------------------------*/,{
+ /*
+ * C1010-33 errata work-around.
+ * Due to a race, the SCSI core may not have
+ * loaded SCNTL3 on SEL_TBL instruction.
+ * We reload it once phase is stable.
+ * Patched with a NOOP for other chips.
+ */
+ SCR_LOAD_REL (scntl3, 1),
+ offsetof(struct sym_dsb, select.sel_scntl3),
}/*-------------------------< SEND_IDENT >-----------------------*/,{
/*
* Selection complete.
@@ -538,6 +549,14 @@ static struct SYM_FWA_SCR SYM_FWA_SCR = {
SCR_RETURN,
0,
}/*-------------------------< DATAO_PHASE >----------------------*/,{
+ /*
+ * C1010-66 errata work-around.
+ * SCNTL4 to be written prior to any DATA_OUT
+ * phase if 33 MHz PCI BUS.
+ * Patched with a NOOP for other chips.
+ */
+ SCR_LOAD_REL (scntl4, 1),
+ offsetof(struct sym_dsb, select.sel_scntl4),
SCR_RETURN,
0,
}/*-------------------------< MSG_IN >---------------------------*/,{
@@ -918,7 +937,7 @@ static struct SYM_FWA_SCR SYM_FWA_SCR = {
/* In normal situations, we jump to RESEL_TAG or RESEL_NO_TAG */
}/*-------------------------< RESEL_TAG >------------------------*/,{
/*
- * ACK the IDENTIFY or TAG previously received.
+ * ACK the IDENTIFY previously received.
*/
SCR_CLR (SCR_ACK),
0,
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index 7b4eda7..a72a623 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -57,7 +57,9 @@
/* $FreeBSD$ */
-#define SYM_DRIVER_NAME "sym-1.5.2-20000430"
+#define SYM_DRIVER_NAME "sym-1.5.3-20000506"
+
+/* #define SYM_DEBUG_GENERIC_SUPPORT */
#include <pci.h>
#include <stddef.h> /* For offsetof */
@@ -1710,9 +1712,10 @@ struct sym_hcb {
u_char maxwide; /* Maximum transfer width */
u_char minsync; /* Min sync period factor (ST) */
u_char maxsync; /* Max sync period factor (ST) */
+ u_char maxoffs; /* Max scsi offset (ST) */
u_char minsync_dt; /* Min sync period factor (DT) */
u_char maxsync_dt; /* Max sync period factor (DT) */
- u_char maxoffs; /* Max scsi offset */
+ u_char maxoffs_dt; /* Max scsi offset (DT) */
u_char multiplier; /* Clock multiplier (1,2,4) */
u_char clock_divn; /* Number of clock divisors */
u_long clock_khz; /* SCSI clock frequency in KHz */
@@ -1961,6 +1964,19 @@ sym_fw2_patch(hcb_p np)
}
/*
+ * Remove a couple of work-arounds specific to C1010 if
+ * they are not desirable. See `sym_fw2.h' for more details.
+ */
+ if ((np->features & (FE_C10|FE_PCI66)) != (FE_C10|FE_PCI66)) {
+ scripta0->datao_phase[0] = cpu_to_scr(SCR_NO_OP);
+ scripta0->datao_phase[1] = cpu_to_scr(0);
+ }
+ if ((np->features & (FE_C10|FE_PCI66)) != FE_C10) {
+ scripta0->sel_done[0] = cpu_to_scr(SCR_NO_OP);
+ scripta0->sel_done[1] = cpu_to_scr(0);
+ }
+
+ /*
* Patch some other variables in SCRIPTS.
* These ones are loaded by the SCRIPTS processor.
*/
@@ -2657,6 +2673,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
if (np->clock_khz == 160000) {
np->minsync_dt = 9;
np->maxsync_dt = 50;
+ np->maxoffs_dt = 62;
}
}
@@ -2830,6 +2847,14 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
sym_nvram_setup_target (np, i, nvram);
+ /*
+ * For now, guess PPR support from the period.
+ */
+ if (tp->tinfo.user.period <= 9) {
+ tp->tinfo.user.options |= PPR_OPT_DT;
+ tp->tinfo.user.offset = np->maxoffs_dt;
+ }
+
if (!tp->usrtags)
tp->usrflags &= ~SYM_TAGS_ENABLED;
}
@@ -2898,17 +2923,6 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr)
tcb_p tp = &np->target[cp->target];
int msglen = 0;
-#if 1
- /*
- * For now, only use PPR with DT option if period factor = 9.
- */
- if (tp->tinfo.goal.period == 9) {
- tp->tinfo.goal.width = BUS_16_BIT;
- tp->tinfo.goal.options |= PPR_OPT_DT;
- }
- else
- tp->tinfo.goal.options &= ~PPR_OPT_DT;
-#endif
/*
* Early C1010 chips need a work-around for DT
* data transfer to work.
@@ -5788,7 +5802,11 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp)
if (dt != (np->msgin[7] & PPR_OPT_MASK)) chg = 1;
if (ofs) {
- if (ofs > np->maxoffs)
+ if (dt) {
+ if (ofs > np->maxoffs_dt)
+ {chg = 1; ofs = np->maxoffs_dt;}
+ }
+ else if (ofs > np->maxoffs)
{chg = 1; ofs = np->maxoffs;}
if (req) {
if (ofs > tp->tinfo.user.offset)
@@ -7561,11 +7579,7 @@ static void sym_action1(struct cam_sim *sim, union ccb *ccb)
if (tp->tinfo.current.width != tp->tinfo.goal.width ||
tp->tinfo.current.period != tp->tinfo.goal.period ||
tp->tinfo.current.offset != tp->tinfo.goal.offset ||
-#if 0 /* For now only renegotiate, based on width, period and offset */
tp->tinfo.current.options != tp->tinfo.goal.options) {
-#else
- 0) {
-#endif
if (!tp->nego_cp && lp)
msglen += sym_prepare_nego(np, cp, 0, msgptr + msglen);
}
@@ -8356,25 +8370,45 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
tip->period = cts->sync_period;
/*
- * Scale against out limits.
+ * Scale against driver configuration limits.
*/
- if (tip->width > SYM_SETUP_MAX_WIDE) tip->width =SYM_SETUP_MAX_WIDE;
- if (tip->width > np->maxwide) tip->width = np->maxwide;
- if (tip->offset > SYM_SETUP_MAX_OFFS) tip->offset =SYM_SETUP_MAX_OFFS;
- if (tip->offset > np->maxoffs) tip->offset = np->maxoffs;
- if (tip->period) {
- if (tip->period < SYM_SETUP_MIN_SYNC)
- tip->period = SYM_SETUP_MIN_SYNC;
- if (np->features & FE_ULTRA3) {
- if (tip->period < np->minsync_dt)
- tip->period = np->minsync_dt;
- }
- else {
- if (tip->period < np->minsync)
- tip->period = np->minsync;
- }
+ if (tip->width > SYM_SETUP_MAX_WIDE) tip->width = SYM_SETUP_MAX_WIDE;
+ if (tip->offset > SYM_SETUP_MAX_OFFS) tip->offset = SYM_SETUP_MAX_OFFS;
+ if (tip->period < SYM_SETUP_MIN_SYNC) tip->period = SYM_SETUP_MIN_SYNC;
+
+ /*
+ * Scale against actual controller BUS width.
+ */
+ if (tip->width > np->maxwide)
+ tip->width = np->maxwide;
+
+ /*
+ * For now, only assume DT if period <= 9, BUS 16 and offset != 0.
+ */
+ tip->options = 0;
+ if ((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3) &&
+ tip->period <= 9 && tip->width == BUS_16_BIT && tip->offset) {
+ tip->options |= PPR_OPT_DT;
+ }
+
+ /*
+ * Scale period factor and offset against controller limits.
+ */
+ if (tip->options & PPR_OPT_DT) {
+ if (tip->period < np->minsync_dt)
+ tip->period = np->minsync_dt;
+ if (tip->period > np->maxsync_dt)
+ tip->period = np->maxsync_dt;
+ if (tip->offset > np->maxoffs_dt)
+ tip->offset = np->maxoffs_dt;
+ }
+ else {
+ if (tip->period < np->minsync)
+ tip->period = np->minsync;
if (tip->period > np->maxsync)
tip->period = np->maxsync;
+ if (tip->offset > np->maxoffs)
+ tip->offset = np->maxoffs;
}
}
@@ -8500,17 +8534,17 @@ static struct sym_pci_chip sym_pci_dev_table[] = {
FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ}
,
- {PCI_ID_LSI53C1010, 0x00, "1010", 6, 62, 7, 8,
+ {PCI_ID_LSI53C1010, 0x00, "1010-33", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_PCI66|FE_CRC|
FE_C10}
,
- {PCI_ID_LSI53C1010, 0xff, "1010", 6, 62, 7, 8,
+ {PCI_ID_LSI53C1010, 0xff, "1010-33", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC|
FE_C10|FE_U3EN}
,
- {PCI_ID_LSI53C1010_2, 0xff, "1010", 6, 62, 7, 8,
+ {PCI_ID_LSI53C1010_2, 0xff, "1010-66", 6, 31, 7, 8,
FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN|
FE_RAM|FE_RAM8K|FE_64BIT|FE_IO256|FE_NOPM|FE_LEDC|FE_PCI66|FE_CRC|
FE_C10|FE_U3EN}
OpenPOWER on IntegriCloud