diff options
author | le <le@FreeBSD.org> | 2004-06-26 10:35:10 +0000 |
---|---|---|
committer | le <le@FreeBSD.org> | 2004-06-26 10:35:10 +0000 |
commit | 1255e60c4d80338ad1bef8f82845886b69b802bf (patch) | |
tree | 570cc786c69ffbcba2d2ad69188c6cb886c21324 /sys/dev/usb/usb_subr.c | |
parent | 1c3c0bb4350c49fb8582a9327f875a5bbf17dc8b (diff) | |
download | FreeBSD-src-1255e60c4d80338ad1bef8f82845886b69b802bf.zip FreeBSD-src-1255e60c4d80338ad1bef8f82845886b69b802bf.tar.gz |
MFNetBSD.
uhid.c (1.61), author: jdolecek
add support for USB_GET_DEVICEINFO and USB_GET_STRING_DESC ioctls,
with same meaning as for ugen(4)
usbdi_util.h (1.29), usb_quirks.c (1.50), uhid.c (1.62),
ugen.c (1.68), usb_subr.c (1.114) author: mycroft
Yes, some devices return incorrect lengths in their string
descriptors. Rather than losing, do what Windows does: just
request the maximum size, and allow a shorter response. Obsoletes
the need for UQ_NO_STRINGS, and therefore these "quirks" are removed.
usb_subr.c (1.116), author: mycroft
In the "seemed like a good idea until I found the fatal flaw"
department... Attempting to read a maximum-size string descriptor
causes my kue device to go completely apeshit. So, go back to the
original method, but allow the device to return a shorter string than
it claimed.
Obtained from: NetBSD
Diffstat (limited to 'sys/dev/usb/usb_subr.c')
-rw-r--r-- | sys/dev/usb/usb_subr.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 1e27987..90984e9 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -4,6 +4,9 @@ * $NetBSD: usb_subr.c,v 1.102 2003/01/01 16:21:50 augustss Exp $ * $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $ * $NetBSD: usb_subr.c,v 1.111 2004/03/15 10:35:04 augustss Exp $ + * $NetBSD: usb_subr.c,v 1.114 2004/06/23 02:30:52 mycroft Exp $ + * $NetBSD: usb_subr.c,v 1.115 2004/06/23 05:23:19 mycroft Exp $ + * $NetBSD: usb_subr.c,v 1.116 2004/06/23 06:27:54 mycroft Exp $ */ #include <sys/cdefs.h> @@ -157,7 +160,7 @@ usbd_errstr(usbd_status err) usbd_status usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid, - usb_string_descriptor_t *sdesc) + usb_string_descriptor_t *sdesc, int *sizep) { usb_device_request_t req; usbd_status err; @@ -173,11 +176,22 @@ usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid, if (err) return (err); - if (actlen < 1) + if (actlen < 2) return (USBD_SHORT_XFER); USETW(req.wLength, sdesc->bLength); /* the whole string */ - return (usbd_do_request(dev, &req, sdesc)); + err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, + &actlen, USBD_DEFAULT_TIMEOUT); + if (err) + return (err); + + if (actlen != sdesc->bLength) { + DPRINTFN(-1, ("usbd_get_string_desc: expected %d, got %d\n", + sdesc->bLength, actlen)); + } + + *sizep = actlen; + return (USBD_NORMAL_COMPLETION); } char * @@ -189,6 +203,7 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf) int i, n; u_int16_t c; usbd_status err; + int size; if (si == 0) return (0); @@ -196,19 +211,20 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf) return (0); if (dev->langid == USBD_NOLANG) { /* Set up default language */ - err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us); - if (err || us.bLength < 4) { + err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, + &size); + if (err || size < 4) { dev->langid = 0; /* Well, just pick something then */ } else { /* Pick the first language as the default. */ dev->langid = UGETW(us.bString[0]); } } - err = usbd_get_string_desc(dev, si, dev->langid, &us); + err = usbd_get_string_desc(dev, si, dev->langid, &us, &size); if (err) return (0); s = buf; - n = us.bLength / 2 - 1; + n = size / 2 - 1; for (i = 0; i < n; i++) { c = UGETW(us.bString[i]); /* Convert from Unicode, handle buggy strings. */ |