summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usb_subr.c
diff options
context:
space:
mode:
authorle <le@FreeBSD.org>2004-06-26 10:35:10 +0000
committerle <le@FreeBSD.org>2004-06-26 10:35:10 +0000
commit1255e60c4d80338ad1bef8f82845886b69b802bf (patch)
tree570cc786c69ffbcba2d2ad69188c6cb886c21324 /sys/dev/usb/usb_subr.c
parent1c3c0bb4350c49fb8582a9327f875a5bbf17dc8b (diff)
downloadFreeBSD-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.c30
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. */
OpenPOWER on IntegriCloud