aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/usbhid
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 13:48:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-10 13:48:28 -0500
commitf62f61917d72c1fb0101ad405664f6fc868d676b (patch)
treecedeb85a8d1c97dc3be0b667734b0fe4e0dd84b6 /drivers/hid/usbhid
parentd04baa157d1b35cbd27c87b4a13111d9675b61f3 (diff)
parent420174afdc7023c000e5b5b1b6fe9e028470c713 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (68 commits) hid-input/battery: add FEATURE quirk hid-input/battery: remove battery_val hid-input/battery: power-supply type really *is* a battery hid-input/battery: make the battery setup common for INPUTs and FEATUREs hid-input/battery: deal with both FEATURE and INPUT report batteries hid-input/battery: add quirks for battery hid-input/battery: remove apparently redundant kmalloc hid-input: add support for HID devices reporting Battery Strength HID: hid-multitouch: add support 9 new Xiroku devices HID: multitouch: add support for 3M 32" HID: multitouch: add support of Atmel multitouch panels HID: usbhid: defer LED setting to a workqueue HID: usbhid: hid-core: submit queued urbs before suspend HID: usbhid: remove LED_ON HID: emsff: use symbolic name instead of hardcoded PID constant HID: Enable HID_QUIRK_MULTI_INPUT for Trio Linker Plus II HID: Kconfig: fix syntax HID: introduce proper dependency of HID_BATTERY on POWER_SUPPLY HID: multitouch: support PixArt optical touch screen HID: make parser more verbose about parsing errors by default ... Fix up rename/delete conflict in drivers/hid/hid-hyperv.c (removed in staging, moved in this branch) and similarly for the rules for same file in drivers/staging/hv/{Kconfig,Makefile}.
Diffstat (limited to 'drivers/hid/usbhid')
-rw-r--r--drivers/hid/usbhid/hid-core.c241
-rw-r--r--drivers/hid/usbhid/hid-quirks.c4
-rw-r--r--drivers/hid/usbhid/usbhid.h3
-rw-r--r--drivers/hid/usbhid/usbkbd.c64
4 files changed, 206 insertions, 106 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b403fcef0b86..5bf91dbad59d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -197,16 +197,24 @@ static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
197{ 197{
198 struct hid_device *hid = usb_get_intfdata(usbhid->intf); 198 struct hid_device *hid = usb_get_intfdata(usbhid->intf);
199 int kicked; 199 int kicked;
200 int r;
200 201
201 if (!hid) 202 if (!hid)
202 return 0; 203 return 0;
203 204
204 if ((kicked = (usbhid->outhead != usbhid->outtail))) { 205 if ((kicked = (usbhid->outhead != usbhid->outtail))) {
205 dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); 206 dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
207
208 r = usb_autopm_get_interface_async(usbhid->intf);
209 if (r < 0)
210 return r;
211 /* Asynchronously flush queue. */
212 set_bit(HID_OUT_RUNNING, &usbhid->iofl);
206 if (hid_submit_out(hid)) { 213 if (hid_submit_out(hid)) {
207 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 214 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
208 wake_up(&usbhid->wait); 215 usb_autopm_put_interface_async(usbhid->intf);
209 } 216 }
217 wake_up(&usbhid->wait);
210 } 218 }
211 return kicked; 219 return kicked;
212} 220}
@@ -215,6 +223,7 @@ static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
215{ 223{
216 struct hid_device *hid = usb_get_intfdata(usbhid->intf); 224 struct hid_device *hid = usb_get_intfdata(usbhid->intf);
217 int kicked; 225 int kicked;
226 int r;
218 227
219 WARN_ON(hid == NULL); 228 WARN_ON(hid == NULL);
220 if (!hid) 229 if (!hid)
@@ -222,10 +231,17 @@ static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
222 231
223 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { 232 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
224 dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); 233 dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
234
235 r = usb_autopm_get_interface_async(usbhid->intf);
236 if (r < 0)
237 return r;
238 /* Asynchronously flush queue. */
239 set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
225 if (hid_submit_ctrl(hid)) { 240 if (hid_submit_ctrl(hid)) {
226 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 241 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
227 wake_up(&usbhid->wait); 242 usb_autopm_put_interface_async(usbhid->intf);
228 } 243 }
244 wake_up(&usbhid->wait);
229 } 245 }
230 return kicked; 246 return kicked;
231} 247}
@@ -304,30 +320,21 @@ static int hid_submit_out(struct hid_device *hid)
304 report = usbhid->out[usbhid->outtail].report; 320 report = usbhid->out[usbhid->outtail].report;
305 raw_report = usbhid->out[usbhid->outtail].raw_report; 321 raw_report = usbhid->out[usbhid->outtail].raw_report;
306 322
307 r = usb_autopm_get_interface_async(usbhid->intf); 323 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) +
308 if (r < 0) 324 1 + (report->id > 0);
309 return -1; 325 usbhid->urbout->dev = hid_to_usb_dev(hid);
310 326 memcpy(usbhid->outbuf, raw_report,
311 /* 327 usbhid->urbout->transfer_buffer_length);
312 * if the device hasn't been woken, we leave the output 328 kfree(raw_report);
313 * to resume()
314 */
315 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
316 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
317 usbhid->urbout->dev = hid_to_usb_dev(hid);
318 memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
319 kfree(raw_report);
320 329
321 dbg_hid("submitting out urb\n"); 330 dbg_hid("submitting out urb\n");
322 331
323 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { 332 r = usb_submit_urb(usbhid->urbout, GFP_ATOMIC);
324 hid_err(hid, "usb_submit_urb(out) failed\n"); 333 if (r < 0) {
325 usb_autopm_put_interface_async(usbhid->intf); 334 hid_err(hid, "usb_submit_urb(out) failed: %d\n", r);
326 return -1; 335 return r;
327 }
328 usbhid->last_out = jiffies;
329 } 336 }
330 337 usbhid->last_out = jiffies;
331 return 0; 338 return 0;
332} 339}
333 340
@@ -343,50 +350,48 @@ static int hid_submit_ctrl(struct hid_device *hid)
343 raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; 350 raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
344 dir = usbhid->ctrl[usbhid->ctrltail].dir; 351 dir = usbhid->ctrl[usbhid->ctrltail].dir;
345 352
346 r = usb_autopm_get_interface_async(usbhid->intf); 353 len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
347 if (r < 0) 354 if (dir == USB_DIR_OUT) {
348 return -1; 355 usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
349 if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { 356 usbhid->urbctrl->transfer_buffer_length = len;
350 len = ((report->size - 1) >> 3) + 1 + (report->id > 0); 357 memcpy(usbhid->ctrlbuf, raw_report, len);
351 if (dir == USB_DIR_OUT) { 358 kfree(raw_report);
352 usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); 359 } else {
353 usbhid->urbctrl->transfer_buffer_length = len; 360 int maxpacket, padlen;
354 memcpy(usbhid->ctrlbuf, raw_report, len); 361
355 kfree(raw_report); 362 usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
356 } else { 363 maxpacket = usb_maxpacket(hid_to_usb_dev(hid),
357 int maxpacket, padlen; 364 usbhid->urbctrl->pipe, 0);
358 365 if (maxpacket > 0) {
359 usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); 366 padlen = DIV_ROUND_UP(len, maxpacket);
360 maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); 367 padlen *= maxpacket;
361 if (maxpacket > 0) { 368 if (padlen > usbhid->bufsize)
362 padlen = DIV_ROUND_UP(len, maxpacket); 369 padlen = usbhid->bufsize;
363 padlen *= maxpacket; 370 } else
364 if (padlen > usbhid->bufsize) 371 padlen = 0;
365 padlen = usbhid->bufsize; 372 usbhid->urbctrl->transfer_buffer_length = padlen;
366 } else
367 padlen = 0;
368 usbhid->urbctrl->transfer_buffer_length = padlen;
369 }
370 usbhid->urbctrl->dev = hid_to_usb_dev(hid);
371
372 usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
373 usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
374 usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
375 usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
376 usbhid->cr->wLength = cpu_to_le16(len);
377
378 dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
379 usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
380 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
381
382 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
383 usb_autopm_put_interface_async(usbhid->intf);
384 hid_err(hid, "usb_submit_urb(ctrl) failed\n");
385 return -1;
386 }
387 usbhid->last_ctrl = jiffies;
388 } 373 }
389 374 usbhid->urbctrl->dev = hid_to_usb_dev(hid);
375
376 usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
377 usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT :
378 HID_REQ_GET_REPORT;
379 usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) |
380 report->id);
381 usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
382 usbhid->cr->wLength = cpu_to_le16(len);
383
384 dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
385 usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" :
386 "Get_Report",
387 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
388
389 r = usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC);
390 if (r < 0) {
391 hid_err(hid, "usb_submit_urb(ctrl) failed: %d\n", r);
392 return r;
393 }
394 usbhid->last_ctrl = jiffies;
390 return 0; 395 return 0;
391} 396}
392 397
@@ -423,11 +428,8 @@ static void hid_irq_out(struct urb *urb)
423 else 428 else
424 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); 429 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
425 430
426 if (usbhid->outhead != usbhid->outtail) { 431 if (usbhid->outhead != usbhid->outtail && !hid_submit_out(hid)) {
427 if (hid_submit_out(hid)) { 432 /* Successfully submitted next urb in queue */
428 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
429 wake_up(&usbhid->wait);
430 }
431 spin_unlock_irqrestore(&usbhid->lock, flags); 433 spin_unlock_irqrestore(&usbhid->lock, flags);
432 return; 434 return;
433 } 435 }
@@ -474,13 +476,9 @@ static void hid_ctrl(struct urb *urb)
474 else 476 else
475 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); 477 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
476 478
477 if (usbhid->ctrlhead != usbhid->ctrltail) { 479 if (usbhid->ctrlhead != usbhid->ctrltail && !hid_submit_ctrl(hid)) {
478 if (hid_submit_ctrl(hid)) { 480 /* Successfully submitted next urb in queue */
479 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
480 wake_up(&usbhid->wait);
481 }
482 spin_unlock(&usbhid->lock); 481 spin_unlock(&usbhid->lock);
483 usb_autopm_put_interface_async(usbhid->intf);
484 return; 482 return;
485 } 483 }
486 484
@@ -515,9 +513,23 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
515 usbhid->out[usbhid->outhead].report = report; 513 usbhid->out[usbhid->outhead].report = report;
516 usbhid->outhead = head; 514 usbhid->outhead = head;
517 515
516 /* Try to awake from autosuspend... */
517 if (usb_autopm_get_interface_async(usbhid->intf) < 0)
518 return;
519
520 /*
521 * But if still suspended, leave urb enqueued, don't submit.
522 * Submission will occur if/when resume() drains the queue.
523 */
524 if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl))
525 return;
526
518 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) { 527 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
519 if (hid_submit_out(hid)) 528 if (hid_submit_out(hid)) {
520 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 529 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
530 usb_autopm_put_interface_async(usbhid->intf);
531 }
532 wake_up(&usbhid->wait);
521 } else { 533 } else {
522 /* 534 /*
523 * the queue is known to run 535 * the queue is known to run
@@ -549,9 +561,23 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
549 usbhid->ctrl[usbhid->ctrlhead].dir = dir; 561 usbhid->ctrl[usbhid->ctrlhead].dir = dir;
550 usbhid->ctrlhead = head; 562 usbhid->ctrlhead = head;
551 563
564 /* Try to awake from autosuspend... */
565 if (usb_autopm_get_interface_async(usbhid->intf) < 0)
566 return;
567
568 /*
569 * If already suspended, leave urb enqueued, but don't submit.
570 * Submission will occur if/when resume() drains the queue.
571 */
572 if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl))
573 return;
574
552 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) { 575 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
553 if (hid_submit_ctrl(hid)) 576 if (hid_submit_ctrl(hid)) {
554 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 577 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
578 usb_autopm_put_interface_async(usbhid->intf);
579 }
580 wake_up(&usbhid->wait);
555 } else { 581 } else {
556 /* 582 /*
557 * the queue is known to run 583 * the queue is known to run
@@ -576,6 +602,30 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
576} 602}
577EXPORT_SYMBOL_GPL(usbhid_submit_report); 603EXPORT_SYMBOL_GPL(usbhid_submit_report);
578 604
605/* Workqueue routine to send requests to change LEDs */
606static void hid_led(struct work_struct *work)
607{
608 struct usbhid_device *usbhid =
609 container_of(work, struct usbhid_device, led_work);
610 struct hid_device *hid = usbhid->hid;
611 struct hid_field *field;
612 unsigned long flags;
613
614 field = hidinput_get_led_field(hid);
615 if (!field) {
616 hid_warn(hid, "LED event field not found\n");
617 return;
618 }
619
620 spin_lock_irqsave(&usbhid->lock, flags);
621 if (!test_bit(HID_DISCONNECTED, &usbhid->iofl)) {
622 usbhid->ledcount = hidinput_count_leds(hid);
623 hid_dbg(usbhid->hid, "New ledcount = %u\n", usbhid->ledcount);
624 __usbhid_submit_report(hid, field->report, USB_DIR_OUT);
625 }
626 spin_unlock_irqrestore(&usbhid->lock, flags);
627}
628
579static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 629static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
580{ 630{
581 struct hid_device *hid = input_get_drvdata(dev); 631 struct hid_device *hid = input_get_drvdata(dev);
@@ -595,17 +645,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
595 return -1; 645 return -1;
596 } 646 }
597 647
648 spin_lock_irqsave(&usbhid->lock, flags);
598 hid_set_field(field, offset, value); 649 hid_set_field(field, offset, value);
599 if (value) { 650 spin_unlock_irqrestore(&usbhid->lock, flags);
600 spin_lock_irqsave(&usbhid->lock, flags); 651
601 usbhid->ledcount++; 652 /*
602 spin_unlock_irqrestore(&usbhid->lock, flags); 653 * Defer performing requested LED action.
603 } else { 654 * This is more likely gather all LED changes into a single URB.
604 spin_lock_irqsave(&usbhid->lock, flags); 655 */
605 usbhid->ledcount--; 656 schedule_work(&usbhid->led_work);
606 spin_unlock_irqrestore(&usbhid->lock, flags);
607 }
608 usbhid_submit_report(hid, field->report, USB_DIR_OUT);
609 657
610 return 0; 658 return 0;
611} 659}
@@ -1100,7 +1148,7 @@ static void usbhid_stop(struct hid_device *hid)
1100 return; 1148 return;
1101 1149
1102 clear_bit(HID_STARTED, &usbhid->iofl); 1150 clear_bit(HID_STARTED, &usbhid->iofl);
1103 spin_lock_irq(&usbhid->lock); /* Sync with error handler */ 1151 spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
1104 set_bit(HID_DISCONNECTED, &usbhid->iofl); 1152 set_bit(HID_DISCONNECTED, &usbhid->iofl);
1105 spin_unlock_irq(&usbhid->lock); 1153 spin_unlock_irq(&usbhid->lock);
1106 usb_kill_urb(usbhid->urbin); 1154 usb_kill_urb(usbhid->urbin);
@@ -1234,6 +1282,8 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1234 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); 1282 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
1235 spin_lock_init(&usbhid->lock); 1283 spin_lock_init(&usbhid->lock);
1236 1284
1285 INIT_WORK(&usbhid->led_work, hid_led);
1286
1237 ret = hid_add_device(hid); 1287 ret = hid_add_device(hid);
1238 if (ret) { 1288 if (ret) {
1239 if (ret != -ENODEV) 1289 if (ret != -ENODEV)
@@ -1266,6 +1316,7 @@ static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
1266{ 1316{
1267 del_timer_sync(&usbhid->io_retry); 1317 del_timer_sync(&usbhid->io_retry);
1268 cancel_work_sync(&usbhid->reset_work); 1318 cancel_work_sync(&usbhid->reset_work);
1319 cancel_work_sync(&usbhid->led_work);
1269} 1320}
1270 1321
1271static void hid_cease_io(struct usbhid_device *usbhid) 1322static void hid_cease_io(struct usbhid_device *usbhid)
@@ -1367,16 +1418,6 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1367 return -EIO; 1418 return -EIO;
1368 } 1419 }
1369 1420
1370 if (!ignoreled && PMSG_IS_AUTO(message)) {
1371 spin_lock_irq(&usbhid->lock);
1372 if (test_bit(HID_LED_ON, &usbhid->iofl)) {
1373 spin_unlock_irq(&usbhid->lock);
1374 usbhid_mark_busy(usbhid);
1375 return -EBUSY;
1376 }
1377 spin_unlock_irq(&usbhid->lock);
1378 }
1379
1380 hid_cancel_delayed_stuff(usbhid); 1421 hid_cancel_delayed_stuff(usbhid);
1381 hid_cease_io(usbhid); 1422 hid_cease_io(usbhid);
1382 1423
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 5028d60a22a1..c831af937481 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -47,6 +47,7 @@ static const struct hid_blacklist {
47 47
48 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, 48 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
49 49
50 { USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II, HID_QUIRK_MULTI_INPUT },
50 { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, 51 { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
51 { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT }, 52 { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
52 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 53 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
@@ -67,6 +68,9 @@ static const struct hid_blacklist {
67 { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, 68 { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET },
68 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, 69 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
69 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 70 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
71 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
72 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
73 { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS },
70 { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, 74 { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
71 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, 75 { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET },
72 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 76 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 1673cac93d77..cb8f703efde5 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -55,7 +55,6 @@ struct usb_interface *usbhid_find_interface(int minor);
55#define HID_STARTED 8 55#define HID_STARTED 8
56#define HID_REPORTED_IDLE 9 56#define HID_REPORTED_IDLE 9
57#define HID_KEYS_PRESSED 10 57#define HID_KEYS_PRESSED 10
58#define HID_LED_ON 11
59 58
60/* 59/*
61 * USB-specific HID struct, to be pointed to 60 * USB-specific HID struct, to be pointed to
@@ -97,6 +96,8 @@ struct usbhid_device {
97 struct work_struct reset_work; /* Task context for resets */ 96 struct work_struct reset_work; /* Task context for resets */
98 wait_queue_head_t wait; /* For sleeping */ 97 wait_queue_head_t wait; /* For sleeping */
99 int ledcount; /* counting the number of active leds */ 98 int ledcount; /* counting the number of active leds */
99
100 struct work_struct led_work; /* Task context for setting LEDs */
100}; 101};
101 102
102#define hid_to_usb_dev(hid_dev) \ 103#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index bc445d7e3bf5..796086980f4a 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -64,6 +64,32 @@ static const unsigned char usb_kbd_keycode[256] = {
64 150,158,159,128,136,177,178,176,142,152,173,140 64 150,158,159,128,136,177,178,176,142,152,173,140
65}; 65};
66 66
67
68/**
69 * struct usb_kbd - state of each attached keyboard
70 * @dev: input device associated with this keyboard
71 * @usbdev: usb device associated with this keyboard
72 * @old: data received in the past from the @irq URB representing which
73 * keys were pressed. By comparing with the current list of keys
74 * that are pressed, we are able to see key releases.
75 * @irq: URB for receiving a list of keys that are pressed when a
76 * new key is pressed or a key that was pressed is released.
77 * @led: URB for sending LEDs (e.g. numlock, ...)
78 * @newleds: data that will be sent with the @led URB representing which LEDs
79 should be on
80 * @name: Name of the keyboard. @dev's name field points to this buffer
81 * @phys: Physical path of the keyboard. @dev's phys field points to this
82 * buffer
83 * @new: Buffer for the @irq URB
84 * @cr: Control request for @led URB
85 * @leds: Buffer for the @led URB
86 * @new_dma: DMA address for @irq URB
87 * @leds_dma: DMA address for @led URB
88 * @leds_lock: spinlock that protects @leds, @newleds, and @led_urb_submitted
89 * @led_urb_submitted: indicates whether @led is in progress, i.e. it has been
90 * submitted and its completion handler has not returned yet
91 * without resubmitting @led
92 */
67struct usb_kbd { 93struct usb_kbd {
68 struct input_dev *dev; 94 struct input_dev *dev;
69 struct usb_device *usbdev; 95 struct usb_device *usbdev;
@@ -78,6 +104,10 @@ struct usb_kbd {
78 unsigned char *leds; 104 unsigned char *leds;
79 dma_addr_t new_dma; 105 dma_addr_t new_dma;
80 dma_addr_t leds_dma; 106 dma_addr_t leds_dma;
107
108 spinlock_t leds_lock;
109 bool led_urb_submitted;
110
81}; 111};
82 112
83static void usb_kbd_irq(struct urb *urb) 113static void usb_kbd_irq(struct urb *urb)
@@ -136,44 +166,66 @@ resubmit:
136static int usb_kbd_event(struct input_dev *dev, unsigned int type, 166static int usb_kbd_event(struct input_dev *dev, unsigned int type,
137 unsigned int code, int value) 167 unsigned int code, int value)
138{ 168{
169 unsigned long flags;
139 struct usb_kbd *kbd = input_get_drvdata(dev); 170 struct usb_kbd *kbd = input_get_drvdata(dev);
140 171
141 if (type != EV_LED) 172 if (type != EV_LED)
142 return -1; 173 return -1;
143 174
175 spin_lock_irqsave(&kbd->leds_lock, flags);
144 kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) | 176 kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
145 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) | 177 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
146 (!!test_bit(LED_NUML, dev->led)); 178 (!!test_bit(LED_NUML, dev->led));
147 179
148 if (kbd->led->status == -EINPROGRESS) 180 if (kbd->led_urb_submitted){
181 spin_unlock_irqrestore(&kbd->leds_lock, flags);
149 return 0; 182 return 0;
183 }
150 184
151 if (*(kbd->leds) == kbd->newleds) 185 if (*(kbd->leds) == kbd->newleds){
186 spin_unlock_irqrestore(&kbd->leds_lock, flags);
152 return 0; 187 return 0;
188 }
153 189
154 *(kbd->leds) = kbd->newleds; 190 *(kbd->leds) = kbd->newleds;
191
155 kbd->led->dev = kbd->usbdev; 192 kbd->led->dev = kbd->usbdev;
156 if (usb_submit_urb(kbd->led, GFP_ATOMIC)) 193 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
157 pr_err("usb_submit_urb(leds) failed\n"); 194 pr_err("usb_submit_urb(leds) failed\n");
158 195 else
196 kbd->led_urb_submitted = true;
197
198 spin_unlock_irqrestore(&kbd->leds_lock, flags);
199
159 return 0; 200 return 0;
160} 201}
161 202
162static void usb_kbd_led(struct urb *urb) 203static void usb_kbd_led(struct urb *urb)
163{ 204{
205 unsigned long flags;
164 struct usb_kbd *kbd = urb->context; 206 struct usb_kbd *kbd = urb->context;
165 207
166 if (urb->status) 208 if (urb->status)
167 hid_warn(urb->dev, "led urb status %d received\n", 209 hid_warn(urb->dev, "led urb status %d received\n",
168 urb->status); 210 urb->status);
169 211
170 if (*(kbd->leds) == kbd->newleds) 212 spin_lock_irqsave(&kbd->leds_lock, flags);
213
214 if (*(kbd->leds) == kbd->newleds){
215 kbd->led_urb_submitted = false;
216 spin_unlock_irqrestore(&kbd->leds_lock, flags);
171 return; 217 return;
218 }
172 219
173 *(kbd->leds) = kbd->newleds; 220 *(kbd->leds) = kbd->newleds;
221
174 kbd->led->dev = kbd->usbdev; 222 kbd->led->dev = kbd->usbdev;
175 if (usb_submit_urb(kbd->led, GFP_ATOMIC)) 223 if (usb_submit_urb(kbd->led, GFP_ATOMIC)){
176 hid_err(urb->dev, "usb_submit_urb(leds) failed\n"); 224 hid_err(urb->dev, "usb_submit_urb(leds) failed\n");
225 kbd->led_urb_submitted = false;
226 }
227 spin_unlock_irqrestore(&kbd->leds_lock, flags);
228
177} 229}
178 230
179static int usb_kbd_open(struct input_dev *dev) 231static int usb_kbd_open(struct input_dev *dev)
@@ -252,6 +304,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
252 304
253 kbd->usbdev = dev; 305 kbd->usbdev = dev;
254 kbd->dev = input_dev; 306 kbd->dev = input_dev;
307 spin_lock_init(&kbd->leds_lock);
255 308
256 if (dev->manufacturer) 309 if (dev->manufacturer)
257 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name)); 310 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
@@ -334,6 +387,7 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
334 if (kbd) { 387 if (kbd) {
335 usb_kill_urb(kbd->irq); 388 usb_kill_urb(kbd->irq);
336 input_unregister_device(kbd->dev); 389 input_unregister_device(kbd->dev);
390 usb_kill_urb(kbd->led);
337 usb_kbd_free_mem(interface_to_usbdev(intf), kbd); 391 usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
338 kfree(kbd); 392 kfree(kbd);
339 } 393 }