aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-core.c24
-rw-r--r--include/linux/hid.h46
2 files changed, 66 insertions, 4 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index ff75cabf7393..680068c0c46a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1267,7 +1267,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1267 if (!hid) 1267 if (!hid)
1268 return -ENODEV; 1268 return -ENODEV;
1269 1269
1270 if (down_trylock(&hid->driver_lock)) 1270 if (down_trylock(&hid->driver_input_lock))
1271 return -EBUSY; 1271 return -EBUSY;
1272 1272
1273 if (!hid->driver) { 1273 if (!hid->driver) {
@@ -1324,7 +1324,7 @@ nomem:
1324 ret = hid_report_raw_event(hid, type, data, size, interrupt); 1324 ret = hid_report_raw_event(hid, type, data, size, interrupt);
1325 1325
1326unlock: 1326unlock:
1327 up(&hid->driver_lock); 1327 up(&hid->driver_input_lock);
1328 return ret; 1328 return ret;
1329} 1329}
1330EXPORT_SYMBOL_GPL(hid_input_report); 1330EXPORT_SYMBOL_GPL(hid_input_report);
@@ -1845,6 +1845,11 @@ static int hid_device_probe(struct device *dev)
1845 1845
1846 if (down_interruptible(&hdev->driver_lock)) 1846 if (down_interruptible(&hdev->driver_lock))
1847 return -EINTR; 1847 return -EINTR;
1848 if (down_interruptible(&hdev->driver_input_lock)) {
1849 ret = -EINTR;
1850 goto unlock_driver_lock;
1851 }
1852 hdev->io_started = false;
1848 1853
1849 if (!hdev->driver) { 1854 if (!hdev->driver) {
1850 id = hid_match_device(hdev, hdrv); 1855 id = hid_match_device(hdev, hdrv);
@@ -1867,6 +1872,9 @@ static int hid_device_probe(struct device *dev)
1867 } 1872 }
1868 } 1873 }
1869unlock: 1874unlock:
1875 if (!hdev->io_started)
1876 up(&hdev->driver_input_lock);
1877unlock_driver_lock:
1870 up(&hdev->driver_lock); 1878 up(&hdev->driver_lock);
1871 return ret; 1879 return ret;
1872} 1880}
@@ -1875,9 +1883,15 @@ static int hid_device_remove(struct device *dev)
1875{ 1883{
1876 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 1884 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1877 struct hid_driver *hdrv; 1885 struct hid_driver *hdrv;
1886 int ret = 0;
1878 1887
1879 if (down_interruptible(&hdev->driver_lock)) 1888 if (down_interruptible(&hdev->driver_lock))
1880 return -EINTR; 1889 return -EINTR;
1890 if (down_interruptible(&hdev->driver_input_lock)) {
1891 ret = -EINTR;
1892 goto unlock_driver_lock;
1893 }
1894 hdev->io_started = false;
1881 1895
1882 hdrv = hdev->driver; 1896 hdrv = hdev->driver;
1883 if (hdrv) { 1897 if (hdrv) {
@@ -1889,8 +1903,11 @@ static int hid_device_remove(struct device *dev)
1889 hdev->driver = NULL; 1903 hdev->driver = NULL;
1890 } 1904 }
1891 1905
1906 if (!hdev->io_started)
1907 up(&hdev->driver_input_lock);
1908unlock_driver_lock:
1892 up(&hdev->driver_lock); 1909 up(&hdev->driver_lock);
1893 return 0; 1910 return ret;
1894} 1911}
1895 1912
1896static ssize_t modalias_show(struct device *dev, struct device_attribute *a, 1913static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
@@ -2329,6 +2346,7 @@ struct hid_device *hid_allocate_device(void)
2329 init_waitqueue_head(&hdev->debug_wait); 2346 init_waitqueue_head(&hdev->debug_wait);
2330 INIT_LIST_HEAD(&hdev->debug_list); 2347 INIT_LIST_HEAD(&hdev->debug_list);
2331 sema_init(&hdev->driver_lock, 1); 2348 sema_init(&hdev->driver_lock, 1);
2349 sema_init(&hdev->driver_input_lock, 1);
2332 2350
2333 return hdev; 2351 return hdev;
2334} 2352}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index e14b465b1146..895b85639dec 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -456,7 +456,8 @@ struct hid_device { /* device report descriptor */
456 unsigned country; /* HID country */ 456 unsigned country; /* HID country */
457 struct hid_report_enum report_enum[HID_REPORT_TYPES]; 457 struct hid_report_enum report_enum[HID_REPORT_TYPES];
458 458
459 struct semaphore driver_lock; /* protects the current driver */ 459 struct semaphore driver_lock; /* protects the current driver, except during input */
460 struct semaphore driver_input_lock; /* protects the current driver */
460 struct device dev; /* device */ 461 struct device dev; /* device */
461 struct hid_driver *driver; 462 struct hid_driver *driver;
462 struct hid_ll_driver *ll_driver; 463 struct hid_ll_driver *ll_driver;
@@ -477,6 +478,7 @@ struct hid_device { /* device report descriptor */
477 unsigned int status; /* see STAT flags above */ 478 unsigned int status; /* see STAT flags above */
478 unsigned claimed; /* Claimed by hidinput, hiddev? */ 479 unsigned claimed; /* Claimed by hidinput, hiddev? */
479 unsigned quirks; /* Various quirks the device can pull on us */ 480 unsigned quirks; /* Various quirks the device can pull on us */
481 bool io_started; /* Protected by driver_lock. If IO has started */
480 482
481 struct list_head inputs; /* The list of inputs */ 483 struct list_head inputs; /* The list of inputs */
482 void *hiddev; /* The hiddev structure */ 484 void *hiddev; /* The hiddev structure */
@@ -599,6 +601,10 @@ struct hid_usage_id {
599 * @resume: invoked on resume if device was not reset (NULL means nop) 601 * @resume: invoked on resume if device was not reset (NULL means nop)
600 * @reset_resume: invoked on resume if device was reset (NULL means nop) 602 * @reset_resume: invoked on resume if device was reset (NULL means nop)
601 * 603 *
604 * probe should return -errno on error, or 0 on success. During probe,
605 * input will not be passed to raw_event unless hid_device_io_start is
606 * called.
607 *
602 * raw_event and event should return 0 on no action performed, 1 when no 608 * raw_event and event should return 0 on no action performed, 1 when no
603 * further processing should be done and negative on error 609 * further processing should be done and negative on error
604 * 610 *
@@ -738,6 +744,44 @@ const struct hid_device_id *hid_match_id(struct hid_device *hdev,
738s32 hid_snto32(__u32 value, unsigned n); 744s32 hid_snto32(__u32 value, unsigned n);
739 745
740/** 746/**
747 * hid_device_io_start - enable HID input during probe, remove
748 *
749 * @hid - the device
750 *
751 * This should only be called during probe or remove and only be
752 * called by the thread calling probe or remove. It will allow
753 * incoming packets to be delivered to the driver.
754 */
755static inline void hid_device_io_start(struct hid_device *hid) {
756 if (hid->io_started) {
757 dev_warn(&hid->dev, "io already started");
758 return;
759 }
760 hid->io_started = true;
761 up(&hid->driver_input_lock);
762}
763
764/**
765 * hid_device_io_stop - disable HID input during probe, remove
766 *
767 * @hid - the device
768 *
769 * Should only be called after hid_device_io_start. It will prevent
770 * incoming packets from going to the driver for the duration of
771 * probe, remove. If called during probe, packets will still go to the
772 * driver after probe is complete. This function should only be called
773 * by the thread calling probe or remove.
774 */
775static inline void hid_device_io_stop(struct hid_device *hid) {
776 if (!hid->io_started) {
777 dev_warn(&hid->dev, "io already stopped");
778 return;
779 }
780 hid->io_started = false;
781 down(&hid->driver_input_lock);
782}
783
784/**
741 * hid_map_usage - map usage input bits 785 * hid_map_usage - map usage input bits
742 * 786 *
743 * @hidinput: hidinput which we are interested in 787 * @hidinput: hidinput which we are interested in