aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-core.c58
-rw-r--r--include/linux/hid.h4
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}
802EXPORT_SYMBOL_GPL(hid_parse_report); 802EXPORT_SYMBOL_GPL(hid_parse_report);
803 803
804static 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 */
821struct 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}
860EXPORT_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);
756struct hid_device *hid_allocate_device(void); 756struct hid_device *hid_allocate_device(void);
757struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id); 757struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
758int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 758int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
759struct 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);
759int hid_open_report(struct hid_device *device); 763int hid_open_report(struct hid_device *device);
760int hid_check_keys_pressed(struct hid_device *hid); 764int hid_check_keys_pressed(struct hid_device *hid);
761int hid_connect(struct hid_device *hid, unsigned int connect_mask); 765int hid_connect(struct hid_device *hid, unsigned int connect_mask);