From dfd21b89f28bd8a6d4acdc05b74fbd03bb844f48 Mon Sep 17 00:00:00 2001 From: Vitalii Tomkiv Date: Fri, 14 Oct 2016 10:19:26 -0700 Subject: [PATCH] Add timeout to usb_device_control_transfer call in usbhost code. usb_device_control_transfer used to use "0" value in control_transfer call which resulted in unlimited timeout. In case of bad USB devices connected it resulted in usbhost stuck state. Bug: 31923641 Test: manual run and test with bad devices. Change-Id: I4a2a691a6d83107f72ba506522c932085bd09624 --- libusbhost/include/usbhost/usbhost.h | 8 ++++---- libusbhost/usbhost.c | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/libusbhost/include/usbhost/usbhost.h b/libusbhost/include/usbhost/usbhost.h index 84594c818..c17f3c7ea 100644 --- a/libusbhost/include/usbhost/usbhost.h +++ b/libusbhost/include/usbhost/usbhost.h @@ -144,17 +144,17 @@ const struct usb_device_descriptor* usb_device_get_device_descriptor(struct usb_ * usb_device_get_product_name and usb_device_get_serial. * Call free() to free the result when you are done with it. */ -char* usb_device_get_string(struct usb_device *device, int id); +char* usb_device_get_string(struct usb_device *device, int id, int timeout); /* Returns the manufacturer name for the USB device. * Call free() to free the result when you are done with it. */ -char* usb_device_get_manufacturer_name(struct usb_device *device); +char* usb_device_get_manufacturer_name(struct usb_device *device, int timeout); /* Returns the product name for the USB device. * Call free() to free the result when you are done with it. */ -char* usb_device_get_product_name(struct usb_device *device); +char* usb_device_get_product_name(struct usb_device *device, int timeout); /* Returns the version number for the USB device. */ @@ -163,7 +163,7 @@ int usb_device_get_version(struct usb_device *device); /* Returns the USB serial number for the USB device. * Call free() to free the result when you are done with it. */ -char* usb_device_get_serial(struct usb_device *device); +char* usb_device_get_serial(struct usb_device *device, int timeout); /* Returns true if we have write access to the USB device, * and false if we only have access to the USB device configuration. diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c index 68aca1774..9bec6e315 100644 --- a/libusbhost/usbhost.c +++ b/libusbhost/usbhost.c @@ -449,7 +449,7 @@ const struct usb_device_descriptor* usb_device_get_device_descriptor(struct usb_ return (struct usb_device_descriptor*)device->desc; } -char* usb_device_get_string(struct usb_device *device, int id) +char* usb_device_get_string(struct usb_device *device, int id, int timeout) { char string[256]; __u16 buffer[MAX_STRING_DESCRIPTOR_LENGTH / sizeof(__u16)]; @@ -465,7 +465,8 @@ char* usb_device_get_string(struct usb_device *device, int id) // read list of supported languages result = usb_device_control_transfer(device, USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE, USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) | 0, 0, languages, sizeof(languages), 0); + (USB_DT_STRING << 8) | 0, 0, languages, sizeof(languages), + timeout); if (result > 0) languageCount = (result - 2) / 2; @@ -474,7 +475,8 @@ char* usb_device_get_string(struct usb_device *device, int id) result = usb_device_control_transfer(device, USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE, USB_REQ_GET_DESCRIPTOR, - (USB_DT_STRING << 8) | id, languages[i], buffer, sizeof(buffer), 0); + (USB_DT_STRING << 8) | id, languages[i], buffer, sizeof(buffer), + timeout); if (result > 0) { int i; // skip first word, and copy the rest to the string, changing shorts to bytes. @@ -489,16 +491,16 @@ char* usb_device_get_string(struct usb_device *device, int id) return NULL; } -char* usb_device_get_manufacturer_name(struct usb_device *device) +char* usb_device_get_manufacturer_name(struct usb_device *device, int timeout) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; - return usb_device_get_string(device, desc->iManufacturer); + return usb_device_get_string(device, desc->iManufacturer, timeout); } -char* usb_device_get_product_name(struct usb_device *device) +char* usb_device_get_product_name(struct usb_device *device, int timeout) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; - return usb_device_get_string(device, desc->iProduct); + return usb_device_get_string(device, desc->iProduct, timeout); } int usb_device_get_version(struct usb_device *device) @@ -507,10 +509,10 @@ int usb_device_get_version(struct usb_device *device) return desc->bcdUSB; } -char* usb_device_get_serial(struct usb_device *device) +char* usb_device_get_serial(struct usb_device *device, int timeout) { struct usb_device_descriptor *desc = (struct usb_device_descriptor *)device->desc; - return usb_device_get_string(device, desc->iSerialNumber); + return usb_device_get_string(device, desc->iSerialNumber, timeout); } int usb_device_is_writeable(struct usb_device *device) @@ -711,4 +713,3 @@ int usb_request_cancel(struct usb_request *req) struct usbdevfs_urb *urb = ((struct usbdevfs_urb*)req->private_data); return ioctl(req->dev->fd, USBDEVFS_DISCARDURB, urb); } -