X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_pci.c;h=76bbcc85307273cb8a3e4e7cfc3dc685ab39f744;hb=25175fb2ab27966b7774be80f0caf94a40092ad9;hp=b6b41be311b389bdc8618b1981956bc6deb4f593;hpb=7917d5f5ea46e6e812ffbcbb451533bee1252428;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c index b6b41be311..76bbcc8530 100644 --- a/lib/librte_eal/common/eal_common_pci.c +++ b/lib/librte_eal/common/eal_common_pci.c @@ -2,6 +2,7 @@ * BSD LICENSE * * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright 2013-2014 6WIND S.A. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,36 +31,6 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* BSD LICENSE - * - * Copyright 2013-2014 6WIND S.A. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of 6WIND S.A. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ #include #include @@ -76,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -102,12 +74,15 @@ const char *pci_get_sysfs_path(void) static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev) { struct rte_devargs *devargs; + struct rte_pci_addr addr; + struct rte_bus *pbus; + pbus = rte_bus_find_by_name("pci"); TAILQ_FOREACH(devargs, &devargs_list, next) { - if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI && - devargs->type != RTE_DEVTYPE_WHITELISTED_PCI) + if (devargs->bus != pbus) continue; - if (!rte_eal_compare_pci_addr(&dev->addr, &devargs->pci.addr)) + devargs->bus->parse(devargs->name, &addr); + if (!rte_eal_compare_pci_addr(&dev->addr, &addr)) return devargs; } return NULL; @@ -200,8 +175,8 @@ rte_pci_match(const struct rte_pci_driver *pci_drv, * driver. */ static int -rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, - struct rte_pci_device *dev) +rte_pci_probe_one_driver(struct rte_pci_driver *dr, + struct rte_pci_device *dev) { int ret; struct rte_pci_addr *loc; @@ -212,12 +187,9 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, loc = &dev->addr; /* The device is not blacklisted; Check if driver supports it */ - if (!rte_pci_match(dr, dev)) { + if (!rte_pci_match(dr, dev)) /* Match of device and driver failed */ - RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n", - dr->driver.name); return 1; - } RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", loc->domain, loc->bus, loc->devid, loc->function, @@ -226,7 +198,7 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, /* no initialization when blacklisted, return without error */ if (dev->device.devargs != NULL && dev->device.devargs->type == - RTE_DEVTYPE_BLACKLISTED_PCI) { + RTE_DEVTYPE_BLACKLISTED) { RTE_LOG(INFO, EAL, " Device is blacklisted, not" " initializing\n"); return 1; @@ -237,7 +209,7 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) { /* map resources for devices that use igb_uio */ - ret = rte_eal_pci_map_device(dev); + ret = rte_pci_map_device(dev); if (ret != 0) return ret; } @@ -250,8 +222,13 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, ret = dr->probe(dr, dev); if (ret) { dev->driver = NULL; - if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) - rte_eal_pci_unmap_device(dev); + if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) && + /* Don't unmap if device is unsupported and + * driver needs mapped resources. + */ + !(ret > 0 && + (dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES))) + rte_pci_unmap_device(dev); } return ret; @@ -262,7 +239,7 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, * driver. */ static int -rte_eal_pci_detach_dev(struct rte_pci_device *dev) +rte_pci_detach_dev(struct rte_pci_device *dev) { struct rte_pci_addr *loc; struct rte_pci_driver *dr; @@ -288,7 +265,7 @@ rte_eal_pci_detach_dev(struct rte_pci_device *dev) if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) /* unmap resources for devices that use igb_uio */ - rte_eal_pci_unmap_device(dev); + rte_pci_unmap_device(dev); return 0; } @@ -312,7 +289,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev) return 0; FOREACH_DRIVER_ON_PCIBUS(dr) { - rc = rte_eal_pci_probe_one_driver(dr, dev); + rc = rte_pci_probe_one_driver(dr, dev); if (rc < 0) /* negative value is an error */ return -1; @@ -326,10 +303,10 @@ pci_probe_all_drivers(struct rte_pci_device *dev) /* * Find the pci device specified by pci address, then invoke probe function of - * the driver of the devive. + * the driver of the device. */ int -rte_eal_pci_probe_one(const struct rte_pci_addr *addr) +rte_pci_probe_one(const struct rte_pci_addr *addr) { struct rte_pci_device *dev = NULL; @@ -366,7 +343,7 @@ err_return: * Detach device specified by its pci address. */ int -rte_eal_pci_detach(const struct rte_pci_addr *addr) +rte_pci_detach(const struct rte_pci_addr *addr) { struct rte_pci_device *dev = NULL; int ret = 0; @@ -378,7 +355,7 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr) if (rte_eal_compare_pci_addr(&dev->addr, addr)) continue; - ret = rte_eal_pci_detach_dev(dev); + ret = rte_pci_detach_dev(dev); if (ret < 0) /* negative value is an error */ goto err_return; @@ -386,7 +363,7 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr) /* positive value means driver doesn't support it */ continue; - rte_eal_pci_remove_device(dev); + rte_pci_remove_device(dev); free(dev); return 0; } @@ -405,7 +382,7 @@ err_return: * for discovered devices. */ int -rte_eal_pci_probe(void) +rte_pci_probe(void) { struct rte_pci_device *dev = NULL; size_t probed = 0, failed = 0; @@ -413,7 +390,7 @@ rte_eal_pci_probe(void) int probe_all = 0; int ret = 0; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0) + if (rte_pci_bus.bus.conf.scan_mode != RTE_BUS_SCAN_WHITELIST) probe_all = 1; FOREACH_DEVICE_ON_PCIBUS(dev) { @@ -428,7 +405,7 @@ rte_eal_pci_probe(void) if (probe_all) ret = pci_probe_all_drivers(dev); else if (devargs != NULL && - devargs->type == RTE_DEVTYPE_WHITELISTED_PCI) + devargs->type == RTE_DEVTYPE_WHITELISTED) ret = pci_probe_all_drivers(dev); if (ret < 0) { RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT @@ -465,7 +442,7 @@ pci_dump_one_device(FILE *f, struct rte_pci_device *dev) /* dump devices on the bus */ void -rte_eal_pci_dump(FILE *f) +rte_pci_dump(FILE *f) { struct rte_pci_device *dev = NULL; @@ -474,9 +451,23 @@ rte_eal_pci_dump(FILE *f) } } +static int +pci_parse(const char *name, void *addr) +{ + struct rte_pci_addr *out = addr; + 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); + if (parse && addr != NULL) + *out = pci_addr; + return parse == false; +} + /* register a driver */ void -rte_eal_pci_register(struct rte_pci_driver *driver) +rte_pci_register(struct rte_pci_driver *driver) { TAILQ_INSERT_TAIL(&rte_pci_bus.driver_list, driver, next); driver->bus = &rte_pci_bus; @@ -484,7 +475,7 @@ rte_eal_pci_register(struct rte_pci_driver *driver) /* unregister a driver */ void -rte_eal_pci_unregister(struct rte_pci_driver *driver) +rte_pci_unregister(struct rte_pci_driver *driver) { TAILQ_REMOVE(&rte_pci_bus.driver_list, driver, next); driver->bus = NULL; @@ -492,33 +483,86 @@ rte_eal_pci_unregister(struct rte_pci_driver *driver) /* Add a device to PCI bus */ void -rte_eal_pci_add_device(struct rte_pci_device *pci_dev) +rte_pci_add_device(struct rte_pci_device *pci_dev) { TAILQ_INSERT_TAIL(&rte_pci_bus.device_list, pci_dev, next); } /* Insert a device into a predefined position in PCI bus */ void -rte_eal_pci_insert_device(struct rte_pci_device *exist_pci_dev, - struct rte_pci_device *new_pci_dev) +rte_pci_insert_device(struct rte_pci_device *exist_pci_dev, + struct rte_pci_device *new_pci_dev) { TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next); } /* Remove a device from PCI bus */ void -rte_eal_pci_remove_device(struct rte_pci_device *pci_dev) +rte_pci_remove_device(struct rte_pci_device *pci_dev) { TAILQ_REMOVE(&rte_pci_bus.device_list, pci_dev, next); } +static struct rte_device * +pci_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, + const void *data) +{ + struct rte_pci_device *dev; + + FOREACH_DEVICE_ON_PCIBUS(dev) { + if (start && &dev->device == start) { + start = NULL; /* starting point found */ + continue; + } + if (cmp(&dev->device, data) == 0) + return &dev->device; + } + + return NULL; +} + +static int +pci_plug(struct rte_device *dev, const char *devargs __rte_unused) +{ + struct rte_pci_device *pdev; + struct rte_pci_addr *addr; + + addr = &RTE_DEV_TO_PCI(dev)->addr; + + /* Find the current device holding this address in the bus. */ + FOREACH_DEVICE_ON_PCIBUS(pdev) { + if (rte_eal_compare_pci_addr(&pdev->addr, addr) == 0) + return rte_pci_probe_one(addr); + } + + rte_errno = ENODEV; + return -1; +} + +static int +pci_unplug(struct rte_device *dev) +{ + struct rte_pci_device *pdev; + + pdev = RTE_DEV_TO_PCI(dev); + if (rte_pci_detach(&pdev->addr) != 0) { + rte_errno = ENODEV; + return -1; + } + return 0; +} + struct rte_pci_bus rte_pci_bus = { .bus = { - .scan = rte_eal_pci_scan, - .probe = rte_eal_pci_probe, + .scan = rte_pci_scan, + .probe = rte_pci_probe, + .find_device = pci_find_device, + .plug = pci_plug, + .unplug = pci_unplug, + .parse = pci_parse, }, .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list), .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list), }; -RTE_REGISTER_BUS(PCI_BUS_NAME, rte_pci_bus.bus); +RTE_REGISTER_BUS(pci, rte_pci_bus.bus);