From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by dpdk.org (Postfix) with ESMTP id B08E0A2F for ; Wed, 15 Feb 2017 12:08:39 +0100 (CET) Received: by mail-wr0-f194.google.com with SMTP id q39so114621wrb.2 for ; Wed, 15 Feb 2017 03:08:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=mMtkqtgQOCgE9Sm6U/9aiWw000QbkgCs8xB1lsoEbcg=; b=gRDmRbQzZ+IQjtk5mcwdvY+vGP1mP2mep12BghROWOWbCsp9E7zp18yISeOwAI8pQ0 iEAS0cAIo1BJGr90vRYCJrzuRokeTwinH0MH5eTuIGsTxEjRKsmGSWkXPOhcoG2x4dQp rxB8vADIxELvE/liS+nCtrK7/r8Sf0bDyTNFKbw48bqKsPI3khCsPyV8M/jc5AMexJEO HRTIZ5urULFb2Le/1JglZrk5im4Uj63APycnrVSWXzN0lzpUxFPeNk+iSc8ksmZ453kU 6xTUwjCwNZ16yhXWmgosBgA8CjV1t4jIxr7RTB7VOkR4/YLnwdLw3OvhRFwKHO6sO1vU zQvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=mMtkqtgQOCgE9Sm6U/9aiWw000QbkgCs8xB1lsoEbcg=; b=DBBp+iGrldv6C7j6zq+gC36qPsWE9T0K/aG/yUjUNJUVEt9mb4AnKax0BUNlLh6a5a mVz50Gqo9hyrtGZH/V0mlNymHnkgp9E2ghKePurkLP1R48H9kg9cmK7/5sXpnTU6MQUr 4Py9ANNgpnCYtVV+kLY7z3jIj0jo8UndLSXk309xgspZ1ARQ9wSfwA1K7LQpmBZz+6KG +REc/iwRwfgt+VoPnLsuY+rqUoyLiUPqs3EqDPrjXXpb/bvs9GPPPfBfYDguIX6zLasR CVXm1BhJt6+SzD/M40poMpODZWZ1jxVAxn44X2PoC2AO++U7ZJUzdUo9B36DlwzzyzQK Hj2w== X-Gm-Message-State: AMke39nzgSgjaKSTglQPSBSHJIFWFfH6h9oOzhp2mO4+ecdI7T/KuM5gmFIAqbWXNgp/hnbLVwrCd1FQcVt2lA== X-Received: by 10.223.132.166 with SMTP id 35mr28283612wrg.122.1487156919273; Wed, 15 Feb 2017 03:08:39 -0800 (PST) MIME-Version: 1.0 Sender: jblunck@gmail.com Received: by 10.28.211.20 with HTTP; Wed, 15 Feb 2017 03:08:38 -0800 (PST) In-Reply-To: <1484801117-779-13-git-send-email-thomas.monjalon@6wind.com> References: <1484748329-5418-1-git-send-email-shreyansh.jain@nxp.com> <1484801117-779-1-git-send-email-thomas.monjalon@6wind.com> <1484801117-779-13-git-send-email-thomas.monjalon@6wind.com> From: Jan Blunck Date: Wed, 15 Feb 2017 12:08:38 +0100 X-Google-Sender-Auth: Ji3__jaPFIwywHsuJQVsS_y3jxg Message-ID: To: Thomas Monjalon Cc: Shreyansh Jain , dev Content-Type: text/plain; charset=UTF-8 Subject: Re: [dpdk-dev] [PATCH v11 12/13] pci: use bus driver for attach/detach X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Feb 2017 11:08:39 -0000 On Thu, Jan 19, 2017 at 5:45 AM, Thomas Monjalon wrote: > From: Shreyansh Jain > > Given a bus, attach and detach callbacks allow the implementation to > handles calls from EAL for attaching or detaching a named device. > > Signed-off-by: Shreyansh Jain > Reviewed-by: Ferruh Yigit > --- > lib/librte_eal/bsdapp/eal/eal_pci.c | 2 + > lib/librte_eal/common/eal_common_dev.c | 56 ++++++++++++++++----- > lib/librte_eal/common/eal_common_pci.c | 89 +++++++++++++++++++++++++++++++-- > lib/librte_eal/common/include/rte_bus.h | 31 ++++++++++++ > lib/librte_eal/common/include/rte_pci.h | 45 +++++++++++------ > lib/librte_eal/linuxapp/eal/eal_pci.c | 2 + > 6 files changed, 193 insertions(+), 32 deletions(-) > > diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c > index 103ad70..38a75af 100644 > --- a/lib/librte_eal/bsdapp/eal/eal_pci.c > +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c > @@ -670,6 +670,8 @@ struct rte_pci_bus rte_pci_bus = { > .bus = { > .scan = rte_eal_pci_scan, > .probe = rte_eal_pci_probe, > + .attach = rte_eal_pci_attach, > + .detach = rte_eal_pci_detach, > }, > .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list), > .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list), > diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c > index 4f3b493..97d0cf5 100644 > --- a/lib/librte_eal/common/eal_common_dev.c > +++ b/lib/librte_eal/common/eal_common_dev.c > @@ -38,6 +38,7 @@ > #include > > #include > +#include > #include > #include > #include > @@ -106,23 +107,37 @@ rte_eal_dev_init(void) > > int rte_eal_dev_attach(const char *name, const char *devargs) > { > - struct rte_pci_addr addr; > + int ret = 1; > + struct rte_bus *bus; > > if (name == NULL || devargs == NULL) { > RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n"); > return -EINVAL; > } > > - if (eal_parse_pci_DomBDF(name, &addr) == 0) { > - if (rte_eal_pci_probe_one(&addr) < 0) > + FOREACH_BUS(bus) { > + if (!bus->attach) { > + RTE_LOG(DEBUG, EAL, "Bus (%s) doesn't implement" > + " attach.\n", bus->name); > + continue; > + } > + ret = bus->attach(name); Enforcing a globally unique naming scheme for the low-level device makes this complicated for users. There are buses that enumerate the devices just by an integer so we will have conflicts. I think it is better to change the signature of rte_eal_dev_attach() instead and find the correct bus based on its name. Also I believe the API is more user friendly if we pass the complete (raw) devargs string instead of the name/args pair. > + if (!ret) /* device successfully attached */ > + return ret; > + if (ret > 0) /* device not found on bus */ > + continue; > + else > goto err; > + } > > - } else { > - if (rte_eal_vdev_init(name, devargs)) > + if (ret > 0) { > + /* In case the device was not found on any bus, search VDEV */ > + ret = rte_eal_vdev_init(name, devargs); > + if (ret) > goto err; > } > > - return 0; > + return ret; > > err: > RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n", name); > @@ -131,21 +146,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs) > > int rte_eal_dev_detach(const char *name) > { > - struct rte_pci_addr addr; > + int ret = 1; > + struct rte_bus *bus; > > if (name == NULL) { > RTE_LOG(ERR, EAL, "Invalid device provided.\n"); > return -EINVAL; > } > > - if (eal_parse_pci_DomBDF(name, &addr) == 0) { > - if (rte_eal_pci_detach(&addr) < 0) > + FOREACH_BUS(bus) { > + if (!bus->detach) { > + RTE_LOG(DEBUG, EAL, "Bus (%s) doesn't implement" > + " detach.\n", bus->name); > + continue; > + } > + > + ret = bus->detach(name); > + if (!ret) /* device successfully detached */ > + return ret; > + if (ret > 0) /* device not found on the bus */ > + continue; > + else > goto err; > - } else { > - if (rte_eal_vdev_uninit(name)) > + } > + > + if (ret > 0) { > + /* In case the device was not found on any bus, search VDEV */ > + ret = rte_eal_vdev_uninit(name); > + if (ret) > goto err; > } > - return 0; > + > + return ret; > > err: > RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name); > diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c > index 5149e6e..6866b04 100644 > --- a/lib/librte_eal/common/eal_common_pci.c > +++ b/lib/librte_eal/common/eal_common_pci.c > @@ -358,19 +358,98 @@ rte_eal_pci_probe_one(const struct rte_pci_addr *addr) > } > > /* > + * Attach device specific by its name > + */ > +int > +rte_eal_pci_attach(const char *device_name) > +{ > + struct rte_pci_device *dev = NULL; > + struct rte_pci_driver *drv = NULL; > + struct rte_pci_addr addr; > + int ret; > + > + if (!device_name) > + return -1; > + > + memset(&addr, 0, sizeof(addr)); > + if (eal_parse_pci_DomBDF(device_name, &addr)) { > + /* Device doesn't match PCI BDF naming format */ > + return 1; > + } > + > + if (pci_update_device(&addr) < 0) > + goto err_return; > + > + FOREACH_DEVICE_ON_PCIBUS(dev) { > + if (rte_eal_compare_pci_addr(&dev->addr, &addr)) > + continue; > + > + FOREACH_DRIVER_ON_PCIBUS(drv) { > + ret = rte_pci_match(drv, dev); > + if (ret) { > + /* Match of device and driver failed */ > + RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match" > + " the device (%s)\n", drv->driver.name, > + device_name); > + continue; > + } > + > + RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", > + dev->id.vendor_id, dev->id.device_id, > + drv->driver.name); > + > + if (drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING) { > + /* map resources for devices that use > + * igb_uio > + */ > + ret = rte_eal_pci_map_device(dev); > + if (ret != 0) > + goto err_return; > + } > + > + /* reference driver structure */ > + dev->driver = drv; > + > + /* call the driver probe() function */ > + ret = drv->probe(drv, dev); > + if (ret) { > + dev->driver = NULL; > + if (drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING) > + rte_eal_pci_unmap_device(dev); > + } > + return ret; > + } > + } > + > + return 1; > +err_return: > + RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT > + " cannot be used\n", dev->addr.domain, dev->addr.bus, > + dev->addr.devid, dev->addr.function); > + return -1; > +} > + > +/* > * Detach device specified by its pci address. > */ > int > -rte_eal_pci_detach(const struct rte_pci_addr *addr) > +rte_eal_pci_detach(const char *device_name) > { > struct rte_pci_device *dev = NULL; > - int ret = 0; > + struct rte_pci_addr addr; > + int ret = 1; > > - if (addr == NULL) > + if (!device_name) > return -1; > > + memset(&addr, 0, sizeof(addr)); > + if (eal_parse_pci_DomBDF(device_name, &addr)) { > + /* Device doesn't match PCI BDF naming format */ > + return 1; > + } > + > FOREACH_DEVICE_ON_PCIBUS(dev) { > - if (rte_eal_compare_pci_addr(&dev->addr, addr)) > + if (rte_eal_compare_pci_addr(&dev->addr, &addr)) > continue; > > ret = rte_eal_pci_detach_dev(dev); > @@ -385,8 +464,8 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr) > free(dev); > return 0; > } > - return -1; > > + return ret; > err_return: > RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT > " cannot be used\n", dev->addr.domain, dev->addr.bus, > diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h > index 19954f4..9a096ec 100644 > --- a/lib/librte_eal/common/include/rte_bus.h > +++ b/lib/librte_eal/common/include/rte_bus.h > @@ -59,6 +59,8 @@ TAILQ_HEAD(rte_bus_list, rte_bus); > /* Bus list exposed */ > extern struct rte_bus_list rte_bus_list; > > +#define FOREACH_BUS(bus_p) TAILQ_FOREACH(bus_p, &rte_bus_list, next) > + > /** > * Bus specific scan for devices attached on the bus. > * For each bus object, the scan would be reponsible for finding devices and > @@ -85,6 +87,33 @@ typedef int (*rte_bus_scan_t)(void); > typedef int (*rte_bus_probe_t)(void); > > /** > + * Attach a device to a bus, assuming it is 'connected' to the bus. > + * A bus is responsible for scanning for devices. Attaching a new device is > + * for reenabling the device after being detached/removed. > + * > + * @param device_name > + * Name of the device to attach. > + * > + * @return > + * 0 for successful attach > + * !0 for unsuccessful attach (or incorrect device name) > + */ > +typedef int (*rte_bus_attach_t)(const char *device_name); > + > +/** > + * Detach a named device from a bus. Implementation would check the existence > + * of device on the bus and detach it. > + * > + * @param device_name > + * Name of the device to detach > + * > + * @return > + * 0 for successful detaching > + * !0 if device not found or can't detach > + */ > +typedef int (*rte_bus_detach_t)(const char *device_name); > + > +/** > * A structure describing a generic bus. > */ > struct rte_bus { > @@ -92,6 +121,8 @@ struct rte_bus { > const char *name; /**< Name of the bus */ > rte_bus_scan_t scan; /**< Scan for devices attached to bus */ > rte_bus_probe_t probe; /**< Probe devices on bus */ > + rte_bus_attach_t attach; /**< Attach a named device */ > + rte_bus_detach_t detach; /**< Detach a named device */ > }; > > /** > diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h > index bab8df4..215d732 100644 > --- a/lib/librte_eal/common/include/rte_pci.h > +++ b/lib/librte_eal/common/include/rte_pci.h > @@ -418,6 +418,36 @@ int > rte_eal_pci_probe(void); > > /** > + * Search and attach a PCI device to PCI Bus > + * Implements rte_bus->attach > + * > + * @param device_name > + * Name of the device to search and attach > + * > + * @return > + * 0 for successful removal of device > + * >0 if device not found on bus > + * <0 in case of error in removal. > + */ > +int > +rte_eal_pci_attach(const char *device_name); > + > +/** > + * Search and detach a PCI device from PCI Bus > + * Implements rte_bus->detach > + * > + * @param device_name > + * Name of the device to search and detach > + * > + * @return > + * 0 for successful detaching of device > + * >0 if device not found on bus > + * <0 in case of error in removal. > + */ > +int > +rte_eal_pci_detach(const char *device_name); > + > +/** > * Map the PCI device resources in user space virtual memory address > * > * Note that driver should not call this function when flag > @@ -491,21 +521,6 @@ void pci_unmap_resource(void *requested_addr, size_t size); > int rte_eal_pci_probe_one(const struct rte_pci_addr *addr); > > /** > - * Close the single PCI device. > - * > - * Scan the content of the PCI bus, and find the pci device specified by pci > - * address, then call the remove() function for registered driver that has a > - * matching entry in its id_table for discovered device. > - * > - * @param addr > - * The PCI Bus-Device-Function address to close. > - * @return > - * - 0 on success. > - * - Negative on error. > - */ > -int rte_eal_pci_detach(const struct rte_pci_addr *addr); > - > -/** > * Dump the content of the PCI bus. > * > * @param f > diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c > index d6f9855..01f0c9a 100644 > --- a/lib/librte_eal/linuxapp/eal/eal_pci.c > +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c > @@ -719,6 +719,8 @@ struct rte_pci_bus rte_pci_bus = { > .bus = { > .scan = rte_eal_pci_scan, > .probe = rte_eal_pci_probe, > + .attach = rte_eal_pci_attach, > + .detach = rte_eal_pci_detach, > }, > .device_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.device_list), > .driver_list = TAILQ_HEAD_INITIALIZER(rte_pci_bus.driver_list), > -- > 2.7.0 >