Introduced in upstream commit 5d7e7d47, and fixed in 6e8ec537. As with the Bamboos mentioned in the later commit, the get request for Intuos5 fails (causing, for some reason, the pen and touch interfaces to not be brought up properly).
Signed-off-by: Jason Gerecke <killert...@gmail.com> --- 2.6.30/wacom_sys.c | 66 +++++++++++++++++++++++++++--------------- 2.6.36/wacom_sys.c | 82 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 56 deletions(-) diff --git a/2.6.30/wacom_sys.c b/2.6.30/wacom_sys.c index 41dd54b..bc43225 100755 --- a/2.6.30/wacom_sys.c +++ b/2.6.30/wacom_sys.c @@ -55,25 +55,43 @@ struct hid_descriptor { #define WAC_HID_FEATURE_REPORT 0x03 #define WAC_CMD_LED_CONTROL 0x20 +#define WAC_CMD_RETRIES 10 -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) +static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id, + void *buf, size_t size, unsigned int retries) { - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); + struct usb_device *dev = interface_to_usbdev(intf); + int retval; + + do { + retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, + (type << 8) + id, + intf->altsetting[0].desc.bInterfaceNumber, + buf, size, 100); + } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); + + return retval; } -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) +static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id, + void *buf, size_t size, unsigned int retries) { - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); + struct usb_device *dev = interface_to_usbdev(intf); + int retval; + + do { + retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_REPORT, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, + intf->altsetting[0].desc.bInterfaceNumber, + buf, size, 1000); + } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); + + return retval; } static void wacom_sys_irq(struct urb *urb) @@ -334,23 +352,23 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat rep_data[2] = 0; rep_data[3] = 0; report_id = 3; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 4); + error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 4, 1); if (error >= 0) - error = usb_get_report(intf, + error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, - rep_data, 4); + rep_data, 4, 1); } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); } else if (features->type != TABLETPC && features->device_type == BTN_TOOL_PEN) { do { rep_data[0] = 2; rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); + error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2, 1); if (error >= 0) - error = usb_get_report(intf, + error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, - rep_data, 2); + rep_data, 2, 1); } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); } @@ -489,8 +507,8 @@ static int wacom_led_control(struct wacom *wacom) buf[2] = wacom->led.llv; buf[3] = wacom->led.hlv; - retval = usb_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, - buf, sizeof(buf)); + retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, + buf, sizeof(buf), WAC_CMD_RETRIES); kfree(buf); return retval; diff --git a/2.6.36/wacom_sys.c b/2.6.36/wacom_sys.c index b78de6d..11e4af9 100644 --- a/2.6.36/wacom_sys.c +++ b/2.6.36/wacom_sys.c @@ -55,25 +55,43 @@ struct hid_descriptor { #define WAC_CMD_LED_CONTROL 0x20 #define WAC_CMD_ICON_START 0x21 #define WAC_CMD_ICON_XFER 0x23 +#define WAC_CMD_RETRIES 10 -static int usb_get_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) +static int wacom_get_report(struct usb_interface *intf, u8 type, u8 id, + void *buf, size_t size, unsigned int retries) { - return usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 100); + struct usb_device *dev = interface_to_usbdev(intf); + int retval; + + do { + retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_REPORT, + USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, + (type << 8) + id, + intf->altsetting[0].desc.bInterfaceNumber, + buf, size, 100); + } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); + + return retval; } -static int usb_set_report(struct usb_interface *intf, unsigned char type, - unsigned char id, void *buf, int size) +static int wacom_set_report(struct usb_interface *intf, u8 type, u8 id, + void *buf, size_t size, unsigned int retries) { - return usb_control_msg(interface_to_usbdev(intf), - usb_sndctrlpipe(interface_to_usbdev(intf), 0), - USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, - buf, size, 1000); + struct usb_device *dev = interface_to_usbdev(intf); + int retval; + + do { + retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_REPORT, + USB_TYPE_CLASS | USB_RECIP_INTERFACE, + (type << 8) + id, + intf->altsetting[0].desc.bInterfaceNumber, + buf, size, 1000); + } while ((retval == -ETIMEDOUT || retval == -EPIPE) && --retries); + + return retval; } static void wacom_sys_irq(struct urb *urb) @@ -291,9 +309,9 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi case HID_MT_CONTACTMAX: do { rep_data[0] = 12; - result = usb_get_report(intf, + result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, rep_data[0], - rep_data, 2); + rep_data, 2, 1); } while (result < 0 && limit++ < WAC_MSG_RETRIES); if ((result >= 0) && (rep_data[1] > 2)) @@ -335,24 +353,24 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat rep_data[2] = 0; rep_data[3] = 0; report_id = 3; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 4); + error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 4, 1); if (error >= 0) - error = usb_get_report(intf, + error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, - rep_data, 4); + rep_data, 4, 1); } while ((error < 0 || rep_data[1] != 4) && limit++ < WAC_MSG_RETRIES); } else if (features->type != TABLETPC && features->device_type == BTN_TOOL_PEN) { do { rep_data[0] = 2; rep_data[1] = 2; - error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, - report_id, rep_data, 2); + error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, 2, 1); if (error >= 0) - error = usb_get_report(intf, + error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, report_id, - rep_data, 2); + rep_data, 2, 1); } while ((error < 0 || rep_data[1] != 2) && limit++ < WAC_MSG_RETRIES); } @@ -490,8 +508,8 @@ static int wacom_led_control(struct wacom *wacom) buf[3] = wacom->led.hlv; buf[4] = wacom->led.img_lum; - retval = usb_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, - buf, sizeof(buf)); + retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_LED_CONTROL, + buf, sizeof(buf), WAC_CMD_RETRIES); kfree(buf); return retval; @@ -509,8 +527,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im /* Send 'start' command */ buf[0] = WAC_CMD_ICON_START; buf[1] = 1; - retval = usb_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, - buf, 2); + retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, + buf, 2, WAC_CMD_RETRIES); if (retval < 0) goto out; @@ -520,8 +538,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im buf[2] = i; memcpy(buf + 3, img + i * 256, 256); - retval = usb_set_report(wacom->intf, 0x03, WAC_CMD_ICON_XFER, - buf, 259); + retval = wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_XFER, + buf, 259, WAC_CMD_RETRIES); if (retval < 0) break; } @@ -529,8 +547,8 @@ static int wacom_led_putimage(struct wacom *wacom, int button_id, const void *im /* Send 'stop' */ buf[0] = WAC_CMD_ICON_START; buf[1] = 0; - usb_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, - buf, 2); + wacom_set_report(wacom->intf, 0x03, WAC_CMD_ICON_START, + buf, 2, WAC_CMD_RETRIES); out: kfree(buf); -- 1.7.9.5 ------------------------------------------------------------------------------ Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel