* [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
@ 2021-01-17 21:36 Jeremy Figgins
2021-01-18 5:44 ` Pete Zaitcev
2021-01-18 9:02 ` Sergei Shtylyov
0 siblings, 2 replies; 16+ messages in thread
From: Jeremy Figgins @ 2021-01-17 21:36 UTC (permalink / raw)
To: zaitcev, gregkh, linux-usb
Certain devices such as Winbond Virtual Com Port,
which is used in some usb printers, will stop
responding after the usb_control_msg_send()
calls in usb_set_interface(). These devices work
fine without having usb_set_interface() called, so
this flag prevents that call.
The naming is designed to mirror the existing
USB_QUIRK_NO_SET_INTF flag, but that flag is
not sufficient to make these devices work.
Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com>
---
drivers/usb/class/usblp.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 134dc2005ce9..6e2d58813d7d 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -209,6 +209,7 @@ struct quirk_printer_struct {
#define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */
#define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */
#define USBLP_QUIRK_BAD_CLASS 0x4 /* descriptor uses vendor-specific Class or SubClass */
+#define USBLP_QUIRK_NO_SET_INTF 0x8 /* device can't handle Set-Interface requests */
static const struct quirk_printer_struct quirk_printers[] = {
{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
@@ -227,6 +228,7 @@ static const struct quirk_printer_struct quirk_printers[] = {
{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
{ 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
+ { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
{ 0, 0 }
};
@@ -1332,7 +1334,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
- r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+ if (usblp->quirks & USBLP_QUIRK_NO_SET_INTF) {
+ r = 0;
+ } else {
+ 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);
--
2.29.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-17 21:36 [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag Jeremy Figgins
@ 2021-01-18 5:44 ` Pete Zaitcev
2021-01-18 16:31 ` Alan Stern
2021-01-18 9:02 ` Sergei Shtylyov
1 sibling, 1 reply; 16+ messages in thread
From: Pete Zaitcev @ 2021-01-18 5:44 UTC (permalink / raw)
To: Jeremy Figgins; +Cc: gregkh, linux-usb, zaitcev
On Sun, 17 Jan 2021 15:36:39 -0600
Jeremy Figgins <kernel@jeremyfiggins.com> wrote:
> The naming is designed to mirror the existing
> USB_QUIRK_NO_SET_INTF flag, but that flag is
> not sufficient to make these devices work.
> + { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
Jeremy, thanks for the patch. It looks mostly fine code-wise (quirk is
out of numerical order), but I have a question: did you consider keying
off usblp->dev->quirks instead?
How about this:
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 37062130a03c..0c4a98f00797 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1315,7 +1315,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
- r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+ if (usblp->dev->quirks & USB_QUIRK_NO_SET_INTF) {
+ r = 0;
+ } else {
+ 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);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 1b4eb7046b07..632c60401d53 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -205,6 +205,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* HP v222w 16GB Mini USB Drive */
{ USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
+ /* Winbond Electronics Corp. Virtual Com Port */
+ { USB_DEVICE(0x0416, 0x5011), .driver_info = USB_QUIRK_NO_SET_INTF },
+
/* Creative SB Audigy 2 NX */
{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
Please let me know if it works for you.
-- Pete
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-17 21:36 [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag Jeremy Figgins
2021-01-18 5:44 ` Pete Zaitcev
@ 2021-01-18 9:02 ` Sergei Shtylyov
1 sibling, 0 replies; 16+ messages in thread
From: Sergei Shtylyov @ 2021-01-18 9:02 UTC (permalink / raw)
To: Jeremy Figgins, zaitcev, gregkh, linux-usb
On 18.01.2021 0:36, Jeremy Figgins wrote:
> Certain devices such as Winbond Virtual Com Port,
> which is used in some usb printers, will stop
> responding after the usb_control_msg_send()
Hm, not usblp_set_protocol()?
> calls in usb_set_interface(). These devices work
> fine without having usb_set_interface() called, so
> this flag prevents that call.
>
> The naming is designed to mirror the existing
> USB_QUIRK_NO_SET_INTF flag, but that flag is
> not sufficient to make these devices work.
Perhaps the handling of that flag should just be extended to yuor case?
> Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com>
> ---
> drivers/usb/class/usblp.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
> index 134dc2005ce9..6e2d58813d7d 100644
> --- a/drivers/usb/class/usblp.c
> +++ b/drivers/usb/class/usblp.c
[...]
> @@ -1332,7 +1334,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
> alts = usblp->protocol[protocol].alt_setting;
> if (alts < 0)
> return -EINVAL;
> - r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
> + if (usblp->quirks & USBLP_QUIRK_NO_SET_INTF) {
> + r = 0;
> + } else {
> + r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
> + }
The braces above not needed at all.
[...]
MBR, Sergei
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-18 5:44 ` Pete Zaitcev
@ 2021-01-18 16:31 ` Alan Stern
2021-01-18 16:43 ` Michael Sweet
2021-01-21 19:19 ` Pete Zaitcev
0 siblings, 2 replies; 16+ messages in thread
From: Alan Stern @ 2021-01-18 16:31 UTC (permalink / raw)
To: Pete Zaitcev; +Cc: Jeremy Figgins, gregkh, linux-usb
On Sun, Jan 17, 2021 at 11:44:16PM -0600, Pete Zaitcev wrote:
> On Sun, 17 Jan 2021 15:36:39 -0600
> Jeremy Figgins <kernel@jeremyfiggins.com> wrote:
>
> > The naming is designed to mirror the existing
> > USB_QUIRK_NO_SET_INTF flag, but that flag is
> > not sufficient to make these devices work.
> > + { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
>
> Jeremy, thanks for the patch. It looks mostly fine code-wise (quirk is
> out of numerical order), but I have a question: did you consider keying
> off usblp->dev->quirks instead?
>
> How about this:
>
> diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
> index 37062130a03c..0c4a98f00797 100644
> --- a/drivers/usb/class/usblp.c
> +++ b/drivers/usb/class/usblp.c
> @@ -1315,7 +1315,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
> alts = usblp->protocol[protocol].alt_setting;
> if (alts < 0)
> return -EINVAL;
> - r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
> + if (usblp->dev->quirks & USB_QUIRK_NO_SET_INTF) {
> + r = 0;
> + } else {
> + 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);
Would it be practical simply to skip the usb_set_interface() call
whenever alts is 0? After all, devices use altsetting 0 by default; it
shouldn't be necessary to tell them to do so.
Alan Stern
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-18 16:31 ` Alan Stern
@ 2021-01-18 16:43 ` Michael Sweet
2021-01-19 0:01 ` Jeremy Figgins
2021-01-21 19:19 ` Pete Zaitcev
1 sibling, 1 reply; 16+ messages in thread
From: Michael Sweet @ 2021-01-18 16:43 UTC (permalink / raw)
To: Alan Stern
Cc: Pete Zaitcev, Jeremy Figgins, <gregkh@linuxfoundation.org>,
linux-usb
FWIW, the CUPS libusb-based backend only sets the alt setting if there is more than 1 alt setting in the descriptor.
> On Jan 18, 2021, at 11:31 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
>
> On Sun, Jan 17, 2021 at 11:44:16PM -0600, Pete Zaitcev wrote:
>> On Sun, 17 Jan 2021 15:36:39 -0600
>> Jeremy Figgins <kernel@jeremyfiggins.com> wrote:
>>
>>> The naming is designed to mirror the existing
>>> USB_QUIRK_NO_SET_INTF flag, but that flag is
>>> not sufficient to make these devices work.
>>> + { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
>>
>> Jeremy, thanks for the patch. It looks mostly fine code-wise (quirk is
>> out of numerical order), but I have a question: did you consider keying
>> off usblp->dev->quirks instead?
>>
>> How about this:
>>
>> diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
>> index 37062130a03c..0c4a98f00797 100644
>> --- a/drivers/usb/class/usblp.c
>> +++ b/drivers/usb/class/usblp.c
>> @@ -1315,7 +1315,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
>> alts = usblp->protocol[protocol].alt_setting;
>> if (alts < 0)
>> return -EINVAL;
>> - r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
>> + if (usblp->dev->quirks & USB_QUIRK_NO_SET_INTF) {
>> + r = 0;
>> + } else {
>> + 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);
>
> Would it be practical simply to skip the usb_set_interface() call
> whenever alts is 0? After all, devices use altsetting 0 by default; it
> shouldn't be necessary to tell them to do so.
>
> Alan Stern
________________________
Michael Sweet
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-18 16:43 ` Michael Sweet
@ 2021-01-19 0:01 ` Jeremy Figgins
2021-01-21 19:21 ` Pete Zaitcev
0 siblings, 1 reply; 16+ messages in thread
From: Jeremy Figgins @ 2021-01-19 0:01 UTC (permalink / raw)
To: Michael Sweet, Alan Stern; +Cc: Pete Zaitcev, Jeremy Figgins, gregkh, linux-usb
On 1/18/21 10:43 AM, Michael Sweet wrote:
> FWIW, the CUPS libusb-based backend only sets the alt setting if there is more than 1 alt setting in the descriptor.
>
>
>> On Jan 18, 2021, at 11:31 AM, Alan Stern <stern@rowland.harvard.edu> wrote:
>>
>> On Sun, Jan 17, 2021 at 11:44:16PM -0600, Pete Zaitcev wrote:
>>> On Sun, 17 Jan 2021 15:36:39 -0600
>>> Jeremy Figgins <kernel@jeremyfiggins.com> wrote:
>>>
>>>> The naming is designed to mirror the existing
>>>> USB_QUIRK_NO_SET_INTF flag, but that flag is
>>>> not sufficient to make these devices work.
>>>> + { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
>>>
>>> Jeremy, thanks for the patch. It looks mostly fine code-wise (quirk is
>>> out of numerical order), but I have a question: did you consider keying
>>> off usblp->dev->quirks instead?
>>>
>>> How about this:
>>>
>>> diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
>>> index 37062130a03c..0c4a98f00797 100644
>>> --- a/drivers/usb/class/usblp.c
>>> +++ b/drivers/usb/class/usblp.c
>>> @@ -1315,7 +1315,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
>>> alts = usblp->protocol[protocol].alt_setting;
>>> if (alts < 0)
>>> return -EINVAL;
>>> - r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
>>> + if (usblp->dev->quirks & USB_QUIRK_NO_SET_INTF) {
>>> + r = 0;
>>> + } else {
>>> + 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);
>>
>> Would it be practical simply to skip the usb_set_interface() call
>> whenever alts is 0? After all, devices use altsetting 0 by default; it
>> shouldn't be necessary to tell them to do so.
>>
>> Alan Stern
>
> ________________________
> Michael Sweet
>
>
>
>
Pete, your proposed change does work. I created USBLP_QUIRK_NO_SET_INTF
because I was concerned about overloading the meaning of
USB_QUIRK_NO_SET_INTF, but if you think that's the better approach, I'm
happy to resubmit the patch.
Alan, just to confirm, alts=0 for this device.
Jeremy Figgins
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-18 16:31 ` Alan Stern
2021-01-18 16:43 ` Michael Sweet
@ 2021-01-21 19:19 ` Pete Zaitcev
2021-01-21 19:29 ` Alan Stern
1 sibling, 1 reply; 16+ messages in thread
From: Pete Zaitcev @ 2021-01-21 19:19 UTC (permalink / raw)
To: Alan Stern; +Cc: Jeremy Figgins, gregkh, linux-usb, zaitcev
On Mon, 18 Jan 2021 11:31:17 -0500
Alan Stern <stern@rowland.harvard.edu> wrote:
> > diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
> > index 37062130a03c..0c4a98f00797 100644
> > --- a/drivers/usb/class/usblp.c
> > +++ b/drivers/usb/class/usblp.c
> > @@ -1315,7 +1315,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
> > alts = usblp->protocol[protocol].alt_setting;
> > if (alts < 0)
> > return -EINVAL;
> > - r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
> > + if (usblp->dev->quirks & USB_QUIRK_NO_SET_INTF) {
> > + r = 0;
> > + } else {
> > + 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);
>
> Would it be practical simply to skip the usb_set_interface() call
> whenever alts is 0? After all, devices use altsetting 0 by default; it
> shouldn't be necessary to tell them to do so.
Is it possible to bind and unbind the driver without enumeration, and
thus inherit a non-zero altsetting?
I'm also concerned about regressions. This is a legacy class driver,
only used where CUPS is not applicable, mostly with truly ancient
devices. So yes, setting a zero altsetting after enumeration should
be unnecessary. But you never know with the old firmware.
-- Pete
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-19 0:01 ` Jeremy Figgins
@ 2021-01-21 19:21 ` Pete Zaitcev
0 siblings, 0 replies; 16+ messages in thread
From: Pete Zaitcev @ 2021-01-21 19:21 UTC (permalink / raw)
To: Jeremy Figgins
Cc: Michael Sweet, Alan Stern, Jeremy Figgins, gregkh, linux-usb, zaitcev
On Mon, 18 Jan 2021 18:01:53 -0600
Jeremy Figgins <jeremy@jeremyfiggins.com> wrote:
> Pete, your proposed change does work. I created USBLP_QUIRK_NO_SET_INTF
> because I was concerned about overloading the meaning of
> USB_QUIRK_NO_SET_INTF, but if you think that's the better approach, I'm
> happy to resubmit the patch.
I do think it's better, so if you submit the channged version,
I'll ack. But note that we need to get Alan Stern onboard too.
-- Pete
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-21 19:19 ` Pete Zaitcev
@ 2021-01-21 19:29 ` Alan Stern
2021-01-21 23:02 ` Pete Zaitcev
0 siblings, 1 reply; 16+ messages in thread
From: Alan Stern @ 2021-01-21 19:29 UTC (permalink / raw)
To: Pete Zaitcev; +Cc: Jeremy Figgins, gregkh, linux-usb
On Thu, Jan 21, 2021 at 01:19:54PM -0600, Pete Zaitcev wrote:
> On Mon, 18 Jan 2021 11:31:17 -0500
> Alan Stern <stern@rowland.harvard.edu> wrote:
> > Would it be practical simply to skip the usb_set_interface() call
> > whenever alts is 0? After all, devices use altsetting 0 by default; it
> > shouldn't be necessary to tell them to do so.
>
> Is it possible to bind and unbind the driver without enumeration, and
> thus inherit a non-zero altsetting?
In theory, yes. But the only way it could happen is if either the
driver itself or a userspace program installed the nonzero
altsetting.
> I'm also concerned about regressions. This is a legacy class driver,
> only used where CUPS is not applicable, mostly with truly ancient
> devices. So yes, setting a zero altsetting after enumeration should
> be unnecessary. But you never know with the old firmware.
True, although I seriously doubt anyone would have written firmware that
required a Set-Interface request for initialization. Particularly if
the interface has only one altsetting.
How about skipping the call whenever the interface has only one
altsetting?
Alan Stern
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-21 19:29 ` Alan Stern
@ 2021-01-21 23:02 ` Pete Zaitcev
2021-01-22 1:06 ` Jeremy Figgins
2021-01-22 16:20 ` Alan Stern
0 siblings, 2 replies; 16+ messages in thread
From: Pete Zaitcev @ 2021-01-21 23:02 UTC (permalink / raw)
To: Alan Stern; +Cc: Jeremy Figgins, gregkh, linux-usb
On Thu, 21 Jan 2021 14:29:29 -0500
Alan Stern <stern@rowland.harvard.edu> wrote:
> > I'm also concerned about regressions. This is a legacy class driver,
> > only used where CUPS is not applicable, mostly with truly ancient
> > devices. So yes, setting a zero altsetting after enumeration should
> > be unnecessary. But you never know with the old firmware.
> How about skipping the call whenever the interface has only one
> altsetting?
Do you mean when it's only one and not equal to zero?
BTW, one other thing bothers me. Jeremy confirmed that my patch
worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
But if we look into drivers/usb/core/message.c, the control
exchange to set the altsetting is skipped in that case anyway.
So, usblp was calling usb_set_protocol, the suspect control was
skipped, but something else caused a problem. Could it be the
attempt to clear halt that triggered the problem?
-- Pete
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-21 23:02 ` Pete Zaitcev
@ 2021-01-22 1:06 ` Jeremy Figgins
2021-01-22 16:22 ` Alan Stern
2021-01-22 16:20 ` Alan Stern
1 sibling, 1 reply; 16+ messages in thread
From: Jeremy Figgins @ 2021-01-22 1:06 UTC (permalink / raw)
To: Pete Zaitcev, Alan Stern; +Cc: gregkh, linux-usb
On 1/21/21 5:02 PM, Pete Zaitcev wrote:
> On Thu, 21 Jan 2021 14:29:29 -0500
> Alan Stern <stern@rowland.harvard.edu> wrote:
>
>>> I'm also concerned about regressions. This is a legacy class driver,
>>> only used where CUPS is not applicable, mostly with truly ancient
>>> devices. So yes, setting a zero altsetting after enumeration should
>>> be unnecessary. But you never know with the old firmware.
>
>> How about skipping the call whenever the interface has only one
>> altsetting?
>
> Do you mean when it's only one and not equal to zero?
>
> BTW, one other thing bothers me. Jeremy confirmed that my patch
> worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
> But if we look into drivers/usb/core/message.c, the control
> exchange to set the altsetting is skipped in that case anyway.
> So, usblp was calling usb_set_protocol, the suspect control was
> skipped, but something else caused a problem. Could it be the
> attempt to clear halt that triggered the problem?
>
> -- Pete
>
In my debugging, I found that it was the calls to usb_control_msg_send()
in both usb_set_interface() and usb_clear_halt() caused the printer to
lockup. I suppose another way to resolve this would to have a flag to
prevent usb_clear_halt()'s call to usb_control_msg_send(), but I'm not
an expert in USB, so I'm not sure of the ramifications of that.
-- Jeremy
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-21 23:02 ` Pete Zaitcev
2021-01-22 1:06 ` Jeremy Figgins
@ 2021-01-22 16:20 ` Alan Stern
1 sibling, 0 replies; 16+ messages in thread
From: Alan Stern @ 2021-01-22 16:20 UTC (permalink / raw)
To: Pete Zaitcev; +Cc: Jeremy Figgins, gregkh, linux-usb
On Thu, Jan 21, 2021 at 05:02:49PM -0600, Pete Zaitcev wrote:
> On Thu, 21 Jan 2021 14:29:29 -0500
> Alan Stern <stern@rowland.harvard.edu> wrote:
>
> > > I'm also concerned about regressions. This is a legacy class driver,
> > > only used where CUPS is not applicable, mostly with truly ancient
> > > devices. So yes, setting a zero altsetting after enumeration should
> > > be unnecessary. But you never know with the old firmware.
>
> > How about skipping the call whenever the interface has only one
> > altsetting?
>
> Do you mean when it's only one and not equal to zero?
If there's only one, it _has_ to be equal to 0. According to section
9.2.3 of the USB-2 spec:
Alternate settings range from zero to one less than the number
of alternate settings for a specific interface.
> BTW, one other thing bothers me. Jeremy confirmed that my patch
> worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
> But if we look into drivers/usb/core/message.c, the control
> exchange to set the altsetting is skipped in that case anyway.
> So, usblp was calling usb_set_protocol, the suspect control was
> skipped, but something else caused a problem. Could it be the
> attempt to clear halt that triggered the problem?
It could very well be. The printer might not reset the endpoint toggle
when it gets the Clear-Halt request.
It's also possible that when the quirk flag wasn't set (so the
Set-Interface request was issued), the printer failed reset the endpoint
toggle.
Alan Stern
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-22 1:06 ` Jeremy Figgins
@ 2021-01-22 16:22 ` Alan Stern
2021-01-23 18:46 ` Jeremy Figgins
0 siblings, 1 reply; 16+ messages in thread
From: Alan Stern @ 2021-01-22 16:22 UTC (permalink / raw)
To: Jeremy Figgins; +Cc: Pete Zaitcev, gregkh, linux-usb
On Thu, Jan 21, 2021 at 07:06:27PM -0600, Jeremy Figgins wrote:
> On 1/21/21 5:02 PM, Pete Zaitcev wrote:
> > On Thu, 21 Jan 2021 14:29:29 -0500
> > Alan Stern <stern@rowland.harvard.edu> wrote:
> >
> > > > I'm also concerned about regressions. This is a legacy class driver,
> > > > only used where CUPS is not applicable, mostly with truly ancient
> > > > devices. So yes, setting a zero altsetting after enumeration should
> > > > be unnecessary. But you never know with the old firmware.
> >
> > > How about skipping the call whenever the interface has only one
> > > altsetting?
> >
> > Do you mean when it's only one and not equal to zero?
> >
> > BTW, one other thing bothers me. Jeremy confirmed that my patch
> > worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
> > But if we look into drivers/usb/core/message.c, the control
> > exchange to set the altsetting is skipped in that case anyway.
> > So, usblp was calling usb_set_protocol, the suspect control was
> > skipped, but something else caused a problem. Could it be the
> > attempt to clear halt that triggered the problem?
> >
> > -- Pete
> >
>
>
> In my debugging, I found that it was the calls to usb_control_msg_send() in
> both usb_set_interface() and usb_clear_halt() caused the printer to lockup.
> I suppose another way to resolve this would to have a flag to prevent
> usb_clear_halt()'s call to usb_control_msg_send(), but I'm not an expert in
> USB, so I'm not sure of the ramifications of that.
The simplest solution in all cases is just to avoid calling either
usb_set_interface or usb_clear_halt. Especially since in cases where
the interface has only one altsetting, neither call should be necessary.
Alan Stern
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-22 16:22 ` Alan Stern
@ 2021-01-23 18:46 ` Jeremy Figgins
2021-01-23 21:33 ` Alan Stern
0 siblings, 1 reply; 16+ messages in thread
From: Jeremy Figgins @ 2021-01-23 18:46 UTC (permalink / raw)
To: Alan Stern; +Cc: Pete Zaitcev, gregkh, linux-usb
On 1/22/21 10:22 AM, Alan Stern wrote:
> On Thu, Jan 21, 2021 at 07:06:27PM -0600, Jeremy Figgins wrote:
>> On 1/21/21 5:02 PM, Pete Zaitcev wrote:
>>> On Thu, 21 Jan 2021 14:29:29 -0500
>>> Alan Stern <stern@rowland.harvard.edu> wrote:
>>>
>>>>> I'm also concerned about regressions. This is a legacy class driver,
>>>>> only used where CUPS is not applicable, mostly with truly ancient
>>>>> devices. So yes, setting a zero altsetting after enumeration should
>>>>> be unnecessary. But you never know with the old firmware.
>>>
>>>> How about skipping the call whenever the interface has only one
>>>> altsetting?
>>>
>>> Do you mean when it's only one and not equal to zero?
>>>
>>> BTW, one other thing bothers me. Jeremy confirmed that my patch
>>> worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
>>> But if we look into drivers/usb/core/message.c, the control
>>> exchange to set the altsetting is skipped in that case anyway.
>>> So, usblp was calling usb_set_protocol, the suspect control was
>>> skipped, but something else caused a problem. Could it be the
>>> attempt to clear halt that triggered the problem?
>>>
>>> -- Pete
>>>
>>
>>
>> In my debugging, I found that it was the calls to usb_control_msg_send() in
>> both usb_set_interface() and usb_clear_halt() caused the printer to lockup.
>> I suppose another way to resolve this would to have a flag to prevent
>> usb_clear_halt()'s call to usb_control_msg_send(), but I'm not an expert in
>> USB, so I'm not sure of the ramifications of that.
>
> The simplest solution in all cases is just to avoid calling either
> usb_set_interface or usb_clear_halt. Especially since in cases where
> the interface has only one altsetting, neither call should be necessary.
>
> Alan Stern
>
I can confirm that only calling usb_clear_halt() if
USB_QUIRK_NO_SET_INTF is not set (and setting it for my device) does
allow my device to work. What is the next step? Should I submit a v2 patch?
-- Jeremy
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
2021-01-23 18:46 ` Jeremy Figgins
@ 2021-01-23 21:33 ` Alan Stern
0 siblings, 0 replies; 16+ messages in thread
From: Alan Stern @ 2021-01-23 21:33 UTC (permalink / raw)
To: Jeremy Figgins; +Cc: Pete Zaitcev, gregkh, linux-usb
On Sat, Jan 23, 2021 at 12:46:06PM -0600, Jeremy Figgins wrote:
> On 1/22/21 10:22 AM, Alan Stern wrote:
> > On Thu, Jan 21, 2021 at 07:06:27PM -0600, Jeremy Figgins wrote:
> > > On 1/21/21 5:02 PM, Pete Zaitcev wrote:
> > > > On Thu, 21 Jan 2021 14:29:29 -0500
> > > > Alan Stern <stern@rowland.harvard.edu> wrote:
> > > >
> > > > > > I'm also concerned about regressions. This is a legacy class driver,
> > > > > > only used where CUPS is not applicable, mostly with truly ancient
> > > > > > devices. So yes, setting a zero altsetting after enumeration should
> > > > > > be unnecessary. But you never know with the old firmware.
> > > >
> > > > > How about skipping the call whenever the interface has only one
> > > > > altsetting?
> > > >
> > > > Do you mean when it's only one and not equal to zero?
> > > >
> > > > BTW, one other thing bothers me. Jeremy confirmed that my patch
> > > > worked, which skips the call when USB_QUIRK_NO_SET_INTF is set.
> > > > But if we look into drivers/usb/core/message.c, the control
> > > > exchange to set the altsetting is skipped in that case anyway.
> > > > So, usblp was calling usb_set_protocol, the suspect control was
> > > > skipped, but something else caused a problem. Could it be the
> > > > attempt to clear halt that triggered the problem?
> > > >
> > > > -- Pete
> > > >
> > >
> > >
> > > In my debugging, I found that it was the calls to usb_control_msg_send() in
> > > both usb_set_interface() and usb_clear_halt() caused the printer to lockup.
> > > I suppose another way to resolve this would to have a flag to prevent
> > > usb_clear_halt()'s call to usb_control_msg_send(), but I'm not an expert in
> > > USB, so I'm not sure of the ramifications of that.
> >
> > The simplest solution in all cases is just to avoid calling either
> > usb_set_interface or usb_clear_halt. Especially since in cases where
> > the interface has only one altsetting, neither call should be necessary.
> >
> > Alan Stern
> >
>
> I can confirm that only calling usb_clear_halt() if USB_QUIRK_NO_SET_INTF is
> not set (and setting it for my device) does allow my device to work. What is
> the next step? Should I submit a v2 patch?
Why don't you write, test, and submit a patch that will make usblp avoid
calling usb_set_interface and usb_clear_halt when there's only one
altsetting?
Alan Stern
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag
@ 2021-01-17 21:39 Jeremy Figgins
0 siblings, 0 replies; 16+ messages in thread
From: Jeremy Figgins @ 2021-01-17 21:39 UTC (permalink / raw)
To: linux-kernel
Certain devices such as Winbond Virtual Com Port,
which is used in some usb printers, will stop
responding after the usb_control_msg_send()
calls in usb_set_interface(). These devices work
fine without having usb_set_interface() called, so
this flag prevents that call.
The naming is designed to mirror the existing
USB_QUIRK_NO_SET_INTF flag, but that flag is
not sufficient to make these devices work.
Signed-off-by: Jeremy Figgins <kernel@jeremyfiggins.com>
---
drivers/usb/class/usblp.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 134dc2005ce9..6e2d58813d7d 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -209,6 +209,7 @@ struct quirk_printer_struct {
#define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */
#define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */
#define USBLP_QUIRK_BAD_CLASS 0x4 /* descriptor uses vendor-specific Class or SubClass */
+#define USBLP_QUIRK_NO_SET_INTF 0x8 /* device can't handle Set-Interface requests */
static const struct quirk_printer_struct quirk_printers[] = {
{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
@@ -227,6 +228,7 @@ static const struct quirk_printer_struct quirk_printers[] = {
{ 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
{ 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */
{ 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
+ { 0x0416, 0x5011, USBLP_QUIRK_NO_SET_INTF }, /* Winbond Electronics Corp. Virtual Com Port */
{ 0, 0 }
};
@@ -1332,7 +1334,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
- r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
+ if (usblp->quirks & USBLP_QUIRK_NO_SET_INTF) {
+ r = 0;
+ } else {
+ 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);
--
2.29.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2021-01-23 21:33 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-17 21:36 [PATCH] USB: usblp: add USBLP_QUIRK_NO_SET_INTF flag Jeremy Figgins
2021-01-18 5:44 ` Pete Zaitcev
2021-01-18 16:31 ` Alan Stern
2021-01-18 16:43 ` Michael Sweet
2021-01-19 0:01 ` Jeremy Figgins
2021-01-21 19:21 ` Pete Zaitcev
2021-01-21 19:19 ` Pete Zaitcev
2021-01-21 19:29 ` Alan Stern
2021-01-21 23:02 ` Pete Zaitcev
2021-01-22 1:06 ` Jeremy Figgins
2021-01-22 16:22 ` Alan Stern
2021-01-23 18:46 ` Jeremy Figgins
2021-01-23 21:33 ` Alan Stern
2021-01-22 16:20 ` Alan Stern
2021-01-18 9:02 ` Sergei Shtylyov
2021-01-17 21:39 Jeremy Figgins
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.