aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2006-12-08 12:41:17 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-12-08 13:43:17 -0500
commitaa8de2f038baec993f07ef66fb3e94481d1ec22b (patch)
treefeb358b58c3eaf94381d9cc89306af0c8808d132
parentaa938f7974b82cfd9ee955031987344f332b7c77 (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>
-rw-r--r--drivers/hid/hid-core.c59
-rw-r--r--drivers/usb/input/hid-core.c67
-rw-r--r--drivers/usb/input/hiddev.c1
-rw-r--r--include/linux/hid.h3
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}
941EXPORT_SYMBOL_GPL(hid_set_field); 941EXPORT_SYMBOL_GPL(hid_set_field);
942 942
943int 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}
1000EXPORT_SYMBOL_GPL(hid_input_report);
1001
943MODULE_LICENSE(DRIVER_LICENSE); 1002MODULE_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
173static 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 *);
492extern void hidinput_disconnect(struct hid_device *); 492extern void hidinput_disconnect(struct hid_device *);
493 493
494int hid_set_field(struct hid_field *, unsigned, __s32); 494int hid_set_field(struct hid_field *, unsigned, __s32);
495int hid_input_report(struct hid_device *, int type, u8 *, int, int);
495int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); 496int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
496void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); 497void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt);
497void hid_output_report(struct hid_report *report, __u8 *data); 498void hid_output_report(struct hid_report *report, __u8 *data);