diff options
author | groudier <groudier@FreeBSD.org> | 2000-05-07 09:54:33 +0000 |
---|---|---|
committer | groudier <groudier@FreeBSD.org> | 2000-05-07 09:54:33 +0000 |
commit | 181073b7649a8d8a4b2c5066d83b4b53f89bd245 (patch) | |
tree | c0a6e40cc518dbb3d9c1c2d97477de84a140ee9b /sys/dev/sym | |
parent | 8b4aef321a44df187cd1c4396dbd0ce2dfd4549e (diff) | |
download | FreeBSD-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.h | 2 | ||||
-rw-r--r-- | sys/dev/sym/sym_fw2.h | 23 | ||||
-rw-r--r-- | sys/dev/sym/sym_hipd.c | 108 |
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} |