I needed a new scanner, and I wanted one that was significantly faster than the one I’ve been using until now. After some Googling, I landed on the Epson DS-50000, which is an A3+ scanner with a promise of being able to scan an A3 300DPI page in four seconds.
The web site I bought it from said that it’s a 4PPM scanner.
THOSE ARE NOT THE SAME THING!
So I was excited when I finally got it, two months after I ordered it. Was it going to be 4PPM or 4SPP?
The latter! From hitting “enter” on my USB-connected laptop to having the scanned page up in my Emacs, it takes 3.5 seconds. Very impressive, I think. It’s only USB2, and I thought that might be a bottleneck, perhaps, but apparently not. It also feels very sturdy and it doesn’t have a fan, so it’s quite silent. It’s very nice. And it makes good-quality scans, too.
Yes, I connected it to a Linux laptop and you all knows what comes next: A tale of woe.
$ scanimage -d epsonds:libusb:001:019 --resolution 300dpi > /tmp/file
Worked perfectly the first time I tried it, so I thought I was in luck for once. But then I tried it again:
$ scanimage -d epsonds:libusb:001:019 --resolution 300dpi > /tmp/file scanimage: open of device epsonds:libusb:001:019 failed: Error during device I/O
Gah! Basically, nothing helped. And it’s not just when scanning: Any command that talks to the scanner works the first time:
$ scanimage -L device `epsonds:libusb:001:019' is a Epson DS-50000 ESC/I-2
But the second time:
$ scanimage -L No scanners were identified. If you were expecting something different, check that the scanner is plugged in, turned on and detected by the sane-find-scanner tool (if appropriate). Please read the documentation which came with this software (README, FAQ, manpages).
If I unplug it and replug it, then it works again.
After googling a bit, it seems that somebody had the same issue some years back with a different scanner, and the way to fix it was to build scanimage and friends from the current source tree, but that didn’t help.
So after some head scratching, I thought of a different approach: Obviously, something scanimage is doing is leaving the scanner in a bad state. What if I just reset the USB interface? Is that something that’s even possible?
I added a Makefile and put it on Microsoft Github for your convenience. All the code does is basically:
ioctl(fd, USBDEVFS_RESET, 0);
And this resets just the single USB port, so nothing else wonky happens to the USB sub-subsystem. And the command is extremely fast, so it adds no delay to the scanning process.
You do get a lot of these messages in your kern.log, though:
Oct 28 21:03:06 corrigan kernel: [972003.683893] usb 1-2: reset high-speed USB device number 19 using xhci_hcd
But who cares.
It’s truly the year of Linux on the Laptop.