Linux and Scanners and Stuff

Some years back, I had to scan a bunch of stuff for various projects. One of them was the Lanterne series thing — it’s totally frivolous, which is what makes it fun.

But now I’ve managed to buy a whole bunch more books, so it was time to scan some more covers. (That’s the result of hunting books for three years up there.)

So I wheeled out my Epson DS-50000 again and dusted off three years worth of dust and plugged it into my laptop.

And, wonders of wonders, it worked fine.

Except… it was strangely slow? One of the delights of that scanner is how fast it is: It can scan an A4 page in about a second. But now it was taking 12 seconds.

So I started checking stuff like the cables (“it’s always the cables!”) and stuff, but nope. So I straced it, and it turns out that scanimage is scanning just as fast as before, but after scanning does nothing for ten seconds. And the ten second delay is the same no matter whether I ask it to scan something big or something small, so it’s not a transfer issue, or an image processing issue.

This is how strace ends:

ioctl(3, USBDEVFS_REAPURBNDELAY, 0x7ffcabbad748) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffcabbada30) = 0
ioctl(3, USBDEVFS_SUBMITURB, 0x7ffcabbad760) = 0
ioctl(3, USBDEVFS_REAPURBNDELAY, 0x7ffcabbad728) = 0
ioctl(3, USBDEVFS_SUBMITURB, 0x7ffcabbad780) = 0
ioctl(3, USBDEVFS_REAPURBNDELAY, 0x7ffcabbad748) = -1 EAGAIN (Resource temporarily unavailable)
pselect6(4, NULL, [3], NULL, {tv_sec=0, tv_nsec=1000000}, NULL) = 1 (out [3], left {tv_sec=0, tv_nsec=996651})
ioctl(3, USBDEVFS_REAPURBNDELAY, 0x7ffcabbad748) = 0
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffcabbada30) = 0
ioctl(3, USBDEVFS_RELEASEINTERFACE, 0x7ffcabbada4c) = 0
close(3)                                = 0
munmap(0x7fd0322ed000, 192272)          = 0
exit_group(0)                           = ?

See those two sleeps of five seconds each? Looks sus, right?

Well, OK. This reminded me of the problems I had with this scanner three years ago: It scanned fine the first time, and then I had to reset the USB port (with the usbreset program) to get it to work again. With the current version of scanimage, I don’t have to do that, so the scanimage people have fixed that bug. But they are apparently instead sending some ioctls to the printer that get no response, which is why you get those sleeps that time out.

So this is where I went “GAH! LINUX! IT”S SUXORS!” But then I thought… “well… it’s just scanimage… perhaps I can poke around a bit.”

I downloaded the source (which is the “backends” package), compiled it, and then observed that this version of scanimage (amusingly located in backends/frontend/scanimage) has the same behaviour as the one in the OS.

The scanimage people have helpfully added a “verbose” mode that makes it trivial to grep for the location where things are timing out — without having to know anything about how the code is organised. So after poking around for a couple of minutes, I did this:

And recompiled.

And the scan time went to under two seconds. And then with the usbreset trick, I’m back to my previous scan methodology.

So… on the one hand it sucks that gadgets don’t work well under Linux (because manufacturers don’t care about Linux). But on the other hand, when they don’t work well, you can poke around yourself and work around the problem. (And if you’ve got the same scanner and landed here because you googled: You’re welcome.)

And besides, while poking at this, I watched the DVD extras on the New Order Movement box set:

They’re great! It has a couple of hours of really early New Order concerts, when they’re so nervous about doing, well, anything, and you can see them growing more confident as the months pass (the various shows are done over a one year period, I think).

It’s cool. And would I have watched this it if I didn’t have to poke at the printer? Probably. But probably not for several years because who has the time.

That’s why I love Linux.

Leave a Reply