209 lines
5.9 KiB
Text
209 lines
5.9 KiB
Text
$NetBSD: patch-ab,v 1.5 2011/07/24 18:00:07 jmcneill Exp $
|
|
|
|
--- usbctl.c.orig 2002-02-24 19:50:55.000000000 -0500
|
|
+++ usbctl.c 2011-07-24 09:56:59.000000000 -0400
|
|
@@ -27,12 +27,18 @@
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
+#include <sys/ioctl.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <err.h>
|
|
#include <errno.h>
|
|
+#ifdef __DragonFly__
|
|
+#include <bus/usb/usb.h>
|
|
+#include <bus/usb/usbhid.h>
|
|
+#else
|
|
#include <dev/usb/usb.h>
|
|
#include <dev/usb/usbhid.h>
|
|
+#endif
|
|
|
|
#ifndef USB_STACK_VERSION
|
|
#define ucr_addr addr
|
|
@@ -52,6 +58,21 @@
|
|
#define UICLASS_HUB UCLASS_HUB
|
|
#endif
|
|
|
|
+#ifndef UDESC_INTERFACE_ASSOC
|
|
+#define UDESC_INTERFACE_ASSOC 0x0b
|
|
+typedef struct {
|
|
+ uByte bLength;
|
|
+ uByte bDescriptorType;
|
|
+ uByte bFirstInterface;
|
|
+ uByte bInterfaceCount;
|
|
+ uByte bFunctionClass;
|
|
+ uByte bFunctionSubClass;
|
|
+ uByte bFunctionProtocol;
|
|
+ uByte iFunction
|
|
+} UPACKED usb_interface_assoc_descriptor_t;
|
|
+#define USB_INTERFACE_ASSOC_DESCRIPTOR_SIZE 8
|
|
+#endif
|
|
+
|
|
#define USBDEV "/dev/usb0"
|
|
|
|
/* Backwards compatibility */
|
|
@@ -62,6 +83,7 @@
|
|
#endif
|
|
|
|
#define NSTRINGS
|
|
+#define STRINGLANG
|
|
|
|
int num = 0;
|
|
|
|
@@ -80,17 +102,43 @@ getstring(int si, char *s)
|
|
int r, i, n;
|
|
u_int16_t c;
|
|
usb_string_descriptor_t us;
|
|
+ int lang = 0;
|
|
|
|
if (si == 0 || num) {
|
|
*s = 0;
|
|
return;
|
|
}
|
|
+
|
|
+#ifdef STRINGLANG
|
|
req.ucr_addr = usbaddr;
|
|
req.ucr_request.bmRequestType = UT_READ_DEVICE;
|
|
req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
|
|
req.ucr_data = &us;
|
|
- USETW2(req.ucr_request.wValue, UDESC_STRING, si);
|
|
+ USETW2(req.ucr_request.wValue, UDESC_STRING, 0);
|
|
USETW(req.ucr_request.wIndex, 0);
|
|
+ USETW(req.ucr_request.wLength, sizeof(usb_string_descriptor_t));
|
|
+ req.ucr_flags = USBD_SHORT_XFER_OK;
|
|
+ r = ioctl(usbf, USB_REQUEST, &req);
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "get lang tbl failed (error=%d)\n", errno);
|
|
+ *s = 0;
|
|
+ return;
|
|
+ }
|
|
+ if (req.ucr_actlen > 0 && us.bLength >= 4) {
|
|
+ lang = UGETW(us.bString[0]);
|
|
+#if 0
|
|
+ printf("getstring: %d langs, using %d\n",
|
|
+ (us.bLength - 2) / 2, lang);
|
|
+#endif
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ req.ucr_addr = usbaddr;
|
|
+ req.ucr_request.bmRequestType = UT_READ_DEVICE;
|
|
+ req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
|
|
+ req.ucr_data = &us;
|
|
+ USETW2(req.ucr_request.wValue, UDESC_STRING, si);
|
|
+ USETW(req.ucr_request.wIndex, lang);
|
|
#ifdef NSTRINGS
|
|
USETW(req.ucr_request.wLength, sizeof(usb_string_descriptor_t));
|
|
req.ucr_flags = USBD_SHORT_XFER_OK;
|
|
@@ -154,6 +202,7 @@ descTypeName(int t)
|
|
case UDESC_STRING: p = "string"; break;
|
|
case UDESC_INTERFACE: p = "interface"; break;
|
|
case UDESC_ENDPOINT: p = "endpoint"; break;
|
|
+ case UDESC_INTERFACE_ASSOC: p = "iad"; break;
|
|
case 0x20: p = "cs_undefined"; break;
|
|
case UDESC_CS_DEVICE: p = "cs_device"; break;
|
|
case UDESC_CS_CONFIG: p = "cs_config"; break;
|
|
@@ -278,6 +327,21 @@ bInterfaceProtocol=%d iInterface=%d(%s)\
|
|
d->iInterface, ifc);
|
|
}
|
|
|
|
+void
|
|
+priad(usb_interface_assoc_descriptor_t *d)
|
|
+{
|
|
+ char func[MAXSTR];
|
|
+ getstring(d->iFunction, func);
|
|
+ if (d->bDescriptorType != UDESC_INTERFACE_ASSOC) printf("weird descriptorType, should be %d\n", UDESC_INTERFACE_ASSOC);
|
|
+ printf("\
|
|
+bLength=%d bDescriptorType=%s bFirstInterface=%d bInterfaceCount=%d\n\
|
|
+bFunctionClass=%d bFunctionSubClass=%d bFunctionProtocol=%d\n\
|
|
+iFunction=%d(%s)\n",
|
|
+ d->bLength, descTypeName(d->bDescriptorType), d->bFirstInterface,
|
|
+ d->bInterfaceCount, d->bFunctionClass, d->bFunctionSubClass,
|
|
+ d->bFunctionProtocol, d->iFunction, func);
|
|
+}
|
|
+
|
|
char *xfernames[] = { "control", "isochronous", "bulk", "interrupt" };
|
|
char *xfertypes[] = { "", "-async", "-adaptive", "-sync" };
|
|
|
|
@@ -384,7 +448,7 @@ struct usb_cdc_union_descriptor {
|
|
};
|
|
|
|
void
|
|
-prcdcd(usb_descriptor_t *ud)
|
|
+prcdcd(struct usb_cdc_header_descriptor *ud)
|
|
{
|
|
if (ud->bDescriptorType != UDESC_CS_INTERFACE)
|
|
printf("prcdcd: strange bDescriptorType=%d\n",
|
|
@@ -630,7 +694,7 @@ gethubdesc(int f, usb_hub_descriptor_t *
|
|
req.ucr_addr = addr;
|
|
req.ucr_request.bmRequestType = UT_READ_CLASS_DEVICE;
|
|
req.ucr_request.bRequest = UR_GET_DESCRIPTOR;
|
|
- USETW(req.ucr_request.wValue, 0);
|
|
+ USETW2(req.ucr_request.wValue, UDESC_HUB, 0);
|
|
USETW(req.ucr_request.wIndex, 0);
|
|
USETW(req.ucr_request.wLength, USB_HUB_DESCRIPTOR_SIZE);
|
|
req.ucr_data = d;
|
|
@@ -1145,6 +1209,11 @@ prdesc(void *p, int *class, int *subclas
|
|
prhubd(p);
|
|
break;
|
|
#endif
|
|
+ case UDESC_INTERFACE_ASSOC:
|
|
+ printf("INTERFACE ASSOCIATION descriptor:\n");
|
|
+ priad(p);
|
|
+ break;
|
|
+ break;
|
|
case UDESC_CS_DEVICE:
|
|
if (*class == UICLASS_HID) {
|
|
usb_hid_descriptor_t *hid = p;
|
|
@@ -1155,10 +1224,14 @@ prdesc(void *p, int *class, int *subclas
|
|
printf("\n");
|
|
for(k = 0; k < hid->bNumDescriptors; k++) {
|
|
int type, len;
|
|
- u_char buf[256];
|
|
+ u_char *buf;
|
|
|
|
type = hid->descrs[k].bDescriptorType;
|
|
len = UGETW(hid->descrs[k].wDescriptorLength);
|
|
+ buf = malloc(len);
|
|
+ if (buf == NULL) {
|
|
+ errx(1, "malloc failed (size=%d)\n", len);
|
|
+ }
|
|
if (type == UDESC_REPORT) {
|
|
getreportdesc(globf, *iface, k, buf, len, globaddr);
|
|
printf("Report descriptor\n");
|
|
@@ -1169,6 +1242,7 @@ prdesc(void *p, int *class, int *subclas
|
|
printf("Unknown HID descriptor type %d\n", type);
|
|
}
|
|
printf("\n");
|
|
+ free(buf);
|
|
}
|
|
} else
|
|
goto def;
|
|
@@ -1243,8 +1317,8 @@ prdesc(void *p, int *class, int *subclas
|
|
default:
|
|
def:
|
|
printf("Unknown descriptor (class %d/%d):\n", *class, *subclass);
|
|
- printf("bLength=%d bDescriptorType=%d bDescriptorSubtype=%d ...\n", d->bLength,
|
|
- d->bDescriptorType, d->bDescriptorSubtype
|
|
+ printf("bLength=%d bDescriptorType=%d ...\n", d->bLength,
|
|
+ d->bDescriptorType
|
|
);
|
|
break;
|
|
}
|
|
@@ -1321,6 +1395,7 @@ main(int argc, char **argv)
|
|
|
|
if (!doaddr)
|
|
prunits(f);
|
|
+#ifndef __NetBSD__
|
|
if (!nodisc) {
|
|
r = ioctl(f, USB_DISCOVER);
|
|
if (r < 0)
|
|
@@ -1329,6 +1404,7 @@ main(int argc, char **argv)
|
|
if (disconly)
|
|
exit(0);
|
|
}
|
|
+#endif
|
|
|
|
for(addr = 0; addr < USB_MAX_DEVICES; addr++) {
|
|
if (doaddr != -1 && addr != doaddr)
|