diff options
Diffstat (limited to 'include/linux/hid.h')
-rw-r--r-- | include/linux/hid.h | 46 |
1 files changed, 45 insertions, 1 deletions
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, | |||
738 | s32 hid_snto32(__u32 value, unsigned n); | 744 | s32 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 | */ | ||
755 | static 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 | */ | ||
775 | static 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 |