Bug 253232 - ulpt possible regression in 12.2
Summary: ulpt possible regression in 12.2
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: 12.2-RELEASE
Hardware: amd64 Any
: --- Affects Some People
Assignee: freebsd-usb (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-03 21:17 UTC by Brock Williams
Modified: 2022-07-02 15:48 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brock Williams 2021-02-03 21:17:28 UTC
We have a point of sale system that uses Epson receipt printers attached via a USB-Parallel adapter.  After upgrading these systems to 12.2-RELEASE the printing is intermittent.

We have duplicated the issue on a fresh 12.2-RELEASE install upgraded to p3 via freebsd-update.  For example, when running an 'echo "hello" > /dev/ulpt0' multiple times on 12.2 only every other line is printed.  No errors are generated.  I have a separate boot environment on the same hardware with 12.1, which works perfectly.

We have tried a couple different USB-Parallel adapters, including:

Belk USB Printing Support IEEE-1284 Controller
and
Prolific Technology Inc. IEEE-1284 Controller, class 0/0, rev 1.00/2.02, addr 1

both of these behave the same.

I have tried enabling ulpt debugging with sysctl hw.usb.ulpt.debug=15
after each echo command, we get:
Feb  3 13:57:31 fbtest kernel: ulpt_reset: 
Feb  3 13:57:31 fbtest kernel: ulpt_write_callback: state=0x0 actlen=6
Feb  3 13:57:31 fbtest kernel: ulpt_write_callback: state=0x1 actlen=6
the ones that work look the same as the ones that don't work.

I have also tried using unlpt0 and it behaves the same way.

Using echo is a simplified example, if we point lpd to the same device it is even more intermittent.  In that case, it seems like the first job or two will print, and after that, most jobs fail silently.
Comment 1 Hans Petter Selasky freebsd_committer freebsd_triage 2021-02-04 15:32:23 UTC
Hi,

Are you using cups for printing?

cups started using libusb for direct USB device access. Verify there is no conflict.

Also you may find "usbdump" useful, to capture all traffic to/from the USB device.

Maybe a USB class compliance issue.

--HPS
Comment 2 Brock Williams 2021-02-04 16:18:45 UTC
We are not using cups, and I verified it is not installed on the test system.

I tried a usbdump but not really sure what to look for.  The output looks the same to me on the ones that work and that don't:

09:12:29.188729 usbus0.2 SUBM-CTRL-EP=00000000,SPD=FULL,NFR=1,SLEN=8,IVAL=50
09:12:29.194644 usbus0.2 DONE-CTRL-EP=00000000,SPD=FULL,NFR=1,SLEN=0,IVAL=50,ERR=0
09:12:29.194684 usbus0.2 SUBM-BULK-EP=00000001,SPD=FULL,NFR=1,SLEN=12,IVAL=0
09:12:29.196558 usbus0.2 DONE-BULK-EP=00000001,SPD=FULL,NFR=1,SLEN=0,IVAL=0,ERR=0
09:12:29.457889 usbus0.2 SUBM-CTRL-EP=00000080,SPD=FULL,NFR=2,SLEN=8,IVAL=0
09:12:29.465653 usbus0.2 DONE-CTRL-EP=00000080,SPD=FULL,NFR=2,SLEN=4,IVAL=0,ERR=0

vs

09:12:32.490567 usbus0.2 SUBM-CTRL-EP=00000000,SPD=FULL,NFR=1,SLEN=8,IVAL=50
09:12:32.496664 usbus0.2 DONE-CTRL-EP=00000000,SPD=FULL,NFR=1,SLEN=0,IVAL=50,ERR=0
09:12:32.496703 usbus0.2 SUBM-BULK-EP=00000001,SPD=FULL,NFR=1,SLEN=12,IVAL=0
09:12:32.498943 usbus0.2 DONE-BULK-EP=00000001,SPD=FULL,NFR=1,SLEN=0,IVAL=0,ERR=0
09:12:32.600296 usbus0.2 SUBM-CTRL-EP=00000080,SPD=FULL,NFR=2,SLEN=8,IVAL=0
09:12:32.608505 usbus0.2 DONE-CTRL-EP=00000080,SPD=FULL,NFR=2,SLEN=4,IVAL=0,ERR=0


We also determined that if we send data directly to the /dev/usb/0.2.1 device as opposed to /dev/ultp0, it prints reliably.  We intend to use that as a workaround for the time being.

FWIW, we have tried multiple computers, multiple printers, and multiple brands of usb->parallel adapters, and so far, all of the combinations have had the same problem.

Brock
Comment 3 Hans Petter Selasky freebsd_committer freebsd_triage 2021-02-04 16:48:33 UTC
Hi,

It might be related to the use of USB clear endpoint stall, prior to transmission.

You can comment that out in the ulpt driver in the kernel. Look for clear stall.

If that happens to be the case, your USB device's firmware is not fully USB class compliant ...

--HPS
Comment 4 Brock Williams 2021-02-06 00:10:06 UTC
Commenting out the clear stall code did make it work using these usb adapters.  It broke printing to some of the newer epson's that have built-in USB ports, though.  For now we'll just communicate via the /dev/usb device instead of ulpt0.  That said I'm happy to do any further testing if this is something anyone wants to look into further.  I think it must be a fairly widespread issue given that all of the different usb-parallel adapters we could round up exhibited the same issue.
Comment 5 Hans Petter Selasky freebsd_committer freebsd_triage 2021-02-07 10:39:25 UTC
Thanks for testing.

It appears that your printer devices has not been through enough low-level USB testing.

Maybe you could write an e-mail to the manufacturer of the USB ulpt device saying that the USB request clear endpoint halt is broken and causes the device to halt.

The main problem here is that if you abort a job, the next job may need a clear-stall message to recover the so-called data-toggle. Else you may loose the contents of one USB packet on the wire :-(

If you never abort jobs, than there is no problem.

Should we perhaps implement a quirk you can set, that prevents clear-stall from happening?

I really don't like to fix FreeBSD because USB manufacturers are not following specs ....

What do you think?

--HPS
Comment 6 Peter Much 2022-07-02 15:48:28 UTC
I'm getting the same errors only on one of two identical Prolific devices.

I bought such a piece, it worked immediately with no further problems. 
A year later I ordered another one, got the very identcal piece (branded "Logitech"), the kernel detects it as the same thing, so I put it into my OK shelf.

Now I try to use it, and it doesn't work. No data whatsoever goes through. From this report I now got the idea to write to /dev/usb/1.3.1 - and voila, I get a line written on the printer!

So the piece is apparently not just broken, and, from the timeline, t doesn't seem to be the unsufficiently-tested prize from the guangzhou lottery, but rather the silently-upgraded-with-new-bugs-or-features prize. (Sorry, Hans-Petter)

Have a closer look:

old:
ugen2.3: <vendor 0x1a86 USB2.0-Print> at usbus2, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (96mA)
new:
ugen1.3: <vendor 0x1a86 USB2.0-Print> at usbus1, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)

old:
ugen2.3: <vendor 0x1a86 USB2.0-Print> at usbus2
ulpt_probe: 
syslog: last message repeated 1 times
ulpt0 on uhub4
ulpt_attach: sc=0xfffff80006957000
ulpt0: <vendor 0x1a86 USB2.0-Print, class 0/0, rev 1.10/2.54, addr 3> on usbus2
ulpt_attach: setting alternate config number: 0
ulpt0: using bi-directional mode
ulpt0: out of paper

new:
ugen1.3: <vendor 0x1a86 USB2.0-Print> at usbus1
ulpt_probe: 
syslogd: last message repeated 1 times
ulpt1 on uhub3
ulpt_attach: sc=0xfffff800bcc0f400
ulpt1: <vendor 0x1a86 USB2.0-Print, class 0/0, rev 1.10/2.54, addr 3> on usbus1
ulpt_attach: setting alternate config number: 1
ulpt1: using bi-directional mode
ulpt_status_callback: error=USB_ERR_STALLED
ulpt_status_callback: error=USB_ERR_STALLED
ulpt_status_callback: error=USB_ERR_STALLED
ulpt_status_callback: error=USB_ERR_STALLED
[loops forever, once a second]

The alternate config number is different.
The old one has only one config with <BULK IN> and <BULK OUT>:

    Interface 0
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x0007  <Printer device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0002 

The new one has three of them:

    Interface 0
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0001       
      bInterfaceClass = 0x0007  <Printer device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0001 
[ <BULK OUT> only ]

    Interface 0 Alt 1
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0001 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x0007  <Printer device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0002 
[ <BULK IN> and <BULK OUT> ]

    Interface 0 Alt 2
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0002 
      bNumEndpoints = 0x0003 
      bInterfaceClass = 0x00ff  <Vendor specific>
      bInterfaceSubClass = 0x0000 
      bInterfaceProtocol = 0x00ff 
[ <BULK IN>, <BULK OUT> and <INTERRUPT IN> ]

I'll now try and test the suggested patch.