summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/usbdi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/usbdi.c')
-rw-r--r--sys/dev/usb/usbdi.c84
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)
OpenPOWER on IntegriCloud