aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/input/hid-core.c62
-rw-r--r--drivers/usb/input/hid.h5
2 files changed, 48 insertions, 19 deletions
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index b2cb2b35892e..376b6043bbff 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -2,7 +2,8 @@
2 * USB HID support for Linux 2 * USB HID support for Linux
3 * 3 *
4 * Copyright (c) 1999 Andreas Gal 4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2001 Vojtech Pavlik <vojtech@suse.cz> 5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
6 */ 7 */
7 8
8/* 9/*
@@ -38,7 +39,7 @@
38 * Version Information 39 * Version Information
39 */ 40 */
40 41
41#define DRIVER_VERSION "v2.01" 42#define DRIVER_VERSION "v2.6"
42#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik" 43#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik"
43#define DRIVER_DESC "USB HID core driver" 44#define DRIVER_DESC "USB HID core driver"
44#define DRIVER_LICENSE "GPL" 45#define DRIVER_LICENSE "GPL"
@@ -1058,8 +1059,8 @@ static int hid_submit_ctrl(struct hid_device *hid)
1058 if (maxpacket > 0) { 1059 if (maxpacket > 0) {
1059 padlen = (len + maxpacket - 1) / maxpacket; 1060 padlen = (len + maxpacket - 1) / maxpacket;
1060 padlen *= maxpacket; 1061 padlen *= maxpacket;
1061 if (padlen > HID_BUFFER_SIZE) 1062 if (padlen > hid->bufsize)
1062 padlen = HID_BUFFER_SIZE; 1063 padlen = hid->bufsize;
1063 } else 1064 } else
1064 padlen = 0; 1065 padlen = 0;
1065 hid->urbctrl->transfer_buffer_length = padlen; 1066 hid->urbctrl->transfer_buffer_length = padlen;
@@ -1284,13 +1285,8 @@ void hid_init_reports(struct hid_device *hid)
1284 struct hid_report *report; 1285 struct hid_report *report;
1285 int err, ret; 1286 int err, ret;
1286 1287
1287 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) { 1288 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
1288 int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered;
1289 if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE;
1290 if (size > hid->urbin->transfer_buffer_length)
1291 hid->urbin->transfer_buffer_length = size;
1292 hid_submit_report(hid, report, USB_DIR_IN); 1289 hid_submit_report(hid, report, USB_DIR_IN);
1293 }
1294 1290
1295 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) 1291 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
1296 hid_submit_report(hid, report, USB_DIR_IN); 1292 hid_submit_report(hid, report, USB_DIR_IN);
@@ -1564,15 +1560,32 @@ static struct hid_blacklist {
1564 { 0, 0 } 1560 { 0, 0 }
1565}; 1561};
1566 1562
1563/*
1564 * Traverse the supplied list of reports and find the longest
1565 */
1566static void hid_find_max_report(struct hid_device *hid, unsigned int type, int *max)
1567{
1568 struct hid_report *report;
1569 int size;
1570
1571 list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
1572 size = ((report->size - 1) >> 3) + 1;
1573 if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered)
1574 size++;
1575 if (*max < size)
1576 *max = size;
1577 }
1578}
1579
1567static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) 1580static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
1568{ 1581{
1569 if (!(hid->inbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->inbuf_dma))) 1582 if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
1570 return -1; 1583 return -1;
1571 if (!(hid->outbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->outbuf_dma))) 1584 if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
1572 return -1; 1585 return -1;
1573 if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma))) 1586 if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
1574 return -1; 1587 return -1;
1575 if (!(hid->ctrlbuf = usb_buffer_alloc(dev, HID_BUFFER_SIZE, SLAB_ATOMIC, &hid->ctrlbuf_dma))) 1588 if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
1576 return -1; 1589 return -1;
1577 1590
1578 return 0; 1591 return 0;
@@ -1581,13 +1594,13 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
1581static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) 1594static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
1582{ 1595{
1583 if (hid->inbuf) 1596 if (hid->inbuf)
1584 usb_buffer_free(dev, HID_BUFFER_SIZE, hid->inbuf, hid->inbuf_dma); 1597 usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma);
1585 if (hid->outbuf) 1598 if (hid->outbuf)
1586 usb_buffer_free(dev, HID_BUFFER_SIZE, hid->outbuf, hid->outbuf_dma); 1599 usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma);
1587 if (hid->cr) 1600 if (hid->cr)
1588 usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); 1601 usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma);
1589 if (hid->ctrlbuf) 1602 if (hid->ctrlbuf)
1590 usb_buffer_free(dev, HID_BUFFER_SIZE, hid->ctrlbuf, hid->ctrlbuf_dma); 1603 usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma);
1591} 1604}
1592 1605
1593static struct hid_device *usb_hid_configure(struct usb_interface *intf) 1606static struct hid_device *usb_hid_configure(struct usb_interface *intf)
@@ -1598,7 +1611,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1598 struct hid_device *hid; 1611 struct hid_device *hid;
1599 unsigned quirks = 0, rsize = 0; 1612 unsigned quirks = 0, rsize = 0;
1600 char *buf, *rdesc; 1613 char *buf, *rdesc;
1601 int n; 1614 int n, insize = 0;
1602 1615
1603 for (n = 0; hid_blacklist[n].idVendor; n++) 1616 for (n = 0; hid_blacklist[n].idVendor; n++)
1604 if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) && 1617 if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
@@ -1652,6 +1665,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1652 kfree(rdesc); 1665 kfree(rdesc);
1653 hid->quirks = quirks; 1666 hid->quirks = quirks;
1654 1667
1668 hid->bufsize = HID_MIN_BUFFER_SIZE;
1669 hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize);
1670 hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize);
1671 hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize);
1672
1673 if (hid->bufsize > HID_MAX_BUFFER_SIZE)
1674 hid->bufsize = HID_MAX_BUFFER_SIZE;
1675
1676 hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
1677
1678 if (insize > HID_MAX_BUFFER_SIZE)
1679 insize = HID_MAX_BUFFER_SIZE;
1680
1655 if (hid_alloc_buffers(dev, hid)) { 1681 if (hid_alloc_buffers(dev, hid)) {
1656 hid_free_buffers(dev, hid); 1682 hid_free_buffers(dev, hid);
1657 goto fail; 1683 goto fail;
@@ -1682,7 +1708,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
1682 if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) 1708 if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
1683 goto fail; 1709 goto fail;
1684 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 1710 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
1685 usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0, 1711 usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize,
1686 hid_irq_in, hid, interval); 1712 hid_irq_in, hid, interval);
1687 hid->urbin->transfer_dma = hid->inbuf_dma; 1713 hid->urbin->transfer_dma = hid->inbuf_dma;
1688 hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK); 1714 hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index ca3e170ce0b3..d76bbc81f6a8 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -351,7 +351,8 @@ struct hid_report_enum {
351 351
352#define HID_REPORT_TYPES 3 352#define HID_REPORT_TYPES 3
353 353
354#define HID_BUFFER_SIZE 64 /* use 64 for compatibility with all possible packetlen */ 354#define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */
355#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
355#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ 356#define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */
356#define HID_OUTPUT_FIFO_SIZE 64 357#define HID_OUTPUT_FIFO_SIZE 64
357 358
@@ -389,6 +390,8 @@ struct hid_device { /* device report descriptor */
389 390
390 unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ 391 unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
391 392
393 unsigned int bufsize; /* URB buffer size */
394
392 struct urb *urbin; /* Input URB */ 395 struct urb *urbin; /* Input URB */
393 char *inbuf; /* Input buffer */ 396 char *inbuf; /* Input buffer */
394 dma_addr_t inbuf_dma; /* Input buffer dma */ 397 dma_addr_t inbuf_dma; /* Input buffer dma */