[sane-devel] Proposal: sanei_usb interface for USB scanners

Henning Meier-Geinitz henning@meier-geinitz.de
Mon, 6 Aug 2001 20:35:27 +0200


On Mon, Aug 06, 2001 at 12:07:46AM +0200, Oliver Neukum wrote:
> > I have just written a quick-and-dirty interface for USB scanners like
> > sanei_scsi is for SCSI scanners. It's not as generic as the SCSI one,
> > however. Currently it works only with device files, so e.g. the Linux
> > USB scanner module is supported. I don't know if it's easy to add
> The architecture you use will work with nothing else.

I'm quite new to USB so I may be wrong:

Question 1: Is there anything else?
I know of:

- libsusb (Linux, *BSD, others?)
- scanner module (Linux, FreeBSD)
- special kernel modules for some scanners (Linux only?)

What about USB support on other operating systems?

Question 2: Is there a more generic way?

My idea to use the scanner module resulted from the fact, that this
module knows which USB device is a scanner and which isn't (at least
in theory). While libusb looks more generic, I can't ask this lib
questions like: "Is any scanner connected to this system", because
there is no class "scanner" (unlike SCSI). So I can't write something
for sane-find-scanner without having a list of the ids of scanners.

Would it be possible to support both libusb and the scanner module by
using opaque handles like that:

sanei_usb_open_by_id (some_handle_type * handle, SANE_Word vendor, SANE_Word product);

If this fails (no libusb and no ioctl support for scanner module):
sanei_usb_open_by_name (some_handle_type * handle, SANE_String_Const device_file);

Or even something like:
sanei_usb_open_by_name (some_handle_type * handle, SANE_Word vendor, SANE_Word product
                        SANE_String_Const device_file,);

Open device with given ids if possible (and ids != 0), if not try to
open based on device_file.

The handles could point to file descriptors, libusb usb_dev_handle or
whatever. Just something to identify the scanner.

However I don't really know how to handle two (or more) identical
devices (same vendor and product id).

> > support for libusb; is there documentation for it anywhere? Would it
> > be possible to add support for the scanners with their own kernel
> > drivers without too much dirty tricks?
> Which would be ?

I don't know. e.g. USB-over-SCSI-over-USB :-)

> There are three scanner drivers in the Linux kernel, the 
> generic, microtek and hp5300. The latter two use SCSI over USB.

So they look like SCSI devices and can be used by sanei_scsi
functions? That's fine. No need to include them into sanei_usb.

> Generally speaking scanners which cannot use the generic driver cannot be 
> used in a way that would map to only bulk read/write.

They use control messages and/or interrupts? But if this
scsi-over-usb works, it doesn't matter.

Question 3:
Is sanei_usb needed? Which backend could use it? Currently mustek_usb
can use it but if this is the only one, it's no problem to include the
necessary code in the backend itsself and something similar in

Question 4:
Can libusb do everything the scanner module can do? If yes, would it
be sensible to use libusb instead of the scanner module? One drawback
would be that the user has to install one more library before he can
use USB scanners. Is libusb included in Linux distributions?

What can the "special" Linux scanner modules that libusb can't do?

> > sanei_scsi_find_devices goes the other way round: it returns a device
> > file for a given vendor and device id. It has the same limitations as
> > above. With this function it's possible to use "usb 0x1233 0x321" in
> > the config file (similar to the "scsi" command) to find a device file
> > for the USB scanner with these ids.
> This is dangerous. In fact it's a race. The id might be invalid by the time 
> the device is actually opened. You should return an fd.

Don't we have the same problem with SCSI scanners? If someone
exchanges the scanner between the detection (usually in sane_init) and
usage (sane_open) we will access the wrong device. At least the mustek
backend doesn't check for the identity of the device again, when it
sane_opens it. Should it?

What about something like 

sanei_usb_get_vendor_product (SANE_Int fd, SANE_Word * vendor, SANE_Word * product);

sanei_usb_find_devices (SANE_Int vendor, SANE_Int product, 
                        SANE_Status (*attach) (SANE_Int fd));
If the ids are checked again after sane_open nothing should go wrong
as far as I see. And sane-find-scanner should also work.

Thanks for your comments.