diff options
Diffstat (limited to 'sys/dev/usb/usbdi.c')
-rw-r--r-- | sys/dev/usb/usbdi.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 9a571dc..adefde3 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $ */ +/* $NetBSD: usbdi.c,v 1.106 2004/10/24 12:52:40 augustss Exp $ */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> #if defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/kernel.h> #include <sys/device.h> #elif defined(__FreeBSD__) #include <sys/module.h> @@ -62,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> +#include <dev/usb/usb_quirks.h> #if defined(__FreeBSD__) #include "usb_if.h" @@ -1154,6 +1156,86 @@ usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, return (NULL); } + +void +usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter) +{ + const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); + + iter->cur = (const uByte *)cd; + iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); +} + +const usb_descriptor_t * +usb_desc_iter_next(usbd_desc_iter_t *iter) +{ + const usb_descriptor_t *desc; + + if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) { + if (iter->cur != iter->end) + printf("usb_desc_iter_next: bad descriptor\n"); + return NULL; + } + desc = (const usb_descriptor_t *)iter->cur; + if (desc->bLength == 0) { + printf("usb_desc_iter_next: descriptor length = 0\n"); + return NULL; + } + iter->cur += desc->bLength; + if (iter->cur > iter->end) { + printf("usb_desc_iter_next: descriptor length too large\n"); + return NULL; + } + return desc; +} + +usbd_status +usbd_get_string(usbd_device_handle dev, int si, char *buf) +{ + int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; + usb_string_descriptor_t us; + char *s; + int i, n; + u_int16_t c; + usbd_status err; + int size; + + buf[0] = '\0'; + if (si == 0) + return (USBD_INVAL); + if (dev->quirks->uq_flags & UQ_NO_STRINGS) + return (USBD_STALLED); + if (dev->langid == USBD_NOLANG) { + /* Set up default language */ + err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, + &size); + if (err || size < 4) { + DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n")); + 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, &size); + if (err) + return (err); + s = buf; + n = size / 2 - 1; + for (i = 0; i < n; i++) { + c = UGETW(us.bString[i]); + /* Convert from Unicode, handle buggy strings. */ + if ((c & 0xff00) == 0) + *s++ = c; + else if ((c & 0x00ff) == 0 && swap) + *s++ = c >> 8; + else + *s++ = '?'; + } + *s++ = 0; + return (USBD_NORMAL_COMPLETION); +} + #if defined(__FreeBSD__) int usbd_driver_load(module_t mod, int what, void *arg) |