libusbhost: Add call for synchronous bulk transfers

Also clean up and add timeout to control request transfer

Change-Id: Ibc2d8ac64d0fa90e0a23e6225ce2c49b23bb0d97
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/include/usbhost/usbhost.h b/include/usbhost/usbhost.h
index 41e2ddc..c330cab 100644
--- a/include/usbhost/usbhost.h
+++ b/include/usbhost/usbhost.h
@@ -125,15 +125,6 @@
 
 const struct usb_device_descriptor* usb_device_get_device_descriptor(struct usb_device *device);
 
-/* Sends a control message to the specified device on endpoint zero */
-int usb_device_send_control(struct usb_device *device,
-                            int requestType,
-                            int request,
-                            int value,
-                            int index,
-                            int length,
-                            void* buffer);
-
 /* Returns a USB descriptor string for the given string ID.
  * Used to implement usb_device_get_manufacturer_name,
  * usb_device_get_product_name and usb_device_get_serial.
@@ -184,6 +175,23 @@
 int usb_device_connect_kernel_driver(struct usb_device *device,
         unsigned int interface, int connect);
 
+/* Sends a control message to the specified device on endpoint zero */
+int usb_device_control_transfer(struct usb_device *device,
+                            int requestType,
+                            int request,
+                            int value,
+                            int index,
+                            void* buffer,
+                            int length,
+                            unsigned int timeout);
+
+/* Reads or writes on a bulk endpoint */
+int usb_device_bulk_transfer(struct usb_device *device,
+                            int endpoint,
+                            void* buffer,
+                            int length,
+                            unsigned int timeout);
+
 /* Creates a new usb_request. */
 struct usb_request *usb_request_new(struct usb_device *dev,
         const struct usb_endpoint_descriptor *ep_desc);
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 89a7f0a..576ee00 100644
--- a/libusbhost/usbhost.c
+++ b/libusbhost/usbhost.c
@@ -332,30 +332,6 @@
     return (struct usb_device_descriptor*)device->desc;
 }
 
-int usb_device_send_control(struct usb_device *device,
-                            int requestType,
-                            int request,
-                            int value,
-                            int index,
-                            int length,
-                            void* buffer)
-{
-    struct usbdevfs_ctrltransfer  ctrl;
-
-    // this usually requires read/write permission
-    if (!usb_device_reopen_writeable(device))
-        return -1;
-
-    memset(&ctrl, 0, sizeof(ctrl));
-    ctrl.bRequestType = requestType;
-    ctrl.bRequest = request;
-    ctrl.wValue = value;
-    ctrl.wIndex = index;
-    ctrl.wLength = length;
-    ctrl.data = buffer;
-    return ioctl(device->fd, USBDEVFS_CONTROL, &ctrl);
-}
-
 char* usb_device_get_string(struct usb_device *device, int id)
 {
     char string[256];
@@ -368,18 +344,18 @@
     memset(languages, 0, sizeof(languages));
 
     // read list of supported languages
-    result = usb_device_send_control(device,
+    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, sizeof(languages), languages);
+            (USB_DT_STRING << 8) | 0, 0, languages, sizeof(languages), 0);
     if (result > 0)
         languageCount = (result - 2) / 2;
 
     for (i = 1; i <= languageCount; i++) {
         memset(buffer, 0, sizeof(buffer));
 
-        result = usb_device_send_control(device,
+        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], sizeof(buffer), buffer);
+                (USB_DT_STRING << 8) | id, languages[i], buffer, sizeof(buffer), 0);
         if (result > 0) {
             int i;
             // skip first word, and copy the rest to the string, changing shorts to bytes.
@@ -467,6 +443,48 @@
     return ioctl(device->fd, USBDEVFS_IOCTL, &ctl);
 }
 
+int usb_device_control_transfer(struct usb_device *device,
+                            int requestType,
+                            int request,
+                            int value,
+                            int index,
+                            void* buffer,
+                            int length,
+                            unsigned int timeout)
+{
+    struct usbdevfs_ctrltransfer  ctrl;
+
+    // this usually requires read/write permission
+    if (!usb_device_reopen_writeable(device))
+        return -1;
+
+    memset(&ctrl, 0, sizeof(ctrl));
+    ctrl.bRequestType = requestType;
+    ctrl.bRequest = request;
+    ctrl.wValue = value;
+    ctrl.wIndex = index;
+    ctrl.wLength = length;
+    ctrl.data = buffer;
+    ctrl.timeout = timeout;
+    return ioctl(device->fd, USBDEVFS_CONTROL, &ctrl);
+}
+
+int usb_device_bulk_transfer(struct usb_device *device,
+                            int endpoint,
+                            void* buffer,
+                            int length,
+                            unsigned int timeout)
+{
+    struct usbdevfs_bulktransfer  ctrl;
+
+    memset(&ctrl, 0, sizeof(ctrl));
+    ctrl.ep = endpoint;
+    ctrl.len = length;
+    ctrl.data = buffer;
+    ctrl.timeout = timeout;
+    return ioctl(device->fd, USBDEVFS_BULK, &ctrl);
+}
+
 struct usb_request *usb_request_new(struct usb_device *dev,
         const struct usb_endpoint_descriptor *ep_desc)
 {