if (devargs->bus != pbus)
continue;
devargs->bus->parse(devargs->name, &addr);
- if (!rte_eal_compare_pci_addr(&dev->addr, &addr))
+ if (!rte_pci_addr_cmp(&dev->addr, &addr))
return devargs;
}
return NULL;
}
+static inline const char *
+get_u8_pciaddr_field(const char *in, void *_u8, char dlm)
+{
+ unsigned long val;
+ uint8_t *u8 = _u8;
+ char *end;
+
+ errno = 0;
+ val = strtoul(in, &end, 16);
+ if (errno != 0 || end[0] != dlm || val > UINT8_MAX) {
+ errno = errno ? errno : EINVAL;
+ return NULL;
+ }
+ *u8 = (uint8_t)val;
+ return end + 1;
+}
+
+
+static int
+rte_pci_bdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+ const char *in = input;
+
+ dev_addr->domain = 0;
+ in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+ if (in == NULL)
+ return -EINVAL;
+ in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+ if (in == NULL)
+ return -EINVAL;
+ in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+ if (in == NULL)
+ return -EINVAL;
+ return 0;
+}
+
+int
+eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+ return rte_pci_bdf_parse(input, dev_addr);
+}
+
+static int
+rte_pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
+{
+ const char *in = input;
+ unsigned long val;
+ char *end;
+
+ errno = 0;
+ val = strtoul(in, &end, 16);
+ if (errno != 0 || end[0] != ':' || val > UINT16_MAX)
+ return -EINVAL;
+ dev_addr->domain = (uint16_t)val;
+ in = end + 1;
+ in = get_u8_pciaddr_field(in, &dev_addr->bus, ':');
+ if (in == NULL)
+ return -EINVAL;
+ in = get_u8_pciaddr_field(in, &dev_addr->devid, '.');
+ if (in == NULL)
+ return -EINVAL;
+ in = get_u8_pciaddr_field(in, &dev_addr->function, '\0');
+ if (in == NULL)
+ return -EINVAL;
+ return 0;
+}
+
+int
+eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
+{
+ return rte_pci_dbdf_parse(input, dev_addr);
+}
+
+void
+rte_pci_device_name(const struct rte_pci_addr *addr,
+ char *output, size_t size)
+{
+ RTE_VERIFY(size >= PCI_PRI_STR_SIZE);
+ RTE_VERIFY(snprintf(output, size, PCI_PRI_FMT,
+ addr->domain, addr->bus,
+ addr->devid, addr->function) >= 0);
+}
+
+int
+rte_pci_addr_cmp(const struct rte_pci_addr *addr,
+ const struct rte_pci_addr *addr2)
+{
+ uint64_t dev_addr, dev_addr2;
+
+ if ((addr == NULL) || (addr2 == NULL))
+ return -1;
+
+ dev_addr = ((uint64_t)addr->domain << 24) |
+ (addr->bus << 16) | (addr->devid << 8) | addr->function;
+ dev_addr2 = ((uint64_t)addr2->domain << 24) |
+ (addr2->bus << 16) | (addr2->devid << 8) | addr2->function;
+
+ if (dev_addr > dev_addr2)
+ return 1;
+ else if (dev_addr < dev_addr2)
+ return -1;
+ else
+ return 0;
+}
+
+int
+rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
+ const struct rte_pci_addr *addr2)
+{
+ return rte_pci_addr_cmp(addr, addr2);
+}
+
+int
+rte_pci_addr_parse(const char *str, struct rte_pci_addr *addr)
+{
+ if (rte_pci_bdf_parse(str, addr) == 0 ||
+ rte_pci_dbdf_parse(str, addr) == 0)
+ return 0;
+ return -1;
+}
+
void
pci_name_set(struct rte_pci_device *dev)
{
{
struct rte_pci_addr *loc;
struct rte_pci_driver *dr;
+ int ret = 0;
if (dev == NULL)
return -EINVAL;
RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
dev->id.device_id, dr->driver.name);
- if (dr->remove && (dr->remove(dev) < 0))
- return -1; /* negative value is an error */
+ if (dr->remove) {
+ ret = dr->remove(dev);
+ if (ret < 0)
+ return ret;
+ }
/* clear driver structure */
dev->driver = NULL;
goto err_return;
FOREACH_DEVICE_ON_PCIBUS(dev) {
- if (rte_eal_compare_pci_addr(&dev->addr, addr))
+ if (rte_pci_addr_cmp(&dev->addr, addr))
continue;
ret = pci_probe_all_drivers(dev);
return -1;
FOREACH_DEVICE_ON_PCIBUS(dev) {
- if (rte_eal_compare_pci_addr(&dev->addr, addr))
+ if (rte_pci_addr_cmp(&dev->addr, addr))
continue;
ret = rte_pci_detach_dev(dev);
struct rte_pci_addr pci_addr;
bool parse;
- parse = (eal_parse_pci_BDF(name, &pci_addr) == 0 ||
- eal_parse_pci_DomBDF(name, &pci_addr) == 0);
+ parse = (rte_pci_addr_parse(name, &pci_addr) == 0);
if (parse && addr != NULL)
*out = pci_addr;
return parse == false;
pdev = RTE_DEV_TO_PCI(dev);
ret = rte_pci_detach_dev(pdev);
- rte_pci_remove_device(pdev);
- free(pdev);
+ if (ret == 0) {
+ rte_pci_remove_device(pdev);
+ free(pdev);
+ }
return ret;
}
.plug = pci_plug,
.unplug = pci_unplug,
.parse = pci_parse,
+ .get_iommu_class = rte_pci_get_iommu_class,
},
.device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list),
.driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),