|
|
@@ -106,6 +106,7 @@ struct usbtouch_device_info {
|
|
|
struct usbtouch_usb {
|
|
|
unsigned char *data;
|
|
|
dma_addr_t data_dma;
|
|
|
+ int data_size;
|
|
|
unsigned char *buffer;
|
|
|
int buf_len;
|
|
|
struct urb *irq;
|
|
|
@@ -1523,7 +1524,7 @@ static int usbtouch_reset_resume(struct usb_interface *intf)
|
|
|
static void usbtouch_free_buffers(struct usb_device *udev,
|
|
|
struct usbtouch_usb *usbtouch)
|
|
|
{
|
|
|
- usb_free_coherent(udev, usbtouch->type->rept_size,
|
|
|
+ usb_free_coherent(udev, usbtouch->data_size,
|
|
|
usbtouch->data, usbtouch->data_dma);
|
|
|
kfree(usbtouch->buffer);
|
|
|
}
|
|
|
@@ -1568,7 +1569,20 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|
|
if (!type->process_pkt)
|
|
|
type->process_pkt = usbtouch_process_pkt;
|
|
|
|
|
|
- usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
|
|
|
+ usbtouch->data_size = type->rept_size;
|
|
|
+ if (type->get_pkt_len) {
|
|
|
+ /*
|
|
|
+ * When dealing with variable-length packets we should
|
|
|
+ * not request more than wMaxPacketSize bytes at once
|
|
|
+ * as we do not know if there is more data coming or
|
|
|
+ * we filled exactly wMaxPacketSize bytes and there is
|
|
|
+ * nothing else.
|
|
|
+ */
|
|
|
+ usbtouch->data_size = min(usbtouch->data_size,
|
|
|
+ usb_endpoint_maxp(endpoint));
|
|
|
+ }
|
|
|
+
|
|
|
+ usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size,
|
|
|
GFP_KERNEL, &usbtouch->data_dma);
|
|
|
if (!usbtouch->data)
|
|
|
goto out_free;
|
|
|
@@ -1628,12 +1642,12 @@ static int usbtouch_probe(struct usb_interface *intf,
|
|
|
if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
|
|
|
usb_fill_int_urb(usbtouch->irq, udev,
|
|
|
usb_rcvintpipe(udev, endpoint->bEndpointAddress),
|
|
|
- usbtouch->data, type->rept_size,
|
|
|
+ usbtouch->data, usbtouch->data_size,
|
|
|
usbtouch_irq, usbtouch, endpoint->bInterval);
|
|
|
else
|
|
|
usb_fill_bulk_urb(usbtouch->irq, udev,
|
|
|
usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
|
|
|
- usbtouch->data, type->rept_size,
|
|
|
+ usbtouch->data, usbtouch->data_size,
|
|
|
usbtouch_irq, usbtouch);
|
|
|
|
|
|
usbtouch->irq->dev = udev;
|