|
From: Hans de G. <hde...@re...> - 2013-06-27 08:13:30
|
Hi,
On 06/27/2013 07:35 AM, Kumar, Sanjay wrote:
<snip>
> 6) As said this also explains what is going on, when printing another userspace app has the interface in question in use. I assume this is either something from cups, or some other part of hplip, so you will need to either wait and retry, or implement some proper locking; or ...
>
> [SANJAY]:During printing, hp backend claims the interface 0 (print interface). But it uses this interface 0 only for bulk transfer (EndPoint 8 in my printers case),
This does not matter, the Linux kernel groups endpoints by interface, and a driver
attaches to a single interface, this is also how things are written in the USB spec.
> however I got to know from HP firmware folks that during printing, printer status can also be queried by using control endpoint (which in fact happens correctly in libusb-1.0.9 or below versions.). So my doubt is that do we now really need to wait for hp backend to terminate before we can query the status from the device? Isn't is possible to write on OUT endpoint and control endpoint parallelly? What if there is a large print job ? Will driver have to wait for such a long time?
At the usb level you can access the control endpoint while bulk transfers are active,
this is correct.
But the Linux kernel allows only 1 driver per interface, for userspace drivers
(such as a libusb using app), the usbfs driver is attached to the interface
when you claim it.
The control endpoint does not belong to a specific interface, but certain
control requests do operate on a specific interface.
To avoid userspace applications messing with the interface settings of
interfaces the usbfs driver is not attached to the usbfs driver checks
control-requests from userspace and if they operate on an interface
which is not claimed, the control-request will be denied.
So before you can do the status request you want to do you must first
claim the interface, and you can only claim the interface if you
first detach any existing the driver from the interface.
I know your code already does the detach and the claim, I'm just trying
to explain why they are needed.
###
So one thing has changed in 1.0.16 compared to 1.0.9 wrt driver detaching,
and that is that we will no longer detach the driver if it is usbfs, since
that means an other userspace application is using the interface, and we
don't want to interfere with another libusb using application.
So with 1.0.16 if the interface is already claimed from another process
using libusb (*), then the detach_kernel_driver and the subsequent
claim_interface call will both fail with LIBUSB_ERROR_BUSY.
This is what you are seeing and this is a good thing.
Lets call the 2 process I believe are in play:
1) hp printing backend, which does the actual printing
2) hp status process, which makes the status control requests
What I believe is happening with 1.0.9 is something along the
lines of:
1) hp printing backend detaches the usblp driver
2) hp printing backend claims the interface (and the kernel now internally attaches the usbfs driver)
3) hp printing backend submits a bunch of bulk transfers
4) hp status process detaches the usbfs driver the hp printing backend is using
5) Note this denies further access to the bulk endpoint by the hp printing backend
unless the hp printing backend detaches and reclaims again!
6) hp status process claims the interface (re-attaching the usbfs driver, but now
on behalf of a different process)
7) hp status process makes its control request
With 1.0.16 what happens instead if the status process runs while
printing is:
4) hp status process tries to detach the usbfs driver
libusb returns LIBUSB_ERROR_BUSY
5) The hp printing backend happily keeps access to the interface
6) hp status process claims the interface
libusb returns LIBUSB_ERROR_BUSY
7) hp status process makes its control request
libusb returns LIBUSB_ERROR_BUSY
This is what breaks your printer status querying, but this is a good
thing, as detaching the usbfs driver while the hp printing backend is
printing is bad.
One possible fix is accessing both the bulk endpoint and the control endpoint
from one process, or if you're already using one process, by also using
only 1 device handle for both.
Alternatively we could change the kernel to simply always allow
the get_device_id printer request. We already have special handling in
the kernel for this request. Changing that code to allow this request without
having to claim the interface first is trivial, and given that it is a
read-only request also kind of sensible. Then you can simply make
the control request without first needing to do any detach- or claiming.
The downside of fixing this kernel side, is that it won't help with
hplip running on older kernels. Let me know if you want me to write a
kernel patch for this (and after you've tested it want me to push it
into the upstream kernel, assuming no-one nacks it).
> Detach kernel drivers is something which you should not do without very good reasons in general. In this case there is a better solution, there is a ieee1284_id file in sysfs which contains the exact string you're looking for, and you can get that without needing any special rights in usbfs, or without needing to detach the driver, ie when I turn on my printer, dmesg contains:
>
> [ 9643.182911] usblp 2-1.7:1.1: usblp0: USB Bidirectional printer dev 7 if 1 alt 0 proto 2 vid 0x03F0 pid 0x3B11
>
> So 2-1.7:1.1 is the printer class interface of my printer, and now I can get the device-id by a simple:
>
> cat /sys/bus/usb/devices/2-1.7:1.1/ieee1284_id
>
> You should seriously consider using this sysfs file, that seems a much better solution to your problem, without the need to coordinate (detach / claim / lock) with any other users of the printer.
>
> [SANJAY]: I could not get all the information which I get in device ID from ieee1284_id (especially for some devices, below string will contain device status cod)
> device ID:MFG:HP;MDL:Deskjet 2000 J210 series;CMD:PCL,DW-PCL,DESKJET,DYN;CLS:PRINTER;DES:CH390A;CID:HPIJVIPAV1;LEDMDIS:USB#07#01#02,USB#FF#04#01;SN:CN03N1C06M05HY;S:038000C484001021002c1f0001ec2880032;J: ;Z:0102,05037460009600,0600,0c0,0e00000000,0f00000000,10000008000008,12000,143,150,16361a3746000316da15ae0003,17000000000000;:
Ah, ok.
Regards,
Hans
*) Or through another libusb_device_handle if you open the same device
twice from the same process
|