USB: usblp: don't call usb_set_interface if there's a single alt
diff mbox series

Message ID YAy9kJhM/rG8EQXC@watson
State Accepted
Commit d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d
Headers show
Series
  • USB: usblp: don't call usb_set_interface if there's a single alt
Related show

Commit Message

Jeremy Figgins Jan. 24, 2021, 12:21 a.m. UTC
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().

Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com>
---
An alternative fix was submitted previously as:

USB: usblp: add USBLP_QUIRK_NO_SETF_INTF flag

and this superscedes that patch. This is a different approach, so
I submitted it as a new patch, rather than adding a v2 to the first
one; I hope that was the correct thing to do in this case.

 drivers/usb/class/usblp.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

Comments

Pete Zaitcev Jan. 25, 2021, 5:39 a.m. UTC | #1
On Sat, 23 Jan 2021 18:21:36 -0600
Jeremy Figgins <kernel@jeremyfiggins.com> wrote:

> Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com>

> +++ b/drivers/usb/class/usblp.c
> +	if (usblp->intf->num_altsetting > 1) {

Acked-by: Pete Zaitcev <zaitcev@redhat.com>

I am having some misgivings about it, but let's see if it works.
At worst, someone will complain and we'll revert to quirks.

-- Pete

Patch
diff mbox series

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);