diff options
| -rw-r--r-- | drivers/hid/hid-core.c | 59 | ||||
| -rw-r--r-- | drivers/usb/input/hid-core.c | 67 | ||||
| -rw-r--r-- | drivers/usb/input/hiddev.c | 1 | ||||
| -rw-r--r-- | include/linux/hid.h | 3 |
4 files changed, 68 insertions, 62 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 | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 4fc828041d0f..a20ff61624b1 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
| @@ -169,65 +169,6 @@ done: | |||
| 169 | spin_unlock_irqrestore(&usbhid->inlock, flags); | 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 | * Input interrupt completion handler. | 173 | * Input interrupt completion handler. |
| 233 | */ | 174 | */ |
| @@ -241,7 +182,9 @@ static void hid_irq_in(struct urb *urb) | |||
| 241 | switch (urb->status) { | 182 | switch (urb->status) { |
| 242 | case 0: /* success */ | 183 | case 0: /* success */ |
| 243 | usbhid->retry_delay = 0; | 184 | usbhid->retry_delay = 0; |
| 244 | hid_input_report(HID_INPUT_REPORT, urb, 1); | 185 | hid_input_report(urb->context, HID_INPUT_REPORT, |
| 186 | urb->transfer_buffer, | ||
| 187 | urb->actual_length, 1); | ||
| 245 | break; | 188 | break; |
| 246 | case -EPIPE: /* stall */ | 189 | case -EPIPE: /* stall */ |
| 247 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); | 190 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
| @@ -426,7 +369,8 @@ static void hid_ctrl(struct urb *urb) | |||
| 426 | switch (urb->status) { | 369 | switch (urb->status) { |
| 427 | case 0: /* success */ | 370 | case 0: /* success */ |
| 428 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) | 371 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) |
| 429 | hid_input_report(usbhid->ctrl[usbhid->ctrltail].report->type, urb, 0); | 372 | hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type, |
| 373 | urb->transfer_buffer, urb->actual_length, 0); | ||
| 430 | break; | 374 | break; |
| 431 | case -ESHUTDOWN: /* unplug */ | 375 | case -ESHUTDOWN: /* unplug */ |
| 432 | unplug = 1; | 376 | unplug = 1; |
| @@ -1286,6 +1230,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
| 1286 | hid->hidinput_close = hidinput_close; | 1230 | hid->hidinput_close = hidinput_close; |
| 1287 | #ifdef CONFIG_USB_HIDDEV | 1231 | #ifdef CONFIG_USB_HIDDEV |
| 1288 | hid->hiddev_hid_event = hiddev_hid_event; | 1232 | hid->hiddev_hid_event = hiddev_hid_event; |
| 1233 | hid->hiddev_report_event = hiddev_report_event; | ||
| 1289 | #endif | 1234 | #endif |
| 1290 | 1235 | ||
| 1291 | return hid; | 1236 | return hid; |
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 0c2647eb9eec..114d6c9f64b1 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
| @@ -214,6 +214,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | |||
| 214 | 214 | ||
| 215 | hiddev_send_event(hid, &uref); | 215 | hiddev_send_event(hid, &uref); |
| 216 | } | 216 | } |
| 217 | |||
| 217 | /* | 218 | /* |
| 218 | * fasync file op | 219 | * fasync file op |
| 219 | */ | 220 | */ |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 5a969a137b85..342b4e639acb 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -436,7 +436,7 @@ struct hid_device { /* device report descriptor */ | |||
| 436 | /* hiddev event handler */ | 436 | /* hiddev event handler */ |
| 437 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, | 437 | void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, |
| 438 | struct hid_usage *, __s32); | 438 | struct hid_usage *, __s32); |
| 439 | 439 | void (*hiddev_report_event) (struct hid_device *, struct hid_report *); | |
| 440 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 440 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
| 441 | unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; | 441 | unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; |
| 442 | unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; | 442 | unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; |
| @@ -492,6 +492,7 @@ extern int hidinput_connect(struct hid_device *); | |||
| 492 | extern void hidinput_disconnect(struct hid_device *); | 492 | extern void hidinput_disconnect(struct hid_device *); |
| 493 | 493 | ||
| 494 | int hid_set_field(struct hid_field *, unsigned, __s32); | 494 | int hid_set_field(struct hid_field *, unsigned, __s32); |
| 495 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); | ||
| 495 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); | 496 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
| 496 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); | 497 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); |
| 497 | void hid_output_report(struct hid_report *report, __u8 *data); | 498 | void hid_output_report(struct hid_report *report, __u8 *data); |
