[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[H-source-users] Improving the h-client devices classes

From: Denis 'GNUtoo' Carikli
Subject: [H-source-users] Improving the h-client devices classes
Date: Sat, 14 Aug 2021 04:25:36 +0200


The h-client uses busses (like PCIe or USB) devices class IDs to find
the device class (Ethernet, Video card, etc).

For example PCI(e) devices export a class code in their configuration

31              16 15              0
 | Device ID      | Vendor ID      |
 | Status         | Command        |
 | Class code             | Rev ID |

So here we just have to read the Class code from there, and as class
codes are standard we know what they mean and we can find the device
class in this way.

So for instance if we have the following Ethernet controller which
looks like that with 'lspci -nn':
> 00:19.0 Ethernet controller [0200]: Intel Corporation 82567LM Gigabit
> Network Connection [8086:10f5] (rev 03)

The "Ethernet controller" class is 0x0200 here.

So h-client knows that 0x2000 is "Ethernet controller" and approximates
it to "Ethernet card" in hclient/devicetypes.py:
> class EthernetCard(DeviceType):
>       """Ethernet card."""
>       interfaces = MOST_INTERFACES
>       interfaces_post = MOST_INTERFACES_POST
>       how_it_works_post_name = "ethernet_card_works"
>       classes = (0x0200,)
>       type_name = "ethernet-card"
>       controller = "ethernetcards"
>       icon = "ethernet-card.png"

So if a PCI(e) device has the 0x0200 class code it get categorized as
an Ethernet card.

However that looks way less straightforward with USB.

If we look at the "CDC-Data" base class from the USB website[2] we have
something like that:
| Base Class | SubClass | Protocol |
| 0x0a       | 0xXX     | 0xXX     |    

Here while the base class is 0x0a, the sub class and the protocol can be
of any value.

In some other classes like Still Imaging we have specific sub classes
and protocols:
| Base Class | SubClass | Protocol |
| 0x0a       | 0x01     | 0x01     |    

That corresponds to scanners according to h-client:
> class Scanner(DeviceType):
>     """Scanner."""
>     classes = (0x060101,)
>     type_name = "scanner"
>     controller = "scanners"
>     icon = "scanner.png"

And some are even more problematic:
> class Webcam(DeviceType):
>     """Web cam."""
>     classes = (0x0e0100, 0xff0100)
>     type_name = "webcam"
>     controller = "webcams"
>     icon = "webcam.png"

Here it means that some webcams use the video class[4], but also the
vendor specific class[5].

Here I see several limitations to this design:
- The classes ids in the DeviceType subclasses are not specific to a
  bus, so it's prone to collisions.
- We can't easily match the USB CDC class (0x0aXXXX) as the classes
  field here uses fixed values.

Would be a good idea to instead use a function inside the DeviceType
subclasses to return some value (like True / False or True / False /
Unknown) if the ID matches and also have the bus name passed to that
function as well?

The function could look like that for instance:
> match_class(id, iface):
>     # Matches USB's CDC-Data class (0x0aXXXX)
>     if iface == 'USB' and (id >> 16) = 0x0a:
>         return True
>     if iface in has_pci_config_space(iface) and id == 0x200:
>         return True
>     return False

PS: Note that I'm not that fluent in python: for instance I am not
    used to more advanced language features like decorators, so reading
    or writing code that use these is more complicated for me than for
    people used to that way of programming.



Attachment: pgpSme43vXXzo.pgp
Description: OpenPGP digital signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]