History

Input: usbtouchscreen - separate report and transmit buffer size handling

This patch supports the separate handling of the USB transfer buffer length and the length of the buffer used for multi packet support. For devices supporting multiple report or diagnostic packets, the USB transfer size is now limited to the USB endpoints wMaxPacketSize - otherwise it defaults to the configured report packet size as before. This fixes an issue where event reporting can be delayed for an arbitrary time for multi packet devices. For instance the report size for eGalax devices is defined to the 16 byte maximum diagnostic packet size as opposed to the 5 byte report packet size. In case the driver requests 16 byte from the USB interrupt endpoint, the USB host controller driver needs to split up the request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte. When the first transfer is answered by the eGalax device with not less than the full 8 byte requested, the host controller has got no way of knowing whether the touch controller has got additional data queued and will issue the second transfer. If per example a liftoff event finishes at such a wMaxPacketSize boundary, the data will not be available to the usbtouch driver until a further event is triggered and transfered to the host. From user perspective the BTN_TOUCH release event in this case is stuck until the next touch down event.

Christian Engelmayer committed 12 years ago

Commit 4ef38351 parent b884eb81 file · +18 −4Browse files

Unified · Split

drivers/input/touchscreen/usbtouchscreen.c+18−4
@@ -106,6 +106,7 @@ struct usbtouch_device_info { · 105 unmodified lines
106106 struct usbtouch_usb {
107107 unsigned char *data;
108108 dma_addr_t data_dma;
109+ int data_size;
109110 unsigned char *buffer;
110111 int buf_len;
111112 struct urb *irq;
@@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf) · 1411 unmodified lines
15231524 static void usbtouch_free_buffers(struct usb_device *udev,
15241525 struct usbtouch_usb *usbtouch)
15251526 {
1526− usb_free_coherent(udev, usbtouch->type->rept_size,
1527+ usb_free_coherent(udev, usbtouch->data_size,
15271528 usbtouch->data, usbtouch->data_dma);
15281529 kfree(usbtouch->buffer);
15291530 }
@@ -1568,7 +1569,20 @@ static int usbtouch_probe(struct usb_interface *intf, · 38 unmodified lines
15681569 if (!type->process_pkt)
15691570 type->process_pkt = usbtouch_process_pkt;
15701571
1571− usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
1572+ usbtouch->data_size = type->rept_size;
1573+ if (type->get_pkt_len) {
1574+ /*
1575+ * When dealing with variable-length packets we should
1576+ * not request more than wMaxPacketSize bytes at once
1577+ * as we do not know if there is more data coming or
1578+ * we filled exactly wMaxPacketSize bytes and there is
1579+ * nothing else.
1580+ */
1581+ usbtouch->data_size = min(usbtouch->data_size,
1582+ usb_endpoint_maxp(endpoint));
1583+ }
1584+
1585+ usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size,
15721586 GFP_KERNEL, &usbtouch->data_dma);
15731587 if (!usbtouch->data)
15741588 goto out_free;
@@ -1628,12 +1642,12 @@ static int usbtouch_probe(struct usb_interface *intf, · 53 unmodified lines
16281642 if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
16291643 usb_fill_int_urb(usbtouch->irq, udev,
16301644 usb_rcvintpipe(udev, endpoint->bEndpointAddress),
1631− usbtouch->data, type->rept_size,
1645+ usbtouch->data, usbtouch->data_size,
16321646 usbtouch_irq, usbtouch, endpoint->bInterval);
16331647 else
16341648 usb_fill_bulk_urb(usbtouch->irq, udev,
16351649 usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
1636− usbtouch->data, type->rept_size,
1650+ usbtouch->data, usbtouch->data_size,
16371651 usbtouch_irq, usbtouch);
16381652
16391653 usbtouch->irq->dev = udev;