Make an iterator abstraction for looping through all descriptors.
Move usb_get_string() and make it public.
This commit is contained in:
parent
c1d4463c05
commit
67f0f483bd
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usb_subr.c,v 1.118 2004/09/13 12:55:49 drochner Exp $ */
|
||||
/* $NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.118 2004/09/13 12:55:49 drochner Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.119 2004/10/23 13:26:33 augustss Exp $");
|
||||
|
||||
#include "opt_usbverbose.h"
|
||||
|
||||
@ -83,7 +83,6 @@ extern int usbdebug;
|
||||
Static usbd_status usbd_set_config(usbd_device_handle, int);
|
||||
Static void usbd_devinfo_vp(usbd_device_handle, char *, size_t, char *,
|
||||
size_t, int);
|
||||
Static char *usbd_get_string(usbd_device_handle, int, char *);
|
||||
Static int usbd_getnewaddr(usbd_bus_handle bus);
|
||||
#if defined(__NetBSD__)
|
||||
Static int usbd_print(void *, const char *);
|
||||
@ -190,51 +189,6 @@ usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid,
|
||||
return (USBD_NORMAL_COMPLETION);
|
||||
}
|
||||
|
||||
char *
|
||||
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;
|
||||
|
||||
if (si == 0)
|
||||
return (0);
|
||||
if (dev->quirks->uq_flags & UQ_NO_STRINGS)
|
||||
return (0);
|
||||
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) {
|
||||
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 (0);
|
||||
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 (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
usbd_trim_spaces(char *p)
|
||||
{
|
||||
@ -267,9 +221,15 @@ usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t lv, char *p, size_t lp,
|
||||
}
|
||||
|
||||
if (usedev) {
|
||||
vendor = usbd_get_string(dev, udd->iManufacturer, v);
|
||||
if (usbd_get_string(dev, udd->iManufacturer, v))
|
||||
vendor = NULL;
|
||||
else
|
||||
vendor = v;
|
||||
usbd_trim_spaces(vendor);
|
||||
product = usbd_get_string(dev, udd->iProduct, p);
|
||||
if (usbd_get_string(dev, udd->iProduct, p))
|
||||
product = NULL;
|
||||
else
|
||||
product = p;
|
||||
usbd_trim_spaces(product);
|
||||
if (vendor && !*vendor)
|
||||
vendor = NULL;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $ */
|
||||
/* $NetBSD: usbdi.c,v 1.105 2004/10/23 13:26:34 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.105 2004/10/23 13:26:34 augustss Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.104 2004/07/17 20:16:13 mycroft Exp $");
|
||||
#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"
|
||||
@ -1141,6 +1142,85 @@ 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 = (uByte *)cd;
|
||||
iter->end = (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 = (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) {
|
||||
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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usbdi.h,v 1.63 2004/04/23 17:25:26 itojun Exp $ */
|
||||
/* $NetBSD: usbdi.h,v 1.64 2004/10/23 13:26:34 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -172,6 +172,16 @@ usbd_status usbd_reload_device_desc(usbd_device_handle);
|
||||
|
||||
int usbd_ratecheck(struct timeval *last);
|
||||
|
||||
usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf);
|
||||
|
||||
/* An iterator for descriptors. */
|
||||
typedef struct {
|
||||
const uByte *cur;
|
||||
const uByte *end;
|
||||
} usbd_desc_iter_t;
|
||||
void usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter);
|
||||
const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *iter);
|
||||
|
||||
/*
|
||||
* The usb_task structs form a queue of things to run in the USB event
|
||||
* thread. Normally this is just device discovery when a connect/disconnect
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usbdi_util.c,v 1.40 2002/07/11 21:14:36 augustss Exp $ */
|
||||
/* $NetBSD: usbdi_util.c,v 1.41 2004/10/23 13:26:34 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi_util.c,v 1.14 1999/11/17 22:33:50 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.40 2002/07/11 21:14:36 augustss Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.41 2004/10/23 13:26:34 augustss Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -365,8 +365,8 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc)
|
||||
char *p, *end;
|
||||
|
||||
if (idesc == NULL)
|
||||
return (0);
|
||||
usbd_interface2device_handle(ifc, &dev);
|
||||
return (NULL);
|
||||
usbd_interface2device_handle(ifc, &dev);
|
||||
cdesc = usbd_get_config_descriptor(dev);
|
||||
|
||||
p = (char *)idesc + idesc->bLength;
|
||||
@ -379,7 +379,7 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc)
|
||||
if (hd->bDescriptorType == UDESC_INTERFACE)
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
usbd_status
|
||||
@ -484,20 +484,19 @@ usb_detach_wakeup(device_ptr_t dv)
|
||||
wakeup(dv);
|
||||
}
|
||||
|
||||
usb_descriptor_t *
|
||||
usb_find_desc(usbd_device_handle dev, int type)
|
||||
const usb_descriptor_t *
|
||||
usb_find_desc(usbd_device_handle dev, int type, int subtype)
|
||||
{
|
||||
usb_descriptor_t *desc;
|
||||
usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
|
||||
uByte *p = (uByte *)cd;
|
||||
uByte *end = p + UGETW(cd->wTotalLength);
|
||||
usbd_desc_iter_t iter;
|
||||
const usb_descriptor_t *desc;
|
||||
|
||||
while (p < end) {
|
||||
desc = (usb_descriptor_t *)p;
|
||||
if (desc->bDescriptorType == type)
|
||||
return (desc);
|
||||
p += desc->bLength;
|
||||
usb_desc_iter_init(dev, &iter);
|
||||
for (;;) {
|
||||
desc = usb_desc_iter_next(&iter);
|
||||
if (!desc || (desc->bDescriptorType == type &&
|
||||
(subtype == USBD_SUBTYPE_ANY ||
|
||||
subtype == desc->bDescriptorSubtype)))
|
||||
break;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
return desc;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: usbdi_util.h,v 1.29 2004/06/23 02:30:52 mycroft Exp $ */
|
||||
/* $NetBSD: usbdi_util.h,v 1.30 2004/10/23 13:26:34 augustss Exp $ */
|
||||
/* $FreeBSD: src/sys/dev/usb/usbdi_util.h,v 1.9 1999/11/17 22:33:50 n_hibma Exp $ */
|
||||
|
||||
/*
|
||||
@ -85,4 +85,7 @@ usbd_status usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
|
||||
void usb_detach_wait(device_ptr_t);
|
||||
void usb_detach_wakeup(device_ptr_t);
|
||||
|
||||
usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type);
|
||||
const usb_descriptor_t *usb_find_desc(usbd_device_handle dev, int type,
|
||||
int subtype);
|
||||
#define USBD_SUBTYPE_ANY (~0)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user