From: Kumar, S. <san...@hp...> - 2013-06-20 12:16:56
|
Hello Hans, Many thanks for looking into this. While I continue to look into the issue I thought of sharing the information you asked for. Please find the logs you requested in the attachment and my comments inline below. Please let me know if I am doing something wrong or you need some more information. -----Original Message----- From: Hans de Goede [mailto:hde...@re...] Sent: Thursday, June 20, 2013 3:24 PM To: Kumar, Sanjay Cc: lib...@li... Subject: Re: [libusb] Can't write to a control endpoint in libusb-1.0.16_RC10, when bulk transfer (printing) is going on in interface 0 Hello Sanjay, On 06/20/2013 08:24 AM, Kumar, Sanjay wrote: > Hello All, > > I am working for HP Linux printer driver (HPLIP team ). Recently I found one issue in libusb-1.0.16RC release. I Can't write on a control endpoint in libusb-1.0.16_RC10, when bulk transfer (printing) is going on in interface 0. I have created a ticket also regarding the same but I can't see it in the active tickets. I've a HP printer (PSC 1350) myself, so I've tried to reproduce this, but I could not reproduce. Still I've a hunch of what is going on: [SANJAY]: I can still reproduce this issue after taking your changes (except interface number because for my printer interface 0 is used for printing) in Fedora 16 after upgrading the libusb version to 1.0.16RC. However 1.0.9 version works fine. 1) First of all, next time, and in your next mail, please include: -Actual output of your test program, esp. the error code given by the libusb_control_transfer would be useful, I bet it is LIBUSB_ERROR_BUSY -lsusb -v output for the device in question -relevant messages in dmesg if any [SANJAY]: In failure case claim interface itself is failing (LIBUSB_ERROR_BUSY). However claim interface does not fail with libusb-1.0.9 or below. 2) Your getdeviceID.c is buggy, my printer has a device-id length > 127 bytes and bad things happen because of sign extension, and you use memcpy where you should memmove, fixed version attached. Also if it fails to claim the interface (which I think it does), the program should stop, continuing after that point is useless. [SANJAY]: Corrected the code but same result. Please see the attached source file. 3) Are you sure that interface 0 is the right interface? On my printer interface 0 is a vendor interface, where as interface 1 is the actual printerclass interface, and the getvendorid call should be made on the printerclass interface. Note that it seems to work fine on both interface with my printer, ie both a wIndex of 0 and of (1 << 8) work. Note that the requested lsusb -v info will tell for sure. [SANJAY]: Attached lsusb.log for the same 4) In case of using 1 << 8 the usblp driver must first be detached from interface 1, since the linux kernel knows about the special wIndex usage for printerclasses, and looks at the upper 8 bits to determine which interface the ctrl req will apply too, and that must be claimed for the ctrl-req to be allowed (and thus the driver must be detached). [SANJAY]: ok 5) > 3) When printing is happening > > *libusb_kernel_driver_active()* returns 1 even after*libusb_detach_kernel_driver(hd, 0)* call is made. Please see the attached code also. Ah yes, this is a bug, which also explains what is going on, recent libusb code does not detach the kernel driver if it is usbfs, since then no other kernel driver is attached, but another userspace app is using it, and we don't want to interfere with that (detaching the kernel driver sometimes is a must, killing another userspace apps access is not). I've just pushed a bug-fix to libusbx git master fixing libusb_kernel_driver_active() to properly return 0 when the device is in use from userspace by another app. [SANJAY]: OK 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), 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? 7) As said you seem to be operating on the wrong interface, which actually is a good thing, because detaching the usblp kernel driver while printing will likely kill the print job halfway through, not good. [SANJAY]: usblp is detached even before printing is started as we make use of libusb_bulk_transfer APIs (usbfs) for printing. 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;: 8) Note that the libusbx and libusb projects are merging back together, and all development is happening in libusbx git atm, you can find the latest code here: https://github.com/libusbx/libusbx I don't expect this to fix your problem, other then the libusb_kernel_driver_active() returning 1 when the device is in use from userspace by another app bug. Also as said, if I were you I would just abandon the whole libusb approach and use sysfs instead. Regards, Hans |