aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-core.c112
-rw-r--r--include/linux/hid.h14
2 files changed, 94 insertions, 32 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4da66b4b977c..9ed4ff37dc2b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -546,12 +546,11 @@ static void hid_free_report(struct hid_report *report)
546} 546}
547 547
548/* 548/*
549 * Free a device structure, all reports, and all fields. 549 * Close report. This function returns the device
550 * state to the point prior to hid_open_report().
550 */ 551 */
551 552static void hid_close_report(struct hid_device *device)
552static void hid_device_release(struct device *dev)
553{ 553{
554 struct hid_device *device = container_of(dev, struct hid_device, dev);
555 unsigned i, j; 554 unsigned i, j;
556 555
557 for (i = 0; i < HID_REPORT_TYPES; i++) { 556 for (i = 0; i < HID_REPORT_TYPES; i++) {
@@ -562,11 +561,34 @@ static void hid_device_release(struct device *dev)
562 if (report) 561 if (report)
563 hid_free_report(report); 562 hid_free_report(report);
564 } 563 }
564 memset(report_enum, 0, sizeof(*report_enum));
565 INIT_LIST_HEAD(&report_enum->report_list);
565 } 566 }
566 567
567 kfree(device->rdesc); 568 kfree(device->rdesc);
569 device->rdesc = NULL;
570 device->rsize = 0;
571
568 kfree(device->collection); 572 kfree(device->collection);
569 kfree(device); 573 device->collection = NULL;
574 device->collection_size = 0;
575 device->maxcollection = 0;
576 device->maxapplication = 0;
577
578 device->status &= ~HID_STAT_PARSED;
579}
580
581/*
582 * Free a device structure, all reports, and all fields.
583 */
584
585static void hid_device_release(struct device *dev)
586{
587 struct hid_device *hid = container_of(dev, struct hid_device, dev);
588
589 hid_close_report(hid);
590 kfree(hid->dev_rdesc);
591 kfree(hid);
570} 592}
571 593
572/* 594/*
@@ -643,15 +665,37 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item)
643 * @start: report start 665 * @start: report start
644 * @size: report size 666 * @size: report size
645 * 667 *
668 * Allocate the device report as read by the bus driver. This function should
669 * only be called from parse() in ll drivers.
670 */
671int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size)
672{
673 hid->dev_rdesc = kmemdup(start, size, GFP_KERNEL);
674 if (!hid->dev_rdesc)
675 return -ENOMEM;
676 hid->dev_rsize = size;
677 return 0;
678}
679EXPORT_SYMBOL_GPL(hid_parse_report);
680
681/**
682 * hid_open_report - open a driver-specific device report
683 *
684 * @device: hid device
685 *
646 * Parse a report description into a hid_device structure. Reports are 686 * Parse a report description into a hid_device structure. Reports are
647 * enumerated, fields are attached to these reports. 687 * enumerated, fields are attached to these reports.
648 * 0 returned on success, otherwise nonzero error value. 688 * 0 returned on success, otherwise nonzero error value.
689 *
690 * This function (or the equivalent hid_parse() macro) should only be
691 * called from probe() in drivers, before starting the device.
649 */ 692 */
650int hid_parse_report(struct hid_device *device, __u8 *start, 693int hid_open_report(struct hid_device *device)
651 unsigned size)
652{ 694{
653 struct hid_parser *parser; 695 struct hid_parser *parser;
654 struct hid_item item; 696 struct hid_item item;
697 unsigned int size;
698 __u8 *start;
655 __u8 *end; 699 __u8 *end;
656 int ret; 700 int ret;
657 static int (*dispatch_type[])(struct hid_parser *parser, 701 static int (*dispatch_type[])(struct hid_parser *parser,
@@ -662,6 +706,14 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
662 hid_parser_reserved 706 hid_parser_reserved
663 }; 707 };
664 708
709 if (WARN_ON(device->status & HID_STAT_PARSED))
710 return -EBUSY;
711
712 start = device->dev_rdesc;
713 if (WARN_ON(!start))
714 return -ENODEV;
715 size = device->dev_rsize;
716
665 if (device->driver->report_fixup) 717 if (device->driver->report_fixup)
666 start = device->driver->report_fixup(device, start, &size); 718 start = device->driver->report_fixup(device, start, &size);
667 719
@@ -679,6 +731,15 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
679 parser->device = device; 731 parser->device = device;
680 732
681 end = start + size; 733 end = start + size;
734
735 device->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS,
736 sizeof(struct hid_collection), GFP_KERNEL);
737 if (!device->collection) {
738 ret = -ENOMEM;
739 goto err;
740 }
741 device->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
742
682 ret = -EINVAL; 743 ret = -EINVAL;
683 while ((start = fetch_item(start, end, &item)) != NULL) { 744 while ((start = fetch_item(start, end, &item)) != NULL) {
684 745
@@ -704,6 +765,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
704 goto err; 765 goto err;
705 } 766 }
706 vfree(parser); 767 vfree(parser);
768 device->status |= HID_STAT_PARSED;
707 return 0; 769 return 0;
708 } 770 }
709 } 771 }
@@ -711,9 +773,10 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
711 hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); 773 hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
712err: 774err:
713 vfree(parser); 775 vfree(parser);
776 hid_close_report(device);
714 return ret; 777 return ret;
715} 778}
716EXPORT_SYMBOL_GPL(hid_parse_report); 779EXPORT_SYMBOL_GPL(hid_open_report);
717 780
718/* 781/*
719 * Convert a signed n-bit integer to signed 32-bit integer. Common 782 * Convert a signed n-bit integer to signed 32-bit integer. Common
@@ -1718,12 +1781,14 @@ static int hid_device_probe(struct device *dev)
1718 if (hdrv->probe) { 1781 if (hdrv->probe) {
1719 ret = hdrv->probe(hdev, id); 1782 ret = hdrv->probe(hdev, id);
1720 } else { /* default probe */ 1783 } else { /* default probe */
1721 ret = hid_parse(hdev); 1784 ret = hid_open_report(hdev);
1722 if (!ret) 1785 if (!ret)
1723 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1786 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
1724 } 1787 }
1725 if (ret) 1788 if (ret) {
1789 hid_close_report(hdev);
1726 hdev->driver = NULL; 1790 hdev->driver = NULL;
1791 }
1727 } 1792 }
1728unlock: 1793unlock:
1729 up(&hdev->driver_lock); 1794 up(&hdev->driver_lock);
@@ -1744,6 +1809,7 @@ static int hid_device_remove(struct device *dev)
1744 hdrv->remove(hdev); 1809 hdrv->remove(hdev);
1745 else /* default remove */ 1810 else /* default remove */
1746 hid_hw_stop(hdev); 1811 hid_hw_stop(hdev);
1812 hid_close_report(hdev);
1747 hdev->driver = NULL; 1813 hdev->driver = NULL;
1748 } 1814 }
1749 1815
@@ -2075,6 +2141,16 @@ int hid_add_device(struct hid_device *hdev)
2075 && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE))) 2141 && (hid_ignore(hdev) || (hdev->quirks & HID_QUIRK_IGNORE)))
2076 return -ENODEV; 2142 return -ENODEV;
2077 2143
2144 /*
2145 * Read the device report descriptor once and use as template
2146 * for the driver-specific modifications.
2147 */
2148 ret = hdev->ll_driver->parse(hdev);
2149 if (ret)
2150 return ret;
2151 if (!hdev->dev_rdesc)
2152 return -ENODEV;
2153
2078 /* XXX hack, any other cleaner solution after the driver core 2154 /* XXX hack, any other cleaner solution after the driver core
2079 * is converted to allow more than 20 bytes as the device name? */ 2155 * is converted to allow more than 20 bytes as the device name? */
2080 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, 2156 dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
@@ -2103,7 +2179,6 @@ EXPORT_SYMBOL_GPL(hid_add_device);
2103struct hid_device *hid_allocate_device(void) 2179struct hid_device *hid_allocate_device(void)
2104{ 2180{
2105 struct hid_device *hdev; 2181 struct hid_device *hdev;
2106 unsigned int i;
2107 int ret = -ENOMEM; 2182 int ret = -ENOMEM;
2108 2183
2109 hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); 2184 hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
@@ -2114,23 +2189,13 @@ struct hid_device *hid_allocate_device(void)
2114 hdev->dev.release = hid_device_release; 2189 hdev->dev.release = hid_device_release;
2115 hdev->dev.bus = &hid_bus_type; 2190 hdev->dev.bus = &hid_bus_type;
2116 2191
2117 hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, 2192 hid_close_report(hdev);
2118 sizeof(struct hid_collection), GFP_KERNEL);
2119 if (hdev->collection == NULL)
2120 goto err;
2121 hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS;
2122
2123 for (i = 0; i < HID_REPORT_TYPES; i++)
2124 INIT_LIST_HEAD(&hdev->report_enum[i].report_list);
2125 2193
2126 init_waitqueue_head(&hdev->debug_wait); 2194 init_waitqueue_head(&hdev->debug_wait);
2127 INIT_LIST_HEAD(&hdev->debug_list); 2195 INIT_LIST_HEAD(&hdev->debug_list);
2128 sema_init(&hdev->driver_lock, 1); 2196 sema_init(&hdev->driver_lock, 1);
2129 2197
2130 return hdev; 2198 return hdev;
2131err:
2132 put_device(&hdev->dev);
2133 return ERR_PTR(ret);
2134} 2199}
2135EXPORT_SYMBOL_GPL(hid_allocate_device); 2200EXPORT_SYMBOL_GPL(hid_allocate_device);
2136 2201
@@ -2141,6 +2206,9 @@ static void hid_remove_device(struct hid_device *hdev)
2141 hid_debug_unregister(hdev); 2206 hid_debug_unregister(hdev);
2142 hdev->status &= ~HID_STAT_ADDED; 2207 hdev->status &= ~HID_STAT_ADDED;
2143 } 2208 }
2209 kfree(hdev->dev_rdesc);
2210 hdev->dev_rdesc = NULL;
2211 hdev->dev_rsize = 0;
2144} 2212}
2145 2213
2146/** 2214/**
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 3a95da60fd3e..d8e7cc7f894f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -467,6 +467,8 @@ struct hid_driver;
467struct hid_ll_driver; 467struct hid_ll_driver;
468 468
469struct hid_device { /* device report descriptor */ 469struct hid_device { /* device report descriptor */
470 __u8 *dev_rdesc;
471 unsigned dev_rsize;
470 __u8 *rdesc; 472 __u8 *rdesc;
471 unsigned rsize; 473 unsigned rsize;
472 struct hid_collection *collection; /* List of HID collections */ 474 struct hid_collection *collection; /* List of HID collections */
@@ -735,6 +737,7 @@ void hid_output_report(struct hid_report *report, __u8 *data);
735struct hid_device *hid_allocate_device(void); 737struct hid_device *hid_allocate_device(void);
736struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); 738struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
737int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 739int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
740int hid_open_report(struct hid_device *device);
738int hid_check_keys_pressed(struct hid_device *hid); 741int hid_check_keys_pressed(struct hid_device *hid);
739int hid_connect(struct hid_device *hid, unsigned int connect_mask); 742int hid_connect(struct hid_device *hid, unsigned int connect_mask);
740void hid_disconnect(struct hid_device *hid); 743void hid_disconnect(struct hid_device *hid);
@@ -805,16 +808,7 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput,
805 */ 808 */
806static inline int __must_check hid_parse(struct hid_device *hdev) 809static inline int __must_check hid_parse(struct hid_device *hdev)
807{ 810{
808 int ret; 811 return hid_open_report(hdev);
809
810 if (hdev->status & HID_STAT_PARSED)
811 return 0;
812
813 ret = hdev->ll_driver->parse(hdev);
814 if (!ret)
815 hdev->status |= HID_STAT_PARSED;
816
817 return ret;
818} 812}
819 813
820/** 814/**