>Number: 163064 >Category: kern >Synopsis: [fix][sym]driver tries to nego synch trans with everyone >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Dec 04 18:20:08 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Peter Much >Release: FreeBSD 7.4-STABLE i386 >Organization: n/a >Environment: System: FreeBSD disp.oper.dinoex.org 7.4-STABLE FreeBSD 7.4-STABLE #0: Sun Dec 4 07:09:44 CET 2011 r...@disp.oper.dinoex.org:/usr/src/sys/i386/compile/D1R74V1 i386
Scanner: Mustek MFS-6000CX Controller: Symbios 810a Driver: sym >Description: The scanner gets detected, but is inaccessible. Long time ago, I figured that the sym driver tries to negotiate synchronous transfer, and the scanner seems to not like this at all, and things go into some indefinite state. Then I created a crude hack to avoid this. With Rel. 7 that crude hack seemed to no longer work. (In fact it did still work - the real problem was that "camcontrol" is flawed since Rel. 7, see bin/163053.) So I started to search for the root cause. Q: why does the driver try to negotiate synchronous with everybody, even with devices that have no idea about synch transfers? And, _if_ it does so deliberately, shouldn't there be a quirk to switch it off for devices that misbehave? I finally found the reason: in sym_hipd.c:sym_update_trans() there is a range-check done for the synchronous parameters. This range-check seems to disregard the possibility that there could be *no* synchronous transfer intended, i.e. the parameter could be 0. >How-To-Repeat: Activate the DEBUG_NEGO option in sym_hipd.c > #define DEBUG_FLAGS (0x0200) and watch the negotiation messages. Thats an U160 disk on a 1010-33 controller - I guess thats how it is supposed to work: Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): wide msgin: 1-2-3-1. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): wide msgout: 1-2-3-1. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): sync msgin: 1-3-1-a-7f. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): sync msgout: 1-3-1-a-1f. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): wide msgout: 1-2-3-1. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): wide msgin: 1-2-3-1. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): sync msgout: 1-3-1-a-1f. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): sync msgin: 1-3-1-a-1f. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): ppr msgout: 1-6-4-9-0-3e-1-2. Dec 3 17:49:51 <kern.crit> disp kernel: (probe2:sym0:0:2:0): ppr msgin: 1-6-4-9-0-3e-1-2. Thats a CDrom on a 810a controller - it can do sync transfers, but we see the controller starts negotiation with someway strange parameters: Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgout: 1-3-1-19-0. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgin: 1-3-1-19-0. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgout: 1-3-1-19-8. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgin: 1-3-1-19-8. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgout: 1-3-1-19-8. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgin: 1-3-1-19-8. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgout: 1-3-1-19-8. Dec 4 06:01:41 <kern.crit> disp kernel: (probe35:sym2:0:5:0): sync msgin: 1-3-1-19-8. Thats a scanner - it has no idea about sync transfers, and seems to ignore the messages: Dec 4 02:28:58 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:28:59 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:29:16 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:29:45 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:30:03 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:30:05 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:30:05 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Dec 4 02:30:18 <kern.crit> disp kernel: (probe1:sym2:0:1:0): sync msgout: 1-3-1-19-0. Thats the Mustek scanner - it seems to be pissed off and will not work - while the driver insists and retries: Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): sync msgout: 1-3-1-19-0. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): phase change 6-7 6@01ab17a8 resid=4. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): sync msgout: 1-3-1-19-0. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): phase change 6-7 6@01ab17a8 resid=4. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): sync msgout: 1-3-1-19-0. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): phase change 6-7 6@01ab17a8 resid=4. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): sync msgout: 1-3-1-19-0. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): phase change 6-7 6@01ab17a8 resid=4. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): sync msgout: 1-3-1-19-0. Dec 3 18:24:42 <kern.crit> disp kernel: (probe33:sym2:0:3:0): phase change 6-7 6@01ab17a8 resid=4. ... >Fix: *** sys/dev/sym/sym_hipd.c.orig Thu Dec 1 05:26:17 2011 --- sys/dev/sym/sym_hipd.c Sun Dec 4 06:35:57 2011 *************** *** 8291,8297 **** */ 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. --- 8291,8298 ---- */ 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 != 0) ! tip->period = SYM_SETUP_MIN_SYNC; /* * Scale against actual controller BUS width. *************** *** 8319,8325 **** tip->offset = np->maxoffs_dt; } else { ! if (tip->period < np->minsync) tip->period = np->minsync; if (tip->period > np->maxsync) tip->period = np->maxsync; --- 8320,8326 ---- tip->offset = np->maxoffs_dt; } else { ! if (tip->period < np->minsync && tip->period != 0) tip->period = np->minsync; if (tip->period > np->maxsync) tip->period = np->maxsync; >Release-Note: >Audit-Trail: >Unformatted: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"