aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
authorMatthias Dellweg <2500@gmx.de>2011-09-25 08:26:25 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-26 19:30:47 -0400
commit393cbb5151ecda9f9e14e3082d048dd27a1ff9f6 (patch)
tree332ed1304482853188a6cb20d3d23ba6348a50e3 /drivers/usb/core/devio.c
parentaec01c5895051849ed842dc5b8794017a7751f28 (diff)
usb/core/devio.c: Check for printer class specific request
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> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index eea53ebe6706..0ca54e22d319 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -609,9 +609,10 @@ static int findintfep(struct usb_device *dev, unsigned int ep)
609} 609}
610 610
611static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, 611static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
612 unsigned int index) 612 unsigned int request, unsigned int index)
613{ 613{
614 int ret = 0; 614 int ret = 0;
615 struct usb_host_interface *alt_setting;
615 616
616 if (ps->dev->state != USB_STATE_UNAUTHENTICATED 617 if (ps->dev->state != USB_STATE_UNAUTHENTICATED
617 && ps->dev->state != USB_STATE_ADDRESS 618 && ps->dev->state != USB_STATE_ADDRESS
@@ -620,6 +621,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype,
620 if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) 621 if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype))
621 return 0; 622 return 0;
622 623
624 /*
625 * check for the special corner case 'get_device_id' in the printer
626 * class specification, where wIndex is (interface << 8 | altsetting)
627 * instead of just interface
628 */
629 if (requesttype == 0xa1 && request == 0) {
630 alt_setting = usb_find_alt_setting(ps->dev->actconfig,
631 index >> 8, index & 0xff);
632 if (alt_setting
633 && alt_setting->desc.bInterfaceClass == USB_CLASS_PRINTER)
634 index >>= 8;
635 }
636
623 index &= 0xff; 637 index &= 0xff;
624 switch (requesttype & USB_RECIP_MASK) { 638 switch (requesttype & USB_RECIP_MASK) {
625 case USB_RECIP_ENDPOINT: 639 case USB_RECIP_ENDPOINT:
@@ -772,7 +786,8 @@ static int proc_control(struct dev_state *ps, void __user *arg)
772 786
773 if (copy_from_user(&ctrl, arg, sizeof(ctrl))) 787 if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
774 return -EFAULT; 788 return -EFAULT;
775 ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.wIndex); 789 ret = check_ctrlrecip(ps, ctrl.bRequestType, ctrl.bRequest,
790 ctrl.wIndex);
776 if (ret) 791 if (ret)
777 return ret; 792 return ret;
778 wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */ 793 wLength = ctrl.wLength; /* To suppress 64k PAGE_SIZE warning */
@@ -1102,7 +1117,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
1102 kfree(dr); 1117 kfree(dr);
1103 return -EINVAL; 1118 return -EINVAL;
1104 } 1119 }
1105 ret = check_ctrlrecip(ps, dr->bRequestType, 1120 ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest,
1106 le16_to_cpup(&dr->wIndex)); 1121 le16_to_cpup(&dr->wIndex));
1107 if (ret) { 1122 if (ret) {
1108 kfree(dr); 1123 kfree(dr);