10

I am writing a C++ Linux userspace driver for a USB device using the C library libusb. I have two copies of the same device (same vendor ID and product ID) and would like to know how to handle this case.

Here are the possibilities I can think of:


How should I deal with this? Which of the preceding options, if any, is the behaviour of libusb when dealing with many of the same devices? How can I differentiate between the in-use device and the idle one?


As @fiscblog said in his answer, "Identification is done via the device descriptor (use the serialnumber which should always be unique)". My problem here is that, in order to do so, the two drivers should communicate to know which instance is handling which device (using, for instance, a file), and I would like to avoid this. I also would like to avoid having to introduce multithreading and manage two devices with one driver, as I don't have the skills to do so in an efficient and well-controlled way (nasty race conditions ... !)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Magix
  • 4,989
  • 7
  • 26
  • 50
  • 1
    Open it when you need to open it and handle the error if and when it happens. Anything else is tantamount to trying to predict the future. Computers are not crystal balls. – user207421 May 02 '17 at 09:33
  • 1
    @EJP Yes, but when having two copies of a same device, you actually want each instance of the driver to manage a different copy of the device... not two drivers for 1 device, and the other device left unmanaged ! The error that happens is at device's configuration, and opening it two times works perfectly well. – Magix May 02 '17 at 16:26
  • You might want to have a look [here](https://unix.stackexchange.com/a/60080/123888)...Good luck! – vlp May 05 '17 at 21:52

3 Answers3

4

The correct handling is:

  • enumerate all devices (get device list)
  • identify the requested device and open it

Identification is done via the device descriptor (use the serialnumber which should always be unique), as you discovered yourself.

How to know if a device is in use?

If a device is open, the endpoints will be bound and configured for I/O. Therefore you cannot open it again but will get the error codes you mentioned.

fiscblog
  • 694
  • 1
  • 12
  • 27
  • Unfortunately, even though the device is opened on one instance of the driver, it looks like it can also be opened in the other instance. The moment it stops working is when I try to set the device's configuration... – Magix May 02 '17 at 16:24
  • It is _visible_ in another instance (it must be), but cannot be used twice. Unfortunately libusb doesn't have a "isOpen" member, instead you can tell by serialnumber that you're already using it somewhere else. – fiscblog May 03 '17 at 11:03
  • Does this means there must be some communication channel between the two drivers ? – Magix May 03 '17 at 11:18
  • 1
    And, more importantly, if there are n copies of the same device, should there be a communication channel (be it lock files etc...) between the n drivers ? This surely doesn't look very practical – Magix May 03 '17 at 11:35
  • No, certainly not. A device in use has only one kernel driver per interface (which has to be detached after use). For reading a descriptor no driver is necessary. – fiscblog May 03 '17 at 12:09
  • I don't really get it. To be clearer, could you please post a code excerpt that shows how I can use the device descriptor to differentiate the in-use device with the idle one knowing they have the same VID/PID combination ? thank you :) – Magix May 03 '17 at 13:15
  • Please note I do not know in advance their serial number – Magix May 03 '17 at 13:17
  • I think you're missing some important key points of usb communication. The descriptor does not tell anything about the actual state of the endpoints nor interfaces (except full/high/super speed maybe). It just gives you basic information the manufacturer provided, see http://www.beyondlogic.org/usbnutshell/usb5.shtml If your code follows the usb spec it should be no problem to successfully open a device. Again, distinguish between similar devices through their serial number which you can read from the device descriptor. – fiscblog May 03 '17 at 14:57
  • Btw libusb itself provides code examples how to open a device. – fiscblog May 03 '17 at 15:01
  • 1
    Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143312/discussion-between-magix-and-fiscblog). – Magix May 03 '17 at 16:05
3

According to the documentation on libusb_claim_interface():

Interface claiming is used to instruct the underlying operating system that your application wishes to take ownership of the interface.

so you should be able to call libusb_claim_interface() on each device and it should only succeed on the unclaimed one:

It is legal to attempt to claim an already-claimed interface, in which case libusb just returns 0 without doing anything.

Jan-Gerd
  • 1,261
  • 8
  • 8
2

libusb is written in C and follows the same basic general guidelines for accessing devices, file descriptors, streams, etc.

1 - Connect to de device

2 - Check the connection, if there's an error, inform and return

3 - There's no error!! Interact

Following this basic flow, the solution in your case IMHO is as simple as:

  • Identify the devices
  • Iterate througth them trying to connect until one throws no failure
  • do something
  • close
PRDeving
  • 679
  • 3
  • 11