diff options
author | Tim Gardner <tim.gardner@canonical.com> | 2011-10-12 08:43:21 -0400 |
---|---|---|
committer | Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com> | 2011-10-17 13:33:27 -0400 |
commit | f347cfac0938cb00d5f8a338429157a6c1d6b26a (patch) | |
tree | 892d25737edbbafcebdb3bc103d605dd21635cba /drivers/usb | |
parent | 61e41dfb427baedb3813dae0e70dd2131177c6ad (diff) |
UBUNTU: SAUCE: usb/core/devio.c: Check for printer class specific request
BugLink: http://bugs.launchpad.net/bugs/872711
Scraped from https://lkml.org/lkml/2011/9/26/371. Watch for the official
patch once merged in 3.2
In the usb printer class specific request get_device_id the value of
wIndex is (interface << 8 | altsetting) instead of just interface.
This enables the detection of some printers with libusb.
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Matthias Dellweg <2500@gmx.de>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Andy Whitcroft <apw@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/devio.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 37518dfdeb9..1d73709c41b 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -607,9 +607,10 @@ static int findintfep(struct usb_device *dev, unsigned int ep) | |||
607 | } | 607 | } |
608 | 608 | ||
609 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | 609 | static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, |
610 | unsigned int index) | 610 | unsigned int request, unsigned int index) |
611 | { | 611 | { |
612 | int ret = 0; | 612 | int ret = 0; |
613 | struct usb_host_interface *alt_setting; | ||
613 | 614 | ||
614 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED | 615 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
615 | && ps->dev->state != USB_STATE_ADDRESS | 616 | && ps->dev->state != USB_STATE_ADDRESS |
@@ -618,6 +619,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | |||
618 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 619 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
619 | return 0; | 620 | return 0; |
620 | 621 | ||
622 | /* | ||
623 | * check for the special corner case 'get_device_id' in the printer | ||
624 | * class specification, where wIndex is (interface << 8 | altsetting) | ||
625 | * instead of just interface | ||
626 | */ | ||
627 | if (requesttype == 0xa1 && request == 0) { | ||
628 | alt_setting = usb_find_alt_setting(ps->dev->actconfig, | ||
629 | index >> 8, index & 0xff); | ||
630 | if (alt_setting | ||
631 | && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER) | ||
632 | index >>= 8; | ||
633 | } | ||
634 | |||
621 | index &= 0xff; | 635 | index &= 0xff; |
622 | switch (requesttype & USB_RECIP_MASK) { | 636 | switch (requesttype & USB_RECIP_MASK) { |
623 | case USB_RECIP_ENDPOINT: | 637 | case USB_RECIP_ENDPOINT: |
@@ -770,7 +784,8 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
770 | 784 | ||
771 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) | 785 | if (copy_from_user(&ctrl, arg, sizeof(ctrl))) |
772 | return -EFAULT; | 786 | return -EFAULT; |
773 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); | 787 | ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest, |
788 | ctrl.wIndex); | ||
774 | if (ret) | 789 | if (ret) |
775 | return ret; | 790 | return ret; |
776 | wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ | 791 | wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ |
@@ -1100,7 +1115,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1100 | kfree(dr); | 1115 | kfree(dr); |
1101 | return -EINVAL; | 1116 | return -EINVAL; |
1102 | } | 1117 | } |
1103 | ret = check_ctrlrecip(ps, dr->bRequestType, | 1118 | ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest, |
1104 | le16_to_cpup(&dr->wIndex)); | 1119 | le16_to_cpup(&dr->wIndex)); |
1105 | if (ret) { | 1120 | if (ret) { |
1106 | kfree(dr); | 1121 | kfree(dr); |