diff options
| -rw-r--r-- | drivers/hid/hid-core.c | 58 | ||||
| -rw-r--r-- | include/linux/hid.h | 4 |
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index ae88a97f976e..be52c06dbe30 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -801,6 +801,64 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size) | |||
| 801 | } | 801 | } |
| 802 | EXPORT_SYMBOL_GPL(hid_parse_report); | 802 | EXPORT_SYMBOL_GPL(hid_parse_report); |
| 803 | 803 | ||
| 804 | static const char * const hid_report_names[] = { | ||
| 805 | "HID_INPUT_REPORT", | ||
| 806 | "HID_OUTPUT_REPORT", | ||
| 807 | "HID_FEATURE_REPORT", | ||
| 808 | }; | ||
| 809 | /** | ||
| 810 | * hid_validate_values - validate existing device report's value indexes | ||
| 811 | * | ||
| 812 | * @device: hid device | ||
| 813 | * @type: which report type to examine | ||
| 814 | * @id: which report ID to examine (0 for first) | ||
| 815 | * @field_index: which report field to examine | ||
| 816 | * @report_counts: expected number of values | ||
| 817 | * | ||
| 818 | * Validate the number of values in a given field of a given report, after | ||
| 819 | * parsing. | ||
| 820 | */ | ||
| 821 | struct hid_report *hid_validate_values(struct hid_device *hid, | ||
| 822 | unsigned int type, unsigned int id, | ||
| 823 | unsigned int field_index, | ||
| 824 | unsigned int report_counts) | ||
| 825 | { | ||
| 826 | struct hid_report *report; | ||
| 827 | |||
| 828 | if (type > HID_FEATURE_REPORT) { | ||
| 829 | hid_err(hid, "invalid HID report type %u\n", type); | ||
| 830 | return NULL; | ||
| 831 | } | ||
| 832 | |||
| 833 | if (id >= HID_MAX_IDS) { | ||
| 834 | hid_err(hid, "invalid HID report id %u\n", id); | ||
| 835 | return NULL; | ||
| 836 | } | ||
| 837 | |||
| 838 | /* | ||
| 839 | * Explicitly not using hid_get_report() here since it depends on | ||
| 840 | * ->numbered being checked, which may not always be the case when | ||
| 841 | * drivers go to access report values. | ||
| 842 | */ | ||
| 843 | report = hid->report_enum[type].report_id_hash[id]; | ||
| 844 | if (!report) { | ||
| 845 | hid_err(hid, "missing %s %u\n", hid_report_names[type], id); | ||
| 846 | return NULL; | ||
| 847 | } | ||
| 848 | if (report->maxfield <= field_index) { | ||
| 849 | hid_err(hid, "not enough fields in %s %u\n", | ||
| 850 | hid_report_names[type], id); | ||
| 851 | return NULL; | ||
| 852 | } | ||
| 853 | if (report->field[field_index]->report_count < report_counts) { | ||
| 854 | hid_err(hid, "not enough values in %s %u field %u\n", | ||
| 855 | hid_report_names[type], id, field_index); | ||
| 856 | return NULL; | ||
| 857 | } | ||
| 858 | return report; | ||
| 859 | } | ||
| 860 | EXPORT_SYMBOL_GPL(hid_validate_values); | ||
| 861 | |||
| 804 | /** | 862 | /** |
| 805 | * hid_open_report - open a driver-specific device report | 863 | * hid_open_report - open a driver-specific device report |
| 806 | * | 864 | * |
diff --git a/include/linux/hid.h b/include/linux/hid.h index ee1ffc5e19c9..31b9d299ef6c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -756,6 +756,10 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags); | |||
| 756 | struct hid_device *hid_allocate_device(void); | 756 | struct hid_device *hid_allocate_device(void); |
| 757 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); | 757 | struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); |
| 758 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | 758 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
| 759 | struct hid_report *hid_validate_values(struct hid_device *hid, | ||
| 760 | unsigned int type, unsigned int id, | ||
| 761 | unsigned int field_index, | ||
| 762 | unsigned int report_counts); | ||
| 759 | int hid_open_report(struct hid_device *device); | 763 | int hid_open_report(struct hid_device *device); |
| 760 | int hid_check_keys_pressed(struct hid_device *hid); | 764 | int hid_check_keys_pressed(struct hid_device *hid); |
| 761 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | 765 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); |
