From 701c8d80c820461e8255dfb7387a09f0e54399f0 Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Tue, 24 May 2016 20:50:36 +0800 Subject: [PATCH] pci: support class id probing This patch is used to add the class_id (class_code, subclass_code, programming_interface) support for pci_device probe. With this patch, it will be flexible for users to probe a class of devices by class_id. Signed-off-by: Ziye Yang --- doc/guides/rel_notes/deprecation.rst | 6 ------ lib/librte_eal/bsdapp/eal/eal_pci.c | 5 +++++ lib/librte_eal/common/eal_common_pci.c | 3 +++ lib/librte_eal/common/include/rte_pci.h | 4 ++++ lib/librte_eal/linuxapp/eal/eal_pci.c | 10 ++++++++++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index bda40c1b1e..7d947ae084 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -23,12 +23,6 @@ Deprecation Notices do not need to care about the kind of devices that are being used, making it easier to add new buses later. -* ABI changes are planned for struct rte_pci_id, i.e., add new field ``class``. - This new added ``class`` field can be used to probe pci device by class - related info. This change should impact size of struct rte_pci_id and struct - rte_pci_device. The release 16.04 does not contain these ABI changes, but - release 16.07 will. - * The xstats API and rte_eth_xstats struct will be changed to allow retrieval of values without any string copies or parsing. No backwards compatibility is planned, as it would require code duplication diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c index 2d16d782d8..7fdd6f1d92 100644 --- a/lib/librte_eal/bsdapp/eal/eal_pci.c +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -278,6 +278,11 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) /* get subsystem_device id */ dev->id.subsystem_device_id = conf->pc_subdevice; + /* get class id */ + dev->id.class_id = (conf->pc_class << 16) | + (conf->pc_subclass << 8) | + (conf->pc_progif); + /* TODO: get max_vfs */ dev->max_vfs = 0; diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c index 0ec3b610c3..ba5283da76 100644 --- a/lib/librte_eal/common/eal_common_pci.c +++ b/lib/librte_eal/common/eal_common_pci.c @@ -175,6 +175,9 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d if (id_table->subsystem_device_id != dev->id.subsystem_device_id && id_table->subsystem_device_id != PCI_ANY_ID) continue; + if (id_table->class_id != dev->id.class_id && + id_table->class_id != RTE_CLASS_ANY_ID) + continue; struct rte_pci_addr *loc = &dev->addr; diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index 7669fd7830..43d17b36e1 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -125,6 +125,7 @@ struct rte_pci_resource { * table of these IDs for each device that it supports. */ struct rte_pci_id { + uint32_t class_id; /**< Class ID (class, subclass, pi) or RTE_CLASS_ANY_ID. */ uint16_t vendor_id; /**< Vendor ID or PCI_ANY_ID. */ uint16_t device_id; /**< Device ID or PCI_ANY_ID. */ uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or PCI_ANY_ID. */ @@ -170,10 +171,12 @@ struct rte_pci_device { /** Any PCI device identifier (vendor, device, ...) */ #define PCI_ANY_ID (0xffff) +#define RTE_CLASS_ANY_ID (0xffffff) #ifdef __cplusplus /** C++ macro used to help building up tables of device IDs */ #define RTE_PCI_DEVICE(vend, dev) \ + RTE_CLASS_ANY_ID, \ (vend), \ (dev), \ PCI_ANY_ID, \ @@ -181,6 +184,7 @@ struct rte_pci_device { #else /** Macro used to help building up tables of device IDs */ #define RTE_PCI_DEVICE(vend, dev) \ + .class_id = RTE_CLASS_ANY_ID, \ .vendor_id = (vend), \ .device_id = (dev), \ .subsystem_vendor_id = PCI_ANY_ID, \ diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index 5041228bf1..e6990baed4 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -306,6 +306,16 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus, } dev->id.subsystem_device_id = (uint16_t)tmp; + /* get class_id */ + snprintf(filename, sizeof(filename), "%s/class", + dirname); + if (eal_parse_sysfs_value(filename, &tmp) < 0) { + free(dev); + return -1; + } + /* the least 24 bits are valid: class, subclass, program interface */ + dev->id.class_id = (uint32_t)tmp & RTE_CLASS_ANY_ID; + /* get max_vfs */ dev->max_vfs = 0; snprintf(filename, sizeof(filename), "%s/max_vfs", dirname); -- 2.20.1