Subject: Re: Incompatibilities between <=3.0 & current: USB_DEVICEINFO ioctl
To: Stephan Thesing <thesing@cs.uni-sb.de>
From: Pavel Cahyna <pavel@NetBSD.org>
List: current-users
Date: 08/29/2006 14:00:26
--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Tue, Mar 21, 2006 at 10:04:02PM +0100, Stephan Thesing wrote:
> attached is a try for a patch which
> - adds compat ioctls with the right numbers from <=3.0 for
> USB_GET_DEVICEINFO and USB_DEVICEINFO named
> USB_GET_DEVICEINFO_OLD and USB_DEVICEINFO_OLD
> - adds structs usb_device_info_old and usb_event_old, which are
> compatible with the usb_device_info and usb_event structs form <=3.0
> - adds code to restore the old string handling for the compat ioctls
> (which is
> quite ugly)
> - adds compat code in `usbread' that transforms results into the
> usb_event_old
> struct if the read size was for that struct (to handle event reads from
> /dev/usb)
>
> This seems to work (digikam now works both with a -current compile libusb
> and a
> 3.0 one, reads from /dev/usb seem to work as well).
>
> As this patch is the result of hacking after a long day of work, it's
> probably not as nice at it could be. One thing that should probably be
> changed is making the compat code dependend on COMPAT_{16,20,30} being
> defined...
Hello,
thanks for your patch, I think it should be integrated before the 4.0 release.
Some comments:
> RCS file: /cvsroot/src/sys/dev/usb/usb.c,v
> retrieving revision 1.85
> diff -u -r1.85 usb.c
> --- sys/dev/usb/usb.c 1 Mar 2006 12:38:13 -0000 1.85
> +++ sys/dev/usb/usb.c 21 Mar 2006 20:30:30 -0000
> @@ -842,3 +883,56 @@
>
> return (0);
> }
> +
> +Static void
> +usb_copy_old_devinfo(struct usb_device_info_old *uo, struct usb_device_info *ue)
> +{
> + unsigned char *p, *q;
> + int n;
> +
> + uo->udi_bus = ue->udi_bus;
> + uo->udi_addr = ue->udi_addr;
> + uo->udi_cookie = ue->udi_cookie;
> + for (p=(unsigned char *)ue->udi_product,
> + q=(unsigned char *)uo->udi_product; *p; p++) {
> + if ((int)*p<0x80)
> + *q++=*p;
> + else {
> + *q++='?';
> + if ((((int)*p)&0xe0)==0xe0)
> + p++;
> + p++;
> + }
> + }
> +
> + for (p=ue->udi_vendor,
> + q=uo->udi_vendor; *p; p++) {
> + if (*p<0x80)
> + *q++=*p;
> + else {
> + *q++='?';
> + p++;
> + if ((*p&0xe0)==0xe0)
> + p++;
> + }
> + }
I miss protection against overruning the buffer in those two cycles.
> + bcopy(ue->udi_release,
> + uo->udi_release, sizeof(uo->udi_release));
> +
> + uo->udi_productNo = ue->udi_productNo;
> + uo->udi_vendorNo = ue->udi_vendorNo;
> + uo->udi_releaseNo = ue->udi_releaseNo;
> + uo->udi_class = ue->udi_class;
> + uo->udi_subclass = ue->udi_subclass;
> + uo->udi_protocol = ue->udi_protocol;
> + uo->udi_config = ue->udi_config;
> + uo->udi_speed = ue->udi_speed;
> + uo->udi_power = ue->udi_power;
> + uo->udi_nports = ue->udi_nports;
> +
> + for (n=0; n<USB_MAX_DEVNAMES; n++)
> + bcopy(uo->udi_devnames[n],
> + ue->udi_devnames[n], USB_MAX_DEVNAMELEN);
> + bcopy(uo->udi_ports, ue->udi_ports, sizeof(uo->udi_ports));
I think you swapped uo and ue in those two calls to bcopy. I would constify ue
to prevent such mistakes and use memcpy instead.
> diff -u -r1.110 usbdi.c
> --- sys/dev/usb/usbdi.c 24 Dec 2005 20:27:52 -0000 1.110
> +++ sys/dev/usb/usbdi.c 21 Mar 2006 19:37:05 -0000
> @@ -1176,7 +1176,7 @@
> }
>
> usbd_status
> -usbd_get_string(usbd_device_handle dev, int si, char *buf)
> +usbd_get_string(usbd_device_handle dev, int si, char *buf, int unicode)
> {
> int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
> usb_string_descriptor_t us;
> @@ -1213,7 +1213,9 @@
> if (swap)
> c = (c >> 8) | (c << 8);
> /* Encode (16-bit) Unicode as UTF8. */
> - if (c < 0x0080) {
> + if (!unicode)
> + *s++=(c<0x80)?c:'?';
> + else if (c < 0x0080) {
> *s++ = c;
> } else if (c < 0x0800) {
> *s++ = 0xc0 | (c >> 6);
I've put buffer overrun protection here (not sure if it is really necessary).
An updated diff is attached.
Pavel
--MGYHOYXEY6WxJCY8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="usbnew.diff"
Index: ugen.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ugen.c,v
retrieving revision 1.84
diff -u -r1.84 ugen.c
--- ugen.c 24 Jul 2006 14:24:50 -0000 1.84
+++ ugen.c 29 Aug 2006 13:57:54 -0000
@@ -1800,10 +1800,16 @@
free(ptr, M_TEMP);
return (error);
}
+
case USB_GET_DEVICEINFO:
usbd_fill_deviceinfo(sc->sc_udev,
(struct usb_device_info *)addr, 1);
break;
+ case USB_GET_DEVICEINFO_OLD:
+ usbd_fill_deviceinfo_old(sc->sc_udev,
+ (struct usb_device_info_old *)addr, 1);
+
+ break;
default:
return (EINVAL);
}
Index: uhid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhid.c,v
retrieving revision 1.69
diff -u -r1.69 uhid.c
--- uhid.c 28 Mar 2006 17:38:35 -0000 1.69
+++ uhid.c 29 Aug 2006 13:57:54 -0000
@@ -532,7 +532,13 @@
case USB_GET_DEVICEINFO:
usbd_fill_deviceinfo(sc->sc_hdev.sc_parent->sc_udev,
- (struct usb_device_info *)addr, 1);
+ (struct usb_device_info *)addr, 1);
+ break;
+
+ case USB_GET_DEVICEINFO_OLD:
+ usbd_fill_deviceinfo_old(sc->sc_hdev.sc_parent->sc_udev,
+ (struct usb_device_info_old *)addr, 1);
+
break;
case USB_GET_STRING_DESC:
Index: usb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb.c,v
retrieving revision 1.87
diff -u -r1.87 usb.c
--- usb.c 9 Jun 2006 21:33:42 -0000 1.87
+++ usb.c 29 Aug 2006 13:57:54 -0000
@@ -142,6 +142,8 @@
Static int usb_get_next_event(struct usb_event *);
+Static void usb_copy_old_devinfo(struct usb_device_info_old *, const struct usb_device_info *);
+
Static const char *usbrev_str[] = USBREV_STR;
USB_DECLARE_DRIVER(usb);
@@ -408,14 +410,28 @@
int
usbread(dev_t dev, struct uio *uio, int flag)
{
- struct usb_event *ue = usb_alloc_event();
- int s, error, n;
+ struct usb_event *ue;
+ struct usb_event_old *ueo;
+ int s, error, n, useold;
if (minor(dev) != USB_DEV_MINOR)
return (ENXIO);
- if (uio->uio_resid != sizeof(struct usb_event))
+ useold = 0;
+ /* XXXGCC */
+ ueo = NULL;
+ switch (uio->uio_resid) {
+ case sizeof(struct usb_event_old):
+ ueo = malloc(sizeof(struct usb_event_old), M_USBDEV,
+ M_WAITOK|M_ZERO);
+ useold = 1;
+ /* FALLTHRU */
+ case sizeof(struct usb_event):
+ ue = usb_alloc_event();
+ break;
+ default:
return (EINVAL);
+ }
error = 0;
s = splusb();
@@ -432,9 +448,40 @@
break;
}
splx(s);
- if (!error)
- error = uiomove((void *)ue, uio->uio_resid, uio);
+ if (!error) {
+ if (useold) { /* copy fields to old struct */
+ ueo->ue_type = ue->ue_type;
+ memcpy(&ueo->ue_time, &ue->ue_time,
+ sizeof(struct timespec));
+ switch (ue->ue_type) {
+ case USB_EVENT_DEVICE_ATTACH:
+ case USB_EVENT_DEVICE_DETACH:
+ usb_copy_old_devinfo(&ueo->u.ue_device, &ue->u.ue_device);
+ break;
+
+ case USB_EVENT_CTRLR_ATTACH:
+ case USB_EVENT_CTRLR_DETACH:
+ ueo->u.ue_ctrlr.ue_bus=ue->u.ue_ctrlr.ue_bus;
+ break;
+
+ case USB_EVENT_DRIVER_ATTACH:
+ case USB_EVENT_DRIVER_DETACH:
+ ueo->u.ue_driver.ue_cookie=ue->u.ue_driver.ue_cookie;
+ memcpy(ueo->u.ue_driver.ue_devname,
+ ue->u.ue_driver.ue_devname,
+ sizeof(ue->u.ue_driver.ue_devname));
+ break;
+ default:
+ ;
+ }
+
+ error = uiomove((void *)ueo, uio->uio_resid, uio);
+ } else
+ error = uiomove((void *)ue, uio->uio_resid, uio);
+ }
usb_free_event(ue);
+ if (useold)
+ free(ueo, M_USBDEV);
return (error);
}
@@ -554,17 +601,26 @@
}
case USB_DEVICEINFO:
+ case USB_DEVICEINFO_OLD:
{
struct usb_device_info *di = (void *)data;
- int addr = di->udi_addr;
+ struct usb_device_info_old *dio = (void *)data;
+ int addr;
usbd_device_handle dev;
+ if (cmd == USB_DEVICEINFO)
+ addr=di->udi_addr;
+ else
+ addr=dio->udi_addr;
if (addr < 1 || addr >= USB_MAX_DEVICES)
return (EINVAL);
dev = sc->sc_bus->devices[addr];
if (dev == NULL)
return (ENXIO);
- usbd_fill_deviceinfo(dev, di, 1);
+ if (cmd == USB_DEVICEINFO)
+ usbd_fill_deviceinfo(dev, di, 1);
+ else
+ usbd_fill_deviceinfo_old(dev, dio, 1);
break;
}
@@ -860,3 +916,60 @@
return (0);
}
+
+Static void
+usb_copy_old_devinfo(struct usb_device_info_old *uo,
+ const struct usb_device_info *ue)
+{
+ const unsigned char *p;
+ unsigned char *q;
+ int i, n;
+
+ uo->udi_bus = ue->udi_bus;
+ uo->udi_addr = ue->udi_addr;
+ uo->udi_cookie = ue->udi_cookie;
+ for (i = 0, p = (const unsigned char *)ue->udi_product,
+ q = (unsigned char *)uo->udi_product;
+ *p && i < USB_MAX_STRING_LEN - 1; p++) {
+ if (*p < 0x80)
+ q[i++] = *p;
+ else {
+ q[i++] = '?';
+ if ((*p & 0xe0) == 0xe0)
+ p++;
+ p++;
+ }
+ }
+ q[i] = 0;
+
+ for (i = 0, p = ue->udi_vendor, q = uo->udi_vendor;
+ *p && i < USB_MAX_STRING_LEN - 1; p++) {
+ if (* p < 0x80)
+ q[i++] = *p;
+ else {
+ q[i++] = '?';
+ p++;
+ if ((*p & 0xe0) == 0xe0)
+ p++;
+ }
+ }
+ q[i] = 0;
+
+ memcpy(uo->udi_release, ue->udi_release, sizeof(uo->udi_release));
+
+ uo->udi_productNo = ue->udi_productNo;
+ uo->udi_vendorNo = ue->udi_vendorNo;
+ uo->udi_releaseNo = ue->udi_releaseNo;
+ uo->udi_class = ue->udi_class;
+ uo->udi_subclass = ue->udi_subclass;
+ uo->udi_protocol = ue->udi_protocol;
+ uo->udi_config = ue->udi_config;
+ uo->udi_speed = ue->udi_speed;
+ uo->udi_power = ue->udi_power;
+ uo->udi_nports = ue->udi_nports;
+
+ for (n=0; n<USB_MAX_DEVNAMES; n++)
+ memcpy(uo->udi_devnames[n],
+ ue->udi_devnames[n], USB_MAX_DEVNAMELEN);
+ memcpy(uo->udi_ports, ue->udi_ports, sizeof(uo->udi_ports));
+}
Index: usb.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb.h,v
retrieving revision 1.74
diff -u -r1.74 usb.h
--- usb.h 24 Jul 2006 14:24:50 -0000 1.74
+++ usb.h 29 Aug 2006 13:57:55 -0000
@@ -621,6 +621,28 @@
#define USB_PORT_DISABLED 0xfc
};
+/* <=3.0 had this layout of the structure */
+struct usb_device_info_old {
+ u_int8_t udi_bus;
+ u_int8_t udi_addr; /* device address */
+ usb_event_cookie_t udi_cookie;
+ char udi_product[USB_MAX_STRING_LEN];
+ char udi_vendor[USB_MAX_STRING_LEN];
+ char udi_release[8];
+ u_int16_t udi_productNo;
+ u_int16_t udi_vendorNo;
+ u_int16_t udi_releaseNo;
+ u_int8_t udi_class;
+ u_int8_t udi_subclass;
+ u_int8_t udi_protocol;
+ u_int8_t udi_config;
+ u_int8_t udi_speed;
+ int udi_power; /* power consumption in mA, 0 if selfpowered */
+ int udi_nports;
+ char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
+ u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */
+};
+
struct usb_ctl_report {
int ucr_report;
u_char ucr_data[1024]; /* filled data size will vary */
@@ -659,11 +681,29 @@
} u;
};
+/* old <=3.0 compat event */
+struct usb_event_old {
+ int ue_type;
+ struct timespec ue_time;
+ union {
+ struct {
+ int ue_bus;
+ } ue_ctrlr;
+ struct usb_device_info_old ue_device;
+ struct {
+ usb_event_cookie_t ue_cookie;
+ char ue_devname[16];
+ } ue_driver;
+ } u;
+};
+
+
/* USB controller */
#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request)
#define USB_SETDEBUG _IOW ('U', 2, int)
#define USB_DISCOVER _IO ('U', 3)
#define USB_DEVICEINFO _IOWR('U', 4, struct usb_device_info)
+#define USB_DEVICEINFO_OLD _IOWR('U', 4, struct usb_device_info_old)
#define USB_DEVICESTATS _IOR ('U', 5, struct usb_device_stats)
/* Generic HID device */
@@ -687,6 +727,7 @@
#define USB_GET_STRING_DESC _IOWR('U', 110, struct usb_string_desc)
#define USB_DO_REQUEST _IOWR('U', 111, struct usb_ctl_request)
#define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info)
+#define USB_GET_DEVICEINFO_OLD _IOR ('U', 112, struct usb_device_info_old)
#define USB_SET_SHORT_XFER _IOW ('U', 113, int)
#define USB_SET_TIMEOUT _IOW ('U', 114, int)
#define USB_SET_BULK_RA _IOW ('U', 115, int)
Index: usb_subr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.135
diff -u -r1.135 usb_subr.c
--- usb_subr.c 11 Jun 2006 16:00:08 -0000 1.135
+++ usb_subr.c 29 Aug 2006 13:57:55 -0000
@@ -83,8 +83,9 @@
Static usbd_status usbd_set_config(usbd_device_handle, int);
Static void usbd_devinfo(usbd_device_handle, int, char *, size_t);
Static void usbd_devinfo_vp(usbd_device_handle dev,
- char v[USB_MAX_ENCODED_STRING_LEN],
- char p[USB_MAX_ENCODED_STRING_LEN], int usedev);
+ char *v,
+ char *p, int usedev,
+ int useencoded );
Static int usbd_getnewaddr(usbd_bus_handle bus);
#if defined(__NetBSD__)
Static int usbd_print(void *, const char *);
@@ -208,8 +209,8 @@
}
Static void
-usbd_devinfo_vp(usbd_device_handle dev, char v[USB_MAX_ENCODED_STRING_LEN],
- char p[USB_MAX_ENCODED_STRING_LEN], int usedev)
+usbd_devinfo_vp(usbd_device_handle dev, char *v,
+ char *p, int usedev, int useencoded)
{
usb_device_descriptor_t *udd = &dev->ddesc;
#ifdef USBVERBOSE
@@ -221,10 +222,10 @@
return;
if (usedev) {
- if (usbd_get_string(dev, udd->iManufacturer, v) ==
+ if (usbd_get_string(dev, udd->iManufacturer, v, useencoded) ==
USBD_NORMAL_COMPLETION)
usbd_trim_spaces(v);
- if (usbd_get_string(dev, udd->iProduct, p) ==
+ if (usbd_get_string(dev, udd->iProduct, p, useencoded) ==
USBD_NORMAL_COMPLETION)
usbd_trim_spaces(p);
}
@@ -273,7 +274,7 @@
ep = cp + l;
- usbd_devinfo_vp(dev, vendor, product, 1);
+ usbd_devinfo_vp(dev, vendor, product, 1, 1);
cp += snprintf(cp, ep - cp, "%s %s", vendor, product);
if (showclass)
cp += snprintf(cp, ep - cp, ", class %d/%d",
@@ -1254,13 +1255,13 @@
di->udi_bus = USBDEVUNIT(dev->bus->bdev);
di->udi_addr = dev->address;
di->udi_cookie = dev->cookie;
- usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev);
+ usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 1);
usbd_printBCD(di->udi_release, sizeof(di->udi_release),
UGETW(dev->ddesc.bcdDevice));
di->udi_serial[0] = 0;
if (usedev)
(void)usbd_get_string(dev, dev->ddesc.iSerialNumber,
- di->udi_serial);
+ di->udi_serial, 1);
di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
di->udi_productNo = UGETW(dev->ddesc.idProduct);
di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
@@ -1311,6 +1312,70 @@
}
void
+usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di,
+ int usedev)
+{
+ struct usbd_port *p;
+ int i, err, s;
+
+ di->udi_bus = USBDEVUNIT(dev->bus->bdev);
+ di->udi_addr = dev->address;
+ di->udi_cookie = dev->cookie;
+ usbd_devinfo_vp(dev, di->udi_vendor, di->udi_product, usedev, 0);
+ usbd_printBCD(di->udi_release, sizeof(di->udi_release),
+ UGETW(dev->ddesc.bcdDevice));
+ di->udi_vendorNo = UGETW(dev->ddesc.idVendor);
+ di->udi_productNo = UGETW(dev->ddesc.idProduct);
+ di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice);
+ di->udi_class = dev->ddesc.bDeviceClass;
+ di->udi_subclass = dev->ddesc.bDeviceSubClass;
+ di->udi_protocol = dev->ddesc.bDeviceProtocol;
+ di->udi_config = dev->config;
+ di->udi_power = dev->self_powered ? 0 : dev->power;
+ di->udi_speed = dev->speed;
+
+ if (dev->subdevs != NULL) {
+ for (i = 0; dev->subdevs[i] &&
+ i < USB_MAX_DEVNAMES; i++) {
+ strncpy(di->udi_devnames[i], USBDEVPTRNAME(dev->subdevs[i]),
+ USB_MAX_DEVNAMELEN);
+ di->udi_devnames[i][USB_MAX_DEVNAMELEN-1] = '\0';
+ }
+ } else {
+ i = 0;
+ }
+ for (/*i is set */; i < USB_MAX_DEVNAMES; i++)
+ di->udi_devnames[i][0] = 0; /* empty */
+
+ if (dev->hub) {
+ for (i = 0;
+ i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) &&
+ i < dev->hub->hubdesc.bNbrPorts;
+ i++) {
+ p = &dev->hub->ports[i];
+ if (p->device)
+ err = p->device->address;
+ else {
+ s = UGETW(p->status.wPortStatus);
+ if (s & UPS_PORT_ENABLED)
+ err = USB_PORT_ENABLED;
+ else if (s & UPS_SUSPEND)
+ err = USB_PORT_SUSPENDED;
+ else if (s & UPS_PORT_POWER)
+ err = USB_PORT_POWERED;
+ else
+ err = USB_PORT_DISABLED;
+ }
+ di->udi_ports[i] = err;
+ }
+ di->udi_nports = dev->hub->hubdesc.bNbrPorts;
+ } else
+ di->udi_nports = 0;
+}
+
+
+
+void
usb_free_device(usbd_device_handle dev)
{
int ifcidx, nifc;
Index: usbdi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdi.c,v
retrieving revision 1.110
diff -u -r1.110 usbdi.c
--- usbdi.c 24 Dec 2005 20:27:52 -0000 1.110
+++ usbdi.c 29 Aug 2006 13:57:55 -0000
@@ -1176,12 +1176,12 @@
}
usbd_status
-usbd_get_string(usbd_device_handle dev, int si, char *buf)
+usbd_get_string(usbd_device_handle dev, int si, char *buf, int unicode)
{
int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
usb_string_descriptor_t us;
char *s;
- int i, n;
+ int i, j, n;
u_int16_t c;
usbd_status err;
int size;
@@ -1208,23 +1208,34 @@
return (err);
s = buf;
n = size / 2 - 1;
- for (i = 0; i < n; i++) {
- c = UGETW(us.bString[i]);
- if (swap)
- c = (c >> 8) | (c << 8);
- /* Encode (16-bit) Unicode as UTF8. */
- if (c < 0x0080) {
- *s++ = c;
- } else if (c < 0x0800) {
- *s++ = 0xc0 | (c >> 6);
- *s++ = 0x80 | (c & 0x3f);
- } else {
- *s++ = 0xe0 | (c >> 12);
- *s++ = 0x80 | ((c >> 6) & 0x3f);
- *s++ = 0x80 | (c & 0x3f);
+ if (unicode) {
+ for (i = 0; i < n; i++) {
+ c = UGETW(us.bString[i]);
+ if (swap)
+ c = (c >> 8) | (c << 8);
+ if (c < 0x0080) {
+ *s++ = c;
+ } else if (c < 0x0800) {
+ *s++ = 0xc0 | (c >> 6);
+ *s++ = 0x80 | (c & 0x3f);
+ } else {
+ *s++ = 0xe0 | (c >> 12);
+ *s++ = 0x80 | ((c >> 6) & 0x3f);
+ *s++ = 0x80 | (c & 0x3f);
+ }
+ }
+ *s++ = 0;
+ }
+ else {
+ for (i = j = 0; i < n && j < USB_MAX_STRING_LEN - 1; i++) {
+ c = UGETW(us.bString[i]);
+ if (swap)
+ c = (c >> 8) | (c << 8);
+ /* Encode (16-bit) Unicode as UTF8. */
+ s[j++] = (c < 0x80) ? c : '?';
}
+ s[j] = 0;
}
- *s++ = 0;
return (USBD_NORMAL_COMPLETION);
}
Index: usbdi.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdi.h,v
retrieving revision 1.69
diff -u -r1.69 usbdi.h
--- usbdi.h 28 Nov 2005 13:14:48 -0000 1.69
+++ usbdi.h 29 Aug 2006 13:57:55 -0000
@@ -150,6 +150,7 @@
int usbd_get_no_alts(usb_config_descriptor_t *, int);
usbd_status usbd_get_interface(usbd_interface_handle, u_int8_t *);
void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int);
+void usbd_fill_deviceinfo_old(usbd_device_handle, struct usb_device_info_old *, int);
int usbd_get_interface_altindex(usbd_interface_handle);
usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
@@ -176,7 +177,7 @@
int usbd_ratecheck(struct timeval *);
-usbd_status usbd_get_string(usbd_device_handle, int, char *);
+usbd_status usbd_get_string(usbd_device_handle, int, char *, int);
/* An iterator for descriptors. */
typedef struct {
--MGYHOYXEY6WxJCY8--