summaryrefslogtreecommitdiff
path: root/drivers/usb/class
diff options
context:
space:
mode:
authorJeremy Figgins <kernel@jeremyfiggins.com>2021-01-24 03:21:36 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-26 17:15:31 +0300
commitd8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d (patch)
treeb8c3c0acd7fa904ea98939dac057ecf58ccb0639 /drivers/usb/class
parent6ee1d745b7c9fd573fba142a2efdad76a9f1cb04 (diff)
downloadlinux-d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d.tar.xz
USB: usblp: don't call usb_set_interface if there's a single alt
Some devices, such as the Winbond Electronics Corp. Virtual Com Port (Vendor=0416, ProdId=5011), lockup when usb_set_interface() or usb_clear_halt() are called. This device has only a single altsetting, so it should not be necessary to call usb_set_interface(). Acked-by: Pete Zaitcev <zaitcev@redhat.com> Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com> Link: https://lore.kernel.org/r/YAy9kJhM/rG8EQXC@watson Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/class')
-rw-r--r--drivers/usb/class/usblp.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 134dc2005ce9..c9f6e9758288 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1329,14 +1329,17 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
return -EINVAL;
- alts = usblp->protocol[protocol].alt_setting;
- if (alts < 0)
- return -EINVAL;
- r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
- if (r < 0) {
- printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
- alts, usblp->ifnum);
- return r;
+ /* Don't unnecessarily set the interface if there's a single alt. */
+ if (usblp->intf->num_altsetting > 1) {
+ alts = usblp->protocol[protocol].alt_setting;
+ if (alts < 0)
+ return -EINVAL;
+ r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+ if (r < 0) {
+ printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",
+ alts, usblp->ifnum);
+ return r;
+ }
}
usblp->bidir = (usblp->protocol[protocol].epread != NULL);