diff options
author | Jiri Kosina <jkosina@suse.cz> | 2006-12-08 12:41:17 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-08 13:43:17 -0500 |
commit | aa8de2f038baec993f07ef66fb3e94481d1ec22b (patch) | |
tree | feb358b58c3eaf94381d9cc89306af0c8808d132 /drivers/hid/hid-core.c | |
parent | aa938f7974b82cfd9ee955031987344f332b7c77 (diff) |
[PATCH] Generic HID layer - input and event reporting
hid_input_report() was needlessly USB-specific in USB HID. This patch
makes the function independent of HID implementation and fixes all
the current users. Bluetooth patches comply with this prototype.
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r-- | drivers/hid/hid-core.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1dd9e4f0df1e..18c2b3cf6bcc 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -940,5 +940,64 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) | |||
940 | } | 940 | } |
941 | EXPORT_SYMBOL_GPL(hid_set_field); | 941 | EXPORT_SYMBOL_GPL(hid_set_field); |
942 | 942 | ||
943 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | ||
944 | { | ||
945 | struct hid_report_enum *report_enum = hid->report_enum + type; | ||
946 | struct hid_report *report; | ||
947 | int n, rsize; | ||
948 | |||
949 | if (!hid) | ||
950 | return -ENODEV; | ||
951 | |||
952 | if (!size) { | ||
953 | dbg("empty report"); | ||
954 | return -1; | ||
955 | } | ||
956 | |||
957 | #ifdef DEBUG_DATA | ||
958 | printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); | ||
959 | #endif | ||
960 | |||
961 | n = 0; /* Normally report number is 0 */ | ||
962 | if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ | ||
963 | n = *data++; | ||
964 | size--; | ||
965 | } | ||
966 | |||
967 | #ifdef DEBUG_DATA | ||
968 | { | ||
969 | int i; | ||
970 | printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, size); | ||
971 | for (i = 0; i < size; i++) | ||
972 | printk(" %02x", data[i]); | ||
973 | printk("\n"); | ||
974 | } | ||
975 | #endif | ||
976 | |||
977 | if (!(report = report_enum->report_id_hash[n])) { | ||
978 | dbg("undefined report_id %d received", n); | ||
979 | return -1; | ||
980 | } | ||
981 | |||
982 | rsize = ((report->size - 1) >> 3) + 1; | ||
983 | |||
984 | if (size < rsize) { | ||
985 | dbg("report %d is too short, (%d < %d)", report->id, size, rsize); | ||
986 | return -1; | ||
987 | } | ||
988 | |||
989 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) | ||
990 | hid->hiddev_report_event(hid, report); | ||
991 | |||
992 | for (n = 0; n < report->maxfield; n++) | ||
993 | hid_input_field(hid, report->field[n], data, interrupt); | ||
994 | |||
995 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
996 | hidinput_report_event(hid, report); | ||
997 | |||
998 | return 0; | ||
999 | } | ||
1000 | EXPORT_SYMBOL_GPL(hid_input_report); | ||
1001 | |||
943 | MODULE_LICENSE(DRIVER_LICENSE); | 1002 | MODULE_LICENSE(DRIVER_LICENSE); |
944 | 1003 | ||