X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_pci.c;h=5ee100e673746ff1c7c8458d6427fd71affd2a78;hb=88ff01ddfb13d580d5ca36b7a6fc1548bac769bf;hp=b74999137e3a01c49e3b863ea25ad8a1e2c86c2d;hpb=3dcfe0390c90560bdd4295dcb009e217521ca4a3;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c index b74999137e..5ee100e673 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 @@ -212,12 +184,9 @@ rte_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, @@ -250,7 +219,12 @@ rte_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) + 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); } @@ -512,10 +486,64 @@ 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; + bool start_found = !start; + + FOREACH_DEVICE_ON_PCIBUS(dev) { + if (!start_found) { + if (&dev->device == start) + start_found = 1; + 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_pci_scan, .probe = rte_pci_probe, + .find_device = pci_find_device, + .plug = pci_plug, + .unplug = pci_unplug, }, .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list), .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list),