summaryrefslogtreecommitdiffstats
path: root/fastboot/usb_linux.c
diff options
context:
space:
mode:
authorPatrick Tjin <pattjin@google.com>2014-07-11 08:59:01 -0700
committerPatrick Tjin <pattjin@google.com>2014-07-17 10:07:19 -0700
commit4415e2a2696dd422fbe5511fdcd2f896b3d13595 (patch)
treea1c16679c447f9134949878e5a0854c151e95ee7 /fastboot/usb_linux.c
parent04f9b2a809cb83c3d36c75791bfa28690800c883 (diff)
downloadsystem_core-4415e2a2696dd422fbe5511fdcd2f896b3d13595.zip
system_core-4415e2a2696dd422fbe5511fdcd2f896b3d13595.tar.gz
system_core-4415e2a2696dd422fbe5511fdcd2f896b3d13595.tar.bz2
Scan all descriptors when checking for fastboot [DO NOT MERGE]
For Linux, the USB code was only looking at the first descriptor when searching for the fastboot interface which caused some devices to not be found. Also clarify some code by using the actual USB structures instead of void or char pointers. (Cherry Picked from aac89db8a541f609d8268966f7b3ded44da03bd1) Change-Id: I9e4871c4d477ac10ba75bb17a955f176809af289 Signed-off-by: Patrick Tjin <pattjin@google.com>
Diffstat (limited to 'fastboot/usb_linux.c')
-rw-r--r--fastboot/usb_linux.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index a45f9f8..fabbd51 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -100,12 +100,12 @@ static inline int badname(const char *name)
static int check(void *_desc, int len, unsigned type, int size)
{
- unsigned char *desc = _desc;
+ struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)_desc;
if(len < size) return -1;
- if(desc[0] < size) return -1;
- if(desc[0] > len) return -1;
- if(desc[1] != type) return -1;
+ if(hdr->bLength < size) return -1;
+ if(hdr->bLength > len) return -1;
+ if(hdr->bDescriptorType != type) return -1;
return 0;
}
@@ -125,15 +125,15 @@ static int filter_usb_device(char* sysfs_name,
unsigned i;
unsigned e;
- if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
+ if (check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
return -1;
- dev = (void*) ptr;
+ dev = (struct usb_device_descriptor *)ptr;
len -= dev->bLength;
ptr += dev->bLength;
- if(check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE))
+ if (check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE))
return -1;
- cfg = (void*) ptr;
+ cfg = (struct usb_config_descriptor *)ptr;
len -= cfg->bLength;
ptr += cfg->bLength;
@@ -177,9 +177,19 @@ static int filter_usb_device(char* sysfs_name,
}
for(i = 0; i < cfg->bNumInterfaces; i++) {
- if(check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE))
+
+ while (len > 0) {
+ struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)ptr;
+ if (check(hdr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE) == 0)
+ break;
+ len -= hdr->bLength;
+ ptr += hdr->bLength;
+ }
+
+ if (len <= 0)
return -1;
- ifc = (void*) ptr;
+
+ ifc = (struct usb_interface_descriptor *)ptr;
len -= ifc->bLength;
ptr += ifc->bLength;
@@ -190,16 +200,25 @@ static int filter_usb_device(char* sysfs_name,
info.ifc_protocol = ifc->bInterfaceProtocol;
for(e = 0; e < ifc->bNumEndpoints; e++) {
- if(check(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE))
- return -1;
- ept = (void*) ptr;
+ while (len > 0) {
+ struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)ptr;
+ if (check(hdr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE) == 0)
+ break;
+ len -= hdr->bLength;
+ ptr += hdr->bLength;
+ }
+ if (len < 0) {
+ break;
+ }
+
+ ept = (struct usb_endpoint_descriptor *)ptr;
len -= ept->bLength;
ptr += ept->bLength;
- if((ept->bmAttributes & 0x03) != 0x02)
+ if((ept->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
continue;
- if(ept->bEndpointAddress & 0x80) {
+ if(ept->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
in = ept->bEndpointAddress;
} else {
out = ept->bEndpointAddress;