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 <ziye.yang at intel.com> --- 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 | 8 ++++++-- lib/librte_eal/linuxapp/eal/eal_pci.c | 10 ++++++++++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 7d94ba5..28f9c61 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -20,12 +20,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 2d16d78..7fdd6f1 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 3cae4cb..6c3117d 100644 --- a/lib/librte_eal/common/eal_common_pci.c +++ b/lib/librte_eal/common/eal_common_pci.c @@ -162,6 +162,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 8fa2712..c30adaf 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,6 +171,7 @@ 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 */ @@ -177,14 +179,16 @@ struct rte_pci_device { (vend), \ (dev), \ PCI_ANY_ID, \ - PCI_ANY_ID + PCI_ANY_ID, \ + RTE_CLASS_ANY_ID #else /** Macro used to help building up tables of device IDs */ #define RTE_PCI_DEVICE(vend, dev) \ .vendor_id = (vend), \ .device_id = (dev), \ .subsystem_vendor_id = PCI_ANY_ID, \ - .subsystem_device_id = PCI_ANY_ID + .subsystem_device_id = PCI_ANY_ID, \ + .class_id = RTE_CLASS_ANY_ID #endif struct rte_pci_driver; diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index bdc08a0..e6f0f13 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); -- 1.9.3