Can I reboot a USB device within a driver's probe function?
Thierry Seegers
thierry.seegers at gmail.com
Sun Sep 13 12:17:49 EDT 2020
Hi,
I have a USB device that when plugged into a computer shows up as a
generic USB device with product ID "0580". The only thing you're
expected to do is to upload firmware to it and reboot it. It then
disappears from the system and reappears as a USB video camera with
product ID "058a".
For example, here's a Python script
(https://github.com/longjie/ps4eye/blob/master/script/ps4eye_init.py)
that does just that. It uses Python usb.core and usb.util to upload a
firmware file as control packets. When that is done, it sends a
special control packet to reboot the device. After the device is
rebooted, it no longer shows up (using "lsusb", for example) as the
generic device but as a USB camera device and is taken in charge by
the corresponding driver. Note that sending that last control packet,
it will fail with an EPIPE error but that is expected since the
interface we were talking to is actually gone.
One can even have this script executed automatically through a
".rules" file. So far so good. My question is: can I write a driver
that will perform the same thing?
I started exploring the idea but I'm stuck. I have written such a
driver that performs the firmware upload and sends that special
control packet. It does all of this within the USB probe() function
which is called on the driver to see if it wants to handle the device.
My problem is that, after returning from the probe() function, the
system does not realize that the interface is actually gone and that a
new one has appeared. If I do "lsusb", the same "0580" device is still
listed and the new USB camera device isn't discovered.
No matter what I tried, I can't get the OS to "shake" this device
which is gone. I've tried the following:
- usb_driver_release_interface()
- usb_reset_configuration()
- interface->condition = USB_INTERFACE_UNBOUND;
- interface->needs_binding = 1;
- usb_put_intf();
- usb_put_dev();
- return -ENODEV
- return -EBUSY
I don't know what I'm supposed to do within (or outside) the probe
function to signify to the OS that this interface is actually not
existent anymore, that this driver doesn't want to deal with this
device any further and that it (the OS) should be listening to new
device connections.
Note that after sending the reboot packet, you can't communicate with
the device anymore, it would simply return EPIPE.
Thanks for your help
More information about the Kernelnewbies
mailing list