Subject: kern/25959: umct(4) fails to locate the bulkin endpoint descriptor
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <rumble@ephemeral.org>
List: netbsd-bugs
Date: 06/17/2004 20:20:41
>Number: 25959
>Category: kern
>Synopsis: umct(4) fails to utilise the proper endpoint descriptor
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jun 18 00:22:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator: Steve Rumble
>Release: NetBSD 2.0_BETA
>Organization:
>Environment:
System: NetBSD t23.ephemeral.org 2.0_BETA NetBSD 2.0_BETA (T23) #10: Sun Jun 13 17:53:30 EDT 2004 rumble@t23.ephemeral.org:/usr/src/sys/arch/i386/compile/T23 i386
Architecture: i386
Machine: i386
>Description:
umct(4) has a workaround for a hardware bug that tags the bulkin
interface descriptor as an interrupt descriptor. In order to
differentiate the interrupt descriptor from the actual bulkin
one, it simply assumes a certain order during enumeration. This
fails on my belkin f5u109 adapter and produces the odd behaviour
of accomodating successful transmits, but no receive capability.
>How-To-Repeat:
Apparently the majority of devices follow the expected
enumeration sequence and do not run into this issue. If your
MCT-based usb serial adapter can transmit, but not receive, this
could be the problem.
>Fix:
The attached patch uses FreeBSD's logic to identify the interrupt
descriptor based on its packet size. I'm not knowledgable enough
about USB to determine if there is a better method, nor whether
one may ever encounter an interrupt descriptor that doesn't have
a 0x2 wMaxPacketSize.
This patch should apply cleanly to -current and 2.0 (and perhaps
earlier code). If committed, a pullup to 2-0 and perhaps 1-6
would be in order.
Index: umct.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/umct.c,v
retrieving revision 1.12
diff -u -r1.12 umct.c
--- umct.c 10 Nov 2003 08:58:39 -0000 1.12
+++ umct.c 7 Jun 2004 01:07:14 -0000
@@ -180,7 +180,7 @@
char devinfo[1024];
char *devname = USBDEVNAME(sc->sc_dev);
usbd_status err;
- int i, found;
+ int i;
struct ucom_attach_args uca;
usbd_devinfo(dev, 0, devinfo);
@@ -230,7 +230,6 @@
id = usbd_get_interface_descriptor(sc->sc_iface);
sc->sc_iface_number = id->bInterfaceNumber;
- found = 0;
for (i = 0; i < id->bNumEndpoints; i++) {
ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
@@ -241,11 +240,15 @@
USB_ATTACH_ERROR_RETURN;
}
+ /*
+ * The Bulkin endpoint is marked as an interrupt. Since
+ * we can't rely on the endpoint descriptor order, we'll
+ * check the wMaxPacketSize field to differentiate.
+ */
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT &&
- found == 0) {
+ UGETW(ed->wMaxPacketSize) != 0x2) {
uca.bulkin = ed->bEndpointAddress;
- found = 1;
} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
uca.bulkout = ed->bEndpointAddress;
>Release-Note:
>Audit-Trail:
>Unformatted: