HID: hidraw: Use Interrupt Endpoint for OUT Transfers if Available
[safe/jmp/linux-2.6] / drivers / hid / usbhid / hid-core.c
index 245aef0..f9640a3 100644 (file)
@@ -807,16 +807,36 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
        struct usb_host_interface *interface = intf->cur_altsetting;
        int ret;
 
-       ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-               HID_REQ_SET_REPORT,
-               USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-               ((report_type + 1) << 8) | *buf,
-               interface->desc.bInterfaceNumber, buf + 1, count - 1,
-               USB_CTRL_SET_TIMEOUT);
-
-       /* count also the report id */
-       if (ret > 0)
-               ret++;
+       if (usbhid->urbout) {
+               int actual_length;
+               int skipped_report_id = 0;
+               if (buf[0] == 0x0) {
+                       /* Don't send the Report ID */
+                       buf++;
+                       count--;
+                       skipped_report_id = 1;
+               }
+               ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
+                       buf, count, &actual_length,
+                       USB_CTRL_SET_TIMEOUT);
+               /* return the number of bytes transferred */
+               if (ret == 0) {
+                       ret = actual_length;
+                       /* count also the report id */
+                       if (skipped_report_id)
+                               ret++;
+               }
+       } else {
+               ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+                       HID_REQ_SET_REPORT,
+                       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                       ((report_type + 1) << 8) | *buf,
+                       interface->desc.bInterfaceNumber, buf + 1, count - 1,
+                       USB_CTRL_SET_TIMEOUT);
+               /* count also the report id */
+               if (ret > 0)
+                       ret++;
+       }
 
        return ret;
 }