diff options
Diffstat (limited to 'drivers/hid/hid-logitech-dj.c')
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 71 |
1 files changed, 29 insertions, 42 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index d44ea58c597e..5e8a7ed42344 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -156,6 +156,14 @@ static const char media_descriptor[] = { | |||
156 | /* Maximum size of all defined hid reports in bytes (including report id) */ | 156 | /* Maximum size of all defined hid reports in bytes (including report id) */ |
157 | #define MAX_REPORT_SIZE 8 | 157 | #define MAX_REPORT_SIZE 8 |
158 | 158 | ||
159 | /* Make sure all descriptors are present here */ | ||
160 | #define MAX_RDESC_SIZE \ | ||
161 | (sizeof(kbd_descriptor) + \ | ||
162 | sizeof(mse_descriptor) + \ | ||
163 | sizeof(consumer_descriptor) + \ | ||
164 | sizeof(syscontrol_descriptor) + \ | ||
165 | sizeof(media_descriptor)) | ||
166 | |||
159 | /* Number of possible hid report types that can be created by this driver. | 167 | /* Number of possible hid report types that can be created by this driver. |
160 | * | 168 | * |
161 | * Right now, RF report types have the same report types (or report id's) | 169 | * Right now, RF report types have the same report types (or report id's) |
@@ -474,9 +482,17 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | |||
474 | return 0; | 482 | return 0; |
475 | } | 483 | } |
476 | 484 | ||
485 | static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size) | ||
486 | { | ||
487 | memcpy(*rdesc + *rsize, data, size); | ||
488 | *rsize += size; | ||
489 | } | ||
490 | |||
477 | static int logi_dj_ll_parse(struct hid_device *hid) | 491 | static int logi_dj_ll_parse(struct hid_device *hid) |
478 | { | 492 | { |
479 | struct dj_device *djdev = hid->driver_data; | 493 | struct dj_device *djdev = hid->driver_data; |
494 | unsigned int rsize = 0; | ||
495 | char *rdesc; | ||
480 | int retval; | 496 | int retval; |
481 | 497 | ||
482 | dbg_hid("%s\n", __func__); | 498 | dbg_hid("%s\n", __func__); |
@@ -484,70 +500,38 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
484 | djdev->hdev->version = 0x0111; | 500 | djdev->hdev->version = 0x0111; |
485 | djdev->hdev->country = 0x00; | 501 | djdev->hdev->country = 0x00; |
486 | 502 | ||
503 | rdesc = kmalloc(MAX_RDESC_SIZE, GFP_KERNEL); | ||
504 | if (!rdesc) | ||
505 | return -ENOMEM; | ||
506 | |||
487 | if (djdev->reports_supported & STD_KEYBOARD) { | 507 | if (djdev->reports_supported & STD_KEYBOARD) { |
488 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", | 508 | dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", |
489 | __func__, djdev->reports_supported); | 509 | __func__, djdev->reports_supported); |
490 | retval = hid_parse_report(hid, | 510 | rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor)); |
491 | (u8 *) kbd_descriptor, | ||
492 | sizeof(kbd_descriptor)); | ||
493 | if (retval) { | ||
494 | dbg_hid("%s: sending a kbd descriptor, hid_parse failed" | ||
495 | " error: %d\n", __func__, retval); | ||
496 | return retval; | ||
497 | } | ||
498 | } | 511 | } |
499 | 512 | ||
500 | if (djdev->reports_supported & STD_MOUSE) { | 513 | if (djdev->reports_supported & STD_MOUSE) { |
501 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " | 514 | dbg_hid("%s: sending a mouse descriptor, reports_supported: " |
502 | "%x\n", __func__, djdev->reports_supported); | 515 | "%x\n", __func__, djdev->reports_supported); |
503 | retval = hid_parse_report(hid, | 516 | rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor)); |
504 | (u8 *) mse_descriptor, | ||
505 | sizeof(mse_descriptor)); | ||
506 | if (retval) { | ||
507 | dbg_hid("%s: sending a mouse descriptor, hid_parse " | ||
508 | "failed error: %d\n", __func__, retval); | ||
509 | return retval; | ||
510 | } | ||
511 | } | 517 | } |
512 | 518 | ||
513 | if (djdev->reports_supported & MULTIMEDIA) { | 519 | if (djdev->reports_supported & MULTIMEDIA) { |
514 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", | 520 | dbg_hid("%s: sending a multimedia report descriptor: %x\n", |
515 | __func__, djdev->reports_supported); | 521 | __func__, djdev->reports_supported); |
516 | retval = hid_parse_report(hid, | 522 | rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor)); |
517 | (u8 *) consumer_descriptor, | ||
518 | sizeof(consumer_descriptor)); | ||
519 | if (retval) { | ||
520 | dbg_hid("%s: sending a consumer_descriptor, hid_parse " | ||
521 | "failed error: %d\n", __func__, retval); | ||
522 | return retval; | ||
523 | } | ||
524 | } | 523 | } |
525 | 524 | ||
526 | if (djdev->reports_supported & POWER_KEYS) { | 525 | if (djdev->reports_supported & POWER_KEYS) { |
527 | dbg_hid("%s: sending a power keys report descriptor: %x\n", | 526 | dbg_hid("%s: sending a power keys report descriptor: %x\n", |
528 | __func__, djdev->reports_supported); | 527 | __func__, djdev->reports_supported); |
529 | retval = hid_parse_report(hid, | 528 | rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor)); |
530 | (u8 *) syscontrol_descriptor, | ||
531 | sizeof(syscontrol_descriptor)); | ||
532 | if (retval) { | ||
533 | dbg_hid("%s: sending a syscontrol_descriptor, " | ||
534 | "hid_parse failed error: %d\n", | ||
535 | __func__, retval); | ||
536 | return retval; | ||
537 | } | ||
538 | } | 529 | } |
539 | 530 | ||
540 | if (djdev->reports_supported & MEDIA_CENTER) { | 531 | if (djdev->reports_supported & MEDIA_CENTER) { |
541 | dbg_hid("%s: sending a media center report descriptor: %x\n", | 532 | dbg_hid("%s: sending a media center report descriptor: %x\n", |
542 | __func__, djdev->reports_supported); | 533 | __func__, djdev->reports_supported); |
543 | retval = hid_parse_report(hid, | 534 | rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor)); |
544 | (u8 *) media_descriptor, | ||
545 | sizeof(media_descriptor)); | ||
546 | if (retval) { | ||
547 | dbg_hid("%s: sending a media_descriptor, hid_parse " | ||
548 | "failed error: %d\n", __func__, retval); | ||
549 | return retval; | ||
550 | } | ||
551 | } | 535 | } |
552 | 536 | ||
553 | if (djdev->reports_supported & KBD_LEDS) { | 537 | if (djdev->reports_supported & KBD_LEDS) { |
@@ -555,7 +539,10 @@ static int logi_dj_ll_parse(struct hid_device *hid) | |||
555 | __func__, djdev->reports_supported); | 539 | __func__, djdev->reports_supported); |
556 | } | 540 | } |
557 | 541 | ||
558 | return 0; | 542 | retval = hid_parse_report(hid, rdesc, rsize); |
543 | kfree(rdesc); | ||
544 | |||
545 | return retval; | ||
559 | } | 546 | } |
560 | 547 | ||
561 | static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, | 548 | static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, |