Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Jiri Kosina and committed by
Greg Kroah-Hartman
aa8de2f0 aa938f79

+68 -62
+59
drivers/hid/hid-core.c
··· 940 940 } 941 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 1002 MODULE_LICENSE(DRIVER_LICENSE); 944 1003
+6 -61
drivers/usb/input/hid-core.c
··· 169 169 spin_unlock_irqrestore(&usbhid->inlock, flags); 170 170 } 171 171 172 - 173 - static int hid_input_report(int type, struct urb *urb, int interrupt) 174 - { 175 - struct hid_device *hid = urb->context; 176 - struct hid_report_enum *report_enum = hid->report_enum + type; 177 - u8 *data = urb->transfer_buffer; 178 - int len = urb->actual_length; 179 - struct hid_report *report; 180 - int n, size; 181 - 182 - if (!len) { 183 - dbg("empty report"); 184 - return -1; 185 - } 186 - 187 - #ifdef DEBUG_DATA 188 - printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); 189 - #endif 190 - 191 - n = 0; /* Normally report number is 0 */ 192 - if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ 193 - n = *data++; 194 - len--; 195 - } 196 - 197 - #ifdef DEBUG_DATA 198 - { 199 - int i; 200 - printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); 201 - for (i = 0; i < len; i++) 202 - printk(" %02x", data[i]); 203 - printk("\n"); 204 - } 205 - #endif 206 - 207 - if (!(report = report_enum->report_id_hash[n])) { 208 - dbg("undefined report_id %d received", n); 209 - return -1; 210 - } 211 - 212 - size = ((report->size - 1) >> 3) + 1; 213 - 214 - if (len < size) { 215 - dbg("report %d is too short, (%d < %d)", report->id, len, size); 216 - memset(data + len, 0, size - len); 217 - } 218 - 219 - if (hid->claimed & HID_CLAIMED_HIDDEV) 220 - hiddev_report_event(hid, report); 221 - 222 - for (n = 0; n < report->maxfield; n++) 223 - hid_input_field(hid, report->field[n], data, interrupt); 224 - 225 - if (hid->claimed & HID_CLAIMED_INPUT) 226 - hidinput_report_event(hid, report); 227 - 228 - return 0; 229 - } 230 - 231 172 /* 232 173 * Input interrupt completion handler. 233 174 */ ··· 182 241 switch (urb->status) { 183 242 case 0: /* success */ 184 243 usbhid->retry_delay = 0; 185 - hid_input_report(HID_INPUT_REPORT, urb, 1); 244 + hid_input_report(urb->context, HID_INPUT_REPORT, 245 + urb->transfer_buffer, 246 + urb->actual_length, 1); 186 247 break; 187 248 case -EPIPE: /* stall */ 188 249 clear_bit(HID_IN_RUNNING, &usbhid->iofl); ··· 369 426 switch (urb->status) { 370 427 case 0: /* success */ 371 428 if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) 372 - hid_input_report(usbhid->ctrl[usbhid->ctrltail].report->type, urb, 0); 429 + hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type, 430 + urb->transfer_buffer, urb->actual_length, 0); 373 431 break; 374 432 case -ESHUTDOWN: /* unplug */ 375 433 unplug = 1; ··· 1230 1286 hid->hidinput_close = hidinput_close; 1231 1287 #ifdef CONFIG_USB_HIDDEV 1232 1288 hid->hiddev_hid_event = hiddev_hid_event; 1289 + hid->hiddev_report_event = hiddev_report_event; 1233 1290 #endif 1234 1291 1235 1292 return hid;
+1
drivers/usb/input/hiddev.c
··· 214 214 215 215 hiddev_send_event(hid, &uref); 216 216 } 217 + 217 218 /* 218 219 * fasync file op 219 220 */
+2 -1
include/linux/hid.h
··· 436 436 /* hiddev event handler */ 437 437 void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, 438 438 struct hid_usage *, __s32); 439 - 439 + void (*hiddev_report_event) (struct hid_device *, struct hid_report *); 440 440 #ifdef CONFIG_USB_HIDINPUT_POWERBOOK 441 441 unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; 442 442 unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; ··· 492 492 extern void hidinput_disconnect(struct hid_device *); 493 493 494 494 int hid_set_field(struct hid_field *, unsigned, __s32); 495 + int hid_input_report(struct hid_device *, int type, u8 *, int, int); 495 496 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); 496 497 void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); 497 498 void hid_output_report(struct hid_report *report, __u8 *data);