[sane-devel] Scanner (USB) not found after kernel upgrade

Couriousous couriousous at mandriva.org
Tue Feb 14 15:09:24 UTC 2006


Hi !

Le Mardi 14 Février 2006 14:54, Johannes Meixner a écrit :
> On Feb 13 23:34 Couriousous wrote (shortened):
> > Le Lundi 13 Février 2006 16:22, Johannes Meixner a écrit :
> > > On Feb 7 21:32 Till Kamppeter wrote (shortened):
> > > > The usblp module can be replaced by a libusb-based CUPS backend.
> > > > Download
> > > >
> > > > http://www.linuxprinting.org/till/tmp/usb-libusb.c
> > >
> > > For me it hangs up during list_devices() with endless
> > > ---------------------------------------------------------
> > > INFO: USB printer is busy; will retry in 5 seconds...
> > > ---------------------------------------------------------
> >
> > Can you try the attached patch ?
> > I've modified the libusb cups backend so it doesn't loop if the
> > configuration setting doesn't work.
>
> Now it works of course but now you do exaclty the same as SANE:
> You ignore this error but as far as I know the "kernel folks"
> regard this as wrong and we are again at the beginning where
> I wrote on sane-devel at lists.alioth.debian.org
> -------------------------------------------------------------
> I asked several people and even one of "the kernel folks"
> for documentation how to correctly talk to a USB device
> which has more than one interface so that SANE could do it
> correctly but no such documentation was available.
> -------------------------------------------------------------

Yes, we should not ignore this error, but since I've never seen an usb device 
which has more than one configuration possible, ignoring this error is not a 
big mistake. The correct behavior would be to check if the device is already 
in the configuration state we want. But this cannot be done with libusb :/
The only way I know is by reading the file:
/sys/bus/usb/devices/BUSNUMBER:DEVICENUMBER/bConfigurationValue

The kernel cannot be patched to allow setting the same configuration that the 
current one even because it already handle this corner case as:

if (actconfig && actconfig->desc.bConfigurationValue == u)
	status = usb_reset_configuration(ps->dev);
else 
	status = usb_set_configuration(ps->dev, u);

So, it does a reset in this specific case :/

BTW, if someone has a device with more than one Configuration possible, it 
would be kind to post:
lsusb -v
cat /proc/bus/usb/devices
cat /sys/bus/usb/devices/XXX:YYY/*

> > As the printer is already claimed by an another driver,
> > the kernel doesn't want to change device's configuration,
> > but it should anyway allow printing.
> >
> > > ----------------------------------------------------------------
> > > usbfs: interface 2 claimed by usb-storage while ... sets config
> > > ----------------------------------------------------------------
>
> This shows - at least as far as I understand it - that
> this "another driver" is the kernel module usb-storage.
> But why does the driver for the cardreader unit claim
> the printer unit?
> For me this looks like a bug in the driver for the cardreader
> unit i.e. a kernel-module bug i.e. a kernel bug.

The printer unit is not claimed by the usb storage module check the "Driver=" 
flag in /proc/bus/usb/device to know which driver claim which interface. The 
kernel do the following ( see /usr/src/linux/drivers/usb/core/devio.c, 
function proc_setconfig() ) :

If an usb device has an interface claimed by a driver, then forbid changing 
device configuration. This is normal since changing device configuration can 
change interfaces. Moreover, usb-storage module doesn't claim the printer 
interface because the kernel would have not accepted the interface claim done 
just after the device configuration try:
usb_claim_interface 
(devhdl,dev->config[conf].interface[interface].altsetting[alt_set].bInterfaceNumber)

In usb-libusb.c I claim interface 0 and the printer interface. I don't know if 
I really should claim interface 0 since kernel module usblp doesn't do it, 
but since I use it to send control msg to the printer... It should not be a 
big problem since interface 0 is, with epson printer/scanner, the scanner 
interface, so it disallow printing and scanning at the same time.


> Again the same question:
> How to talk correctly to a USB device with more than one interface?
> This question seem to be the core of all the problems.

You're right, there is a little documentation on libusb.sf.net, but it's not 
an advanced doc. There is still kernel source, but it's not easy to read/find 
info.

>
> > Cups specify explicitly that backend should loop if
> > the printer is busy.
>
> I assume you are talking about "CUPS Software Programmers Manual",
> "Writing Backends", "Retries":
> -------------------------------------------------------------------
> All backends must retry connections to the device. This includes
> backends that talk to local character or block devices, as the
> user may define more than one printer queue pointing at the same
> physical device.
> -------------------------------------------------------------------
> On the one hand this is correct but note what is actually meant:
> "Retry if the device is accessible but at the moment it is busy",
> i.e. retry if a later attempt should be successful.
> On the other hand:
> If a backend receives an error condition which indicates that a
> later attempt is not successful (e.g. the USB system reports a
> fatal error which indicates that USB access will not work at all),
> then it should exit with non-zero exit code so that the cupsd
> disables the queue, see for example

Yes, but there is absolutly no way to know if the -EBUSY returned by the 
kernel mean "An another backend use it now, it will be aviable later", or if 
it mean "No, you will never be able to claim this interface". Usb-libusb.c 
does already return with a non-zero exit code if an another error than -EBUSY 
is returned by the kernel.

> http://portal.suse.com/sdb/en/2004/05/jsmeix_print-cups-in-a-nutshell.html
> "The Backends"

Nice cups doc !

Regards,
Couriousous



More information about the sane-devel mailing list