diff options
author | groudier <groudier@FreeBSD.org> | 2001-02-11 15:38:06 +0000 |
---|---|---|
committer | groudier <groudier@FreeBSD.org> | 2001-02-11 15:38:06 +0000 |
commit | b2cea7549ca4d8add5440571d1639082dd250f9b (patch) | |
tree | b0eb45fe9a80be856b474d7ae72db2977d185e31 /sys/dev/sym/sym_hipd.c | |
parent | 712f94325cdd944faab47817a869d99e4959db88 (diff) | |
download | FreeBSD-src-b2cea7549ca4d8add5440571d1639082dd250f9b.zip FreeBSD-src-b2cea7549ca4d8add5440571d1639082dd250f9b.tar.gz |
Fix:
- Missing cpu_to_scr() added (endian-ness).
Improvement (fix|workaroung??):
- Blindly firing a PPR can lead to some messy situations due to
various causes or misfeatures, for example:
* The 53C1010-[33|66] supports offset 62 in DT mode, but only
offset 31 in ST mode. As a result, a PPR(DT, offset 62)
responded with PPR(ST, any offset > 31) must be rejected.
* A device that doesn't know about PPR should reject it, but
may also be confused by this message.
When a PPR encounters problems, the driver now patches the goal
transfer settings for legacy negotiations to be performed later
with the offending target. This give a chance for bad situations
to be fixed automagically.
Diffstat (limited to 'sys/dev/sym/sym_hipd.c')
-rw-r--r-- | sys/dev/sym/sym_hipd.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c index bd9d9db..04b371b 100644 --- a/sys/dev/sym/sym_hipd.c +++ b/sys/dev/sym/sym_hipd.c @@ -5222,7 +5222,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) target = (INB (nc_sdid) & 0xf); tp = &np->target[target]; - np->abrt_tbl.addr = vtobus(np->abrt_msg); + np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg)); /* * If the target is to be reset, prepare a @@ -5893,6 +5893,15 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) }; /* + * get requested values. + */ + chg = 0; + per = np->msgin[3]; + ofs = np->msgin[5]; + wide = np->msgin[6]; + dt = np->msgin[7] & PPR_OPT_DT; + + /* * request or answer ? */ if (INB (HS_PRT) == HS_NEGOTIATE) { @@ -5903,15 +5912,6 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) } /* - * get requested values. - */ - chg = 0; - per = np->msgin[3]; - ofs = np->msgin[5]; - wide = np->msgin[6]; - dt = np->msgin[7] & PPR_OPT_DT; - - /* * check values against our limits. */ if (wide > np->maxwide) @@ -6004,6 +6004,17 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) reject_it: sym_setpprot (np, cp, 0, 0, 0, 0, 0, 0); OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + /* + * If it was a device response that should result in + * ST, we may want to try a legacy negotiation later. + */ + if (!req && !dt) { + tp->tinfo.goal.options = 0; + tp->tinfo.goal.width = wide; + tp->tinfo.goal.period = per; + tp->tinfo.goal.offset = ofs; + } + return; } /* @@ -6116,6 +6127,9 @@ reject_it: * * Called when a negotiation does not succeed either * on rejection or on protocol error. + * + * If it was a PPR that made problems, we may want to + * try a legacy negotiation later. */ static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) { @@ -6125,7 +6139,15 @@ static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) */ switch (cp->nego_status) { case NS_PPR: +#if 0 sym_setpprot (np, cp, 0, 0, 0, 0, 0, 0); +#else + tp->tinfo.goal.options = 0; + if (tp->tinfo.goal.period < np->minsync) + tp->tinfo.goal.period = np->minsync; + if (tp->tinfo.goal.offset > np->maxoffs) + tp->tinfo.goal.offset = np->maxoffs; +#endif break; case NS_SYNC: sym_setsync (np, cp, 0, 0, 0, 0); |