3

I need to get some parameters related to USB Host Controllers in Linux. I made a lot of searches in the internet and the only way that I found is using pciutils lib. Each PCI device is in the structure pci_dev in pci.h:

struct pci_dev {
  struct pci_dev *next;         /* Next device in the chain */
  u16 domain_16;            /* 16-bit version of the PCI domain for backward compatibility */
                    /* 0xffff if the real domain doesn't fit in 16 bits */
  u8 bus, dev, func;            /* Bus inside domain, device and function */

  /* These fields are set by pci_fill_info() */
  int known_fields;         /* Set of info fields already known */
  u16 vendor_id, device_id;     /* Identity of the device */
  u16 device_class;         /* PCI device class */
  int irq;              /* IRQ number */
  pciaddr_t base_addr[6];       /* Base addresses including flags in lower bits */
  pciaddr_t size[6];            /* Region sizes */
  pciaddr_t rom_base_addr;      /* Expansion ROM base address */
  pciaddr_t rom_size;           /* Expansion ROM size */
  struct pci_cap *first_cap;        /* List of capabilities */
  char *phy_slot;           /* Physical slot */
  char *module_alias;           /* Linux kernel module alias */
  char *label;              /* Device name as exported by BIOS */
  int numa_node;            /* NUMA node */
  pciaddr_t flags[6];           /* PCI_IORESOURCE_* flags for regions */
  pciaddr_t rom_flags;          /* PCI_IORESOURCE_* flags for expansion ROM */
  int domain;               /* PCI domain (host bridge) */

  /* Fields used internally */
  struct pci_access *access;
  struct pci_methods *methods;
  u8 *cache;                /* Cached config registers */
  int cache_len;
  int hdrtype;              /* Cached low 7 bits of header type, -1 if unknown */
  void *aux;                /* Auxiliary data */
  struct pci_property *properties;  /* A linked list of extra properties */
  struct pci_cap *last_cap;     /* Last capability in the list */
};

I found also that I can parse pci devices as following:

struct pci_access *pacc1;
struct pci_dev *dev1;
unsigned int c1;
char namebuf1[1024], *name1;

pacc1 = pci_alloc();        /* Get the pci_access structure */
/* Set all options you want -- here we stick with the defaults */
pci_init(pacc1);        /* Initialize the PCI library */
pci_scan_bus(pacc1);        /* We want to get the list of devices */
for (dev1=pacc1->devices; dev1; dev1=dev1->next)    /* Iterate over all devices */
{
    pci_fill_info(dev1, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS);  /* Fill in header info we need */
    c1 = pci_read_byte(dev1, PCI_INTERRUPT_PIN);                /* Read config register directly */
    printf("%04x:%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d (pin %d) base0=%lx",
     dev1->domain, dev1->bus, dev1->dev, dev1->func, dev1->vendor_id, dev1->device_id,
     dev1->device_class, dev1->irq, c1, (long) dev1->base_addr[0]);

    /* Look up and print the full name of the device */
    name1 = pci_lookup_name(pacc, namebuf1, sizeof(namebuf1), PCI_LOOKUP_DEVICE, dev1->vendor_id, dev1->device_id);
    printf(" ***************** %d: (%s)\n", dev1->dev, name1);
}
pci_cleanup(pacc1);     /* Close everything */

Is there a way to check in the loop if the corresponding pci device corresponds to an USB Host Controller? Or is there a simpler way to get USB Host Controller infos?

Kallel Omar
  • 1,208
  • 2
  • 17
  • 51
  • 2
    The PCI class code should indicate whether it is a USB host controller. I don't know why it only fills in the upper 16 bits of the 24-bit class code in the `device_class` member, missing out the lower 8 bits that contain the 'programming interface' code. That would tell you the type of USB host controller. – Ian Abbott Jul 12 '19 at 14:42
  • 3
    PCI class code for USB controller is 0x0c03. The 'programming interface' byte is 0x00 for UHCI, 0x10 for OHCI, 0x20 for EHCI, 0x30 for XHCI, 0x80 for 'unspecified', 0xFE for a USB device (not a host controller). – Ian Abbott Jul 12 '19 at 14:53
  • @IanAbbott : will gladly upvote a Hello World demo code for this! Can you provide a reference that included this info? Thanks in any case. – shellter Jul 12 '19 at 15:03
  • 2
    Here is a non-authoritative (but good) reference: https://pci-ids.ucw.cz/read/PD/0c/03 – Ian Abbott Jul 12 '19 at 15:06
  • @IanAbbott: Thank you for your comments. Do you mean that if device_class is 0x0c03 so it corresponds to a Host Controller? – Kallel Omar Jul 15 '19 at 08:29
  • @IanAbbott: I need also to know the type of the Host controller (OHCI, EHCI, UHCI, xHCI). Seems your second and third can help. Could you please clarify what do you mean by "The 'programming interface' byte is 0x00 for UHCI ..." what's the programming interface? – Kallel Omar Jul 15 '19 at 08:36
  • 2
    Byte 09h of the PCI configuration header is the "program interface" byte of the class code. – Ian Abbott Jul 15 '19 at 10:07

0 Answers0