From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1bon0061.outbound.protection.outlook.com [157.56.111.61]) by dpdk.org (Postfix) with ESMTP id 2D2C0CB68 for ; Thu, 16 Jun 2016 16:07:15 +0200 (CEST) Received: from CH1PR03CA003.namprd03.prod.outlook.com (10.255.156.148) by BY1PR03MB1452.namprd03.prod.outlook.com (10.162.127.158) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.511.8; Thu, 16 Jun 2016 14:07:13 +0000 Received: from BL2FFO11FD033.protection.gbl (10.255.156.132) by CH1PR03CA003.outlook.office365.com (10.255.156.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.523.12 via Frontend Transport; Thu, 16 Jun 2016 14:07:13 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=nxp.com; 6wind.com; dkim=none (message not signed) header.d=none;6wind.com; dmarc=none action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BL2FFO11FD033.mail.protection.outlook.com (10.173.161.129) with Microsoft SMTP Server (TLS) id 15.1.511.7 via Frontend Transport; Thu, 16 Jun 2016 14:07:13 +0000 Received: from Tophie.ap.freescale.net (Tophie.ap.freescale.net [10.232.14.199]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id u5GE6XoH026530; Thu, 16 Jun 2016 07:07:10 -0700 From: Shreyansh Jain To: CC: , , David Marchand Date: Thu, 16 Jun 2016 19:36:50 +0530 Message-ID: <1466086011-11920-17-git-send-email-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1466086011-11920-1-git-send-email-shreyansh.jain@nxp.com> References: <1454076516-21591-1-git-send-email-david.marchand@6wind.com> <1466086011-11920-1-git-send-email-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131105596334885051; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.158.2; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(1110001)(1109001)(339900001)(189002)(199003)(50466002)(2950100001)(106466001)(81166006)(8936002)(8676002)(356003)(50226002)(5008740100001)(2906002)(77096005)(69596002)(87936001)(5003940100001)(68736007)(97736004)(81156014)(4326007)(229853001)(19580405001)(48376002)(47776003)(50986999)(76176999)(104016004)(5890100001)(86362001)(189998001)(85426001)(105606002)(6806005)(92566002)(586003)(11100500001)(2351001)(110136002)(19580395003)(36756003)(33646002); DIR:OUT; SFP:1101; SCL:1; SRVR:BY1PR03MB1452; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD033; 1:ZUAdvbnrzNDhhAw6aClG2oLeKQcXecMiy4hbGdjDtS4ToU4ZPlu9axlQ0MpPtJNyDFz8UsBmymBlfLQPCjXZ2XdpOjAupytzpv6G//bxZvF5LerIeiJrBYY3vLPdZW8xrvwoyIgD5aQZfQQ7uDfAALvCHxGzcEMLA8vSgyqehcG7oqMitwlp8w95bKokLe4ewfLAqui3jmSr4lCCMzufxb8IkLJV/EwvNx8PYiOs1g8dMP38J8jKZdh+8ICzfWlVb4qxdHXrZYA1PAfkYqOlEXKvcnlkXggtVCOd5n5oifA0HJbgbasGfWs0gG/tLb6DY6QfsC080TC8CRrIvtiU9BBc1pndMySKVja6v9YJ0uRvNvD8DeClt8Ch7nv2EagORD2f83a7QkOU/YNpzWLdIj9j44c1vfctf2f66EnbDFEaljVjPvQ/bT2A+aWlNNfOPlb+Zsmi0T5z0hS/Jh5WjG3Th8+bdRdtgg8upmxu6Go2WoaSieM3SLhzR2r4k0bWYq4RqyveyzLT2TL/C9NDH/ziQDpAgxIdx3SaB2Z4fF+15HBJjLXe0lG/MGzNw+vikI4hWcj/dxpvfjo9lUrTYA== MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: e304e7a3-478c-4455-e75a-08d395ef840f X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1452; 2:5M0Rtzx8c6EQvRGb2cXotwpevhfs1LRZE8KPlOstoMb5d+b8Hmu7ucoOLN9cDFH29AGoPof99t78uEgnHpRKsvjWMF+CGizr2+6GEPIKy/3cN96nEv5h4vZQhUkGnAar1KU8XPQDbL5o7uBH5tGZec3VZAZ8wdvKun74gLrXFoZp0EtULczgDjekdaOWzhb4; 3:+uwDwEz1s364ni2LzZ5wvK0fTC+YaLQIXqHzfsaJeEDSgF6X7VsbXKwJpytllxxWPLJoq8dyvGx7VcITFMiNUm3Frn6LcWR1yxLfdeCXPxV/eLUFoaJGYd24gWdPMivkHshiyFyHPauRcyuceN9ebpWlEdZCQZVqeiUqPsO3MFMZoKupsmoYOR56C+uszvShlFM0Rh6KiLf2Ds1jcUf0CCJqXulz7RAeMct44UI/d6w=; 25:I16p4mrQDGlCgPgxYB69Q/JOrFYyOcA6mHt9eR80ktmIozjEV9aZLF4Tg9xYfJKFSUJcd1wXQO2f58E7FbeXtBPxG9QmHUgrMQL8UQSRgex4Q7ZFGoiN13P0U4OhgRZOdDdj/04FihbHgMkefFblrmBVpkH/NFQf641zELDAU2NTgup2y4TKSgAtFkLrUwNjcgx5CWLMmyCWx0uAbfE99plGQtcJc4FovKl/KNBcVtoePJfuTugQGZ3uVZbdLXAjy5RIIfzdKfS4AeZSNidNYFGw0SUA0El1pVwt4KVY3NJbUM4kL2fp9pW+pbtPf1p2d2PoZVbRbpJK361Ge4BkMbw94pcepaINoQyrKGbn/vz3cf/f4mKWy0gNl1uDgRefly5/3BGMNahXpY1o/EssSpq9JZx/LHbOi9C4s7eRj/A= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR03MB1452; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(13023025)(13015025)(13024025)(13017025)(13018025)(3002001)(10201501046)(6055026); SRVR:BY1PR03MB1452; BCL:0; PCL:0; RULEID:(400006); SRVR:BY1PR03MB1452; X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1452; 4:F2J3nko/R2885CZ8Qjr6AAqJUHMp7oiYm2LzSEbXxoGZ+o3jvFLP2yp/XUqRddW+jGtf1/c2LpCfwCFzkIpxxo0nHQ4C5hagwmcvO4pXOlFNAtP3gFi67nLjpaX9qjom1ewkOdGwwP95y5KHDiTnmuQ/gYM2xXV6FwIcfmNJnRW3hugXJGLWlDhe4ptKkbQ9UwQhCGcjL1FuorWUOlGyyyQSY+sqqb8EveTV0Ohhl5yPG1zi9avBcYmv0oL0NS83j/Tb3oJ8wOnAK3xpChH8SyRrIlEt/gtpwBxffOD1CGVR5ErQT5d4U1MybYyE30zpiGlOYGkCFl/5DKnsK8buj1FBaL9WpVmkyeUa5qiZmO6HdME7utWh6u7a32NvzeA9fj6S7wwTeY+PEEJvxG7p68HVHIjlUidjrn7X+vZ5I2NbveMdbZ9cy+yxMdhT4zWgYl/TZpMeXioNzcQ37TzeNwURvSMRkipWoJvgrgXGal/6bkquCbBXfuRi2d0bOk1mxEeeBVf6H9ESLALPp2UrKw== X-Forefront-PRVS: 09752BC779 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY1PR03MB1452; 23:Ze1nnlyY8tR4Df+3YxRz64MNjoYS7uEY0rnnqBIcc?= =?us-ascii?Q?dzBoe2RvCVhuPlmGKeXACs+Z3DBqessDJ+2hbIxZruC/9W72gvoiqlp1HdwE?= =?us-ascii?Q?+EX67ABRJDg5trtOTiUvBpKaEE17APRoqcYMycApfXA926hnjz2E+ptRq847?= =?us-ascii?Q?KGTobtzVWxCqdztD3aJsbM7Rg7SmIJopaNg1jxs/OGsOsqNHBYqsTtS0A+qc?= =?us-ascii?Q?IH1t+3kMSuZxAGQqQX/1b/HsNiNtotHxFaRNl4x2diFQbMLLRgB6mpXxRpEP?= =?us-ascii?Q?FokeeSTJu5xVjMm9+z8z93xYNlB9K+omhiwzveEXOAub9NU58cCmmJkrI5Sb?= =?us-ascii?Q?IERqqOtdV4R6Hf1FD0Fghz9RlszcJO9hJHMSkE4ecA1VDw/NFKABHLh2djB8?= =?us-ascii?Q?mHeNC94CCvCIdE2lbORJ6HIUhkR2dJzpFrW/FaSNrs129N2I4jcjAnDg3fJY?= =?us-ascii?Q?Znrks5hPTEIL5n+cExE+AeM+nRVKL1d8cO+tpVilcczSm+KH2upVaw/IryDw?= =?us-ascii?Q?3DJL/2FMiNZagZ4qfqNQO3fQt7cHIYp6cUF/IJXb4u66s7qHHeD4gOh8mSCP?= =?us-ascii?Q?Tu+KR77UDmQ9dAilDPvPm+8moOqWGQrIBDOuP/0hENjn2KrDYmf22qQqkqV0?= =?us-ascii?Q?lyqODho7QfCzMo38rCBBiqD5Mqe2BHvXF113B61bBfWsjgoAlrq6or9Ge8z3?= =?us-ascii?Q?0ufi8syRYLrPJMIqFwx5ud02aO8ULXY+ePcXo6vm+1QXu3b58PvuFv+UBlHY?= =?us-ascii?Q?0xM98eONMUPL64QDgV718GM+HQXe1AWDu1XTzgpV90LjOjlprJaWqVqvrGKc?= =?us-ascii?Q?jIxPtF0+EMUJtK9U58TWgcJNC3NiQrgeFwLtxbzh/Rn0Xd+rgGtVv/bzawN1?= =?us-ascii?Q?qJcK8ltIrGS1KcFFxDdbtMYy8Ex6/ZOQJnyksRcwsBj7DLKQQla8uDwBa5XF?= =?us-ascii?Q?O8qulg4NhPLdWC8YMACf2ZJj2fliL4rrhyPDAWsoXKDkJbF0I56ljIqkTxwn?= =?us-ascii?Q?eLrSMe6SjlzseF43UhVKmyTSjXgxQMcL91nT7yfomrWmHWo02cZ1IKEFfmXQ?= =?us-ascii?Q?RY/SeHAD5FBtS8dNeuJTYXfQ47YeUag1o4AesO6sIaHNvbBnWM7Q7P5LTe9J?= =?us-ascii?Q?izSMwhhCJCHmhMY1gxJ1EhBiX+3nMuXoEv/WxdpOX7GYbpts4fGF105ITgVw?= =?us-ascii?Q?w4+a4dpwI8G6tE=3D?= X-Microsoft-Exchange-Diagnostics: 1; BY1PR03MB1452; 5:tjiVYwWxDpKxgWSaYtT8VmkGPjXTkVZt/yoNpmMpudeYQxjgQ7/PqzJUkNNta/qAUKKjjcBm+wB8568FN3MM0t0gNuJ4NuK8E756dZB/xDfnAp64vWBp/j8SU5CQCWsPF77OcXTQ3cRaf0ERMMldSF2AMDCP/RcRBn3xWe/RpeQ=; 24:DdEvqnAxtTtF6ecNmUhv1uTzv9h5TRLeEX5TdBRQt/9/JfruvE9OBPDYFsi/ZNmUt/XuDI2iJqxdPGWY1YjC/rEc4B8HhNDeEhXc9DWgISo=; 7:pclzClR5ZEPFnIWeXbOasgxrYd6EgIMG0LwGCJOhwYvwhUpdVaDClUafYkhATBdCJW6FPxx81vXxR+5I4lricA5GqhzxvOCdMHfJ7r4m8re+jHf+FoIMTqdoh1fnXkFGqrSXjferHsB9wt1Ub9zBB+T6hB2EcWVWoevbYoDSv6g85KlsO4mRqfozZA5/idMtkzHIvFJgqKA1unGUQD7PTg== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jun 2016 14:07:13.2701 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR03MB1452 Subject: [dpdk-dev] [PATCH v3 16/17] ethdev: convert to eal hotplug X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jun 2016 14:07:16 -0000 From: David Marchand Remove bus logic from ethdev hotplug by using eal for this. Current api is preserved: - the last port that has been created is tracked to return it to the application when attaching, - the internal device name is reused when detaching. We can not get rid of ethdev hotplug yet since we still need some mechanism to inform applications of port creation/removal to substitute for ethdev hotplug api. dev_type field in struct rte_eth_dev and rte_eth_dev_allocate are kept as is, but this information is not needed anymore and is removed in the following commit. Signed-off-by: David Marchand --- lib/librte_ether/rte_ethdev.c | 251 ++++++------------------------------------ 1 file changed, 33 insertions(+), 218 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index a496521..12d24ff 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -72,6 +72,7 @@ static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data"; struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS]; static struct rte_eth_dev_data *rte_eth_dev_data; +static uint8_t eth_dev_last_created_port; static uint8_t nb_ports; /* spinlock for eth device callbacks */ @@ -210,6 +211,7 @@ rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type) eth_dev->data->port_id = port_id; eth_dev->attached = DEV_ATTACHED; eth_dev->dev_type = type; + eth_dev_last_created_port = port_id; nb_ports++; return eth_dev; } @@ -341,99 +343,6 @@ rte_eth_dev_count(void) return nb_ports; } -static enum rte_eth_dev_type -rte_eth_dev_get_device_type(uint8_t port_id) -{ - RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, RTE_ETH_DEV_UNKNOWN); - return rte_eth_devices[port_id].dev_type; -} - -static int -rte_eth_dev_get_addr_by_port(uint8_t port_id, struct rte_pci_addr *addr) -{ - RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); - - if (addr == NULL) { - RTE_PMD_DEBUG_TRACE("Null pointer is specified\n"); - return -EINVAL; - } - - *addr = rte_eth_devices[port_id].pci_dev->addr; - return 0; -} - -static int -rte_eth_dev_get_name_by_port(uint8_t port_id, char *name) -{ - char *tmp; - - RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); - - if (name == NULL) { - RTE_PMD_DEBUG_TRACE("Null pointer is specified\n"); - return -EINVAL; - } - - /* shouldn't check 'rte_eth_devices[i].data', - * because it might be overwritten by VDEV PMD */ - tmp = rte_eth_dev_data[port_id].name; - strcpy(name, tmp); - return 0; -} - -static int -rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id) -{ - int i; - - if (name == NULL) { - RTE_PMD_DEBUG_TRACE("Null pointer is specified\n"); - return -EINVAL; - } - - *port_id = RTE_MAX_ETHPORTS; - - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - - if (!strncmp(name, - rte_eth_dev_data[i].name, strlen(name))) { - - *port_id = i; - - return 0; - } - } - return -ENODEV; -} - -static int -rte_eth_dev_get_port_by_addr(const struct rte_pci_addr *addr, uint8_t *port_id) -{ - int i; - struct rte_pci_device *pci_dev = NULL; - - if (addr == NULL) { - RTE_PMD_DEBUG_TRACE("Null pointer is specified\n"); - return -EINVAL; - } - - *port_id = RTE_MAX_ETHPORTS; - - for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - - pci_dev = rte_eth_devices[i].pci_dev; - - if (pci_dev && - !rte_eal_compare_pci_addr(&pci_dev->addr, addr)) { - - *port_id = i; - - return 0; - } - } - return -ENODEV; -} - static int rte_eth_dev_is_detachable(uint8_t port_id) { @@ -459,124 +368,45 @@ rte_eth_dev_is_detachable(uint8_t port_id) return 1; } -/* attach the new physical device, then store port_id of the device */ -static int -rte_eth_dev_attach_pdev(struct rte_pci_addr *addr, uint8_t *port_id) -{ - /* Invoke probe func of the driver can handle the new device. */ - if (rte_eal_pci_probe_one(addr)) - goto err; - - if (rte_eth_dev_get_port_by_addr(addr, port_id)) - goto err; - - return 0; -err: - return -1; -} - -/* detach the new physical device, then store pci_addr of the device */ -static int -rte_eth_dev_detach_pdev(uint8_t port_id, struct rte_pci_addr *addr) -{ - struct rte_pci_addr freed_addr; - struct rte_pci_addr vp; - - /* get pci address by port id */ - if (rte_eth_dev_get_addr_by_port(port_id, &freed_addr)) - goto err; - - /* Zeroed pci addr means the port comes from virtual device */ - vp.domain = vp.bus = vp.devid = vp.function = 0; - if (rte_eal_compare_pci_addr(&vp, &freed_addr) == 0) - goto err; - - /* invoke devuninit func of the pci driver, - * also remove the device from pci_device_list */ - if (rte_eal_pci_detach(&freed_addr)) - goto err; - - *addr = freed_addr; - return 0; -err: - return -1; -} - -/* attach the new virtual device, then store port_id of the device */ -static int -rte_eth_dev_attach_vdev(const char *vdevargs, uint8_t *port_id) -{ - char *name = NULL, *args = NULL; - int ret = -1; - - /* parse vdevargs, then retrieve device name and args */ - if (rte_eal_parse_devargs_str(vdevargs, &name, &args)) - goto end; - - /* walk around dev_driver_list to find the driver of the device, - * then invoke probe function of the driver. - * rte_eal_vdev_init() updates port_id allocated after - * initialization. - */ - if (rte_eal_vdev_init(name, args)) - goto end; - - if (rte_eth_dev_get_port_by_name(name, port_id)) - goto end; - - ret = 0; -end: - free(name); - free(args); - - return ret; -} - -/* detach the new virtual device, then store the name of the device */ -static int -rte_eth_dev_detach_vdev(uint8_t port_id, char *vdevname) -{ - char name[RTE_ETH_NAME_MAX_LEN]; - - /* get device name by port id */ - if (rte_eth_dev_get_name_by_port(port_id, name)) - goto err; - /* walk around dev_driver_list to find the driver of the device, - * then invoke uninit function of the driver */ - if (rte_eal_vdev_uninit(name)) - goto err; - - strncpy(vdevname, name, sizeof(name)); - return 0; -err: - return -1; -} - /* attach the new device, then store port_id of the device */ int rte_eth_dev_attach(const char *devargs, uint8_t *port_id) { - struct rte_pci_addr addr; int ret = -1; + int current = eth_dev_last_created_port; + char *name = NULL; + char *args = NULL; if ((devargs == NULL) || (port_id == NULL)) { ret = -EINVAL; goto err; } - if (eal_parse_pci_DomBDF(devargs, &addr) == 0) { - ret = rte_eth_dev_attach_pdev(&addr, port_id); - if (ret < 0) - goto err; - } else { - ret = rte_eth_dev_attach_vdev(devargs, port_id); - if (ret < 0) - goto err; + /* parse devargs, then retrieve device name and args */ + if (rte_eal_parse_devargs_str(devargs, &name, &args)) + goto err; + + ret = rte_eal_dev_attach(name, args); + if (ret < 0) + goto err; + + /* no point looking at eth_dev_last_created_port if no port exists */ + if (!nb_ports) { + ret = -1; + goto err; } + /* if nothing happened, there is a bug here, since some driver told us + * it did attach a device, but did not create a port */ + if (current == eth_dev_last_created_port) { + ret = -1; + goto err; + } + *port_id = eth_dev_last_created_port; + ret = 0; - return 0; err: - RTE_LOG(ERR, EAL, "Driver, cannot attach the device\n"); + free(name); + free(args); return ret; } @@ -584,7 +414,6 @@ err: int rte_eth_dev_detach(uint8_t port_id, char *name) { - struct rte_pci_addr addr; int ret = -1; if (name == NULL) { @@ -592,33 +421,19 @@ rte_eth_dev_detach(uint8_t port_id, char *name) goto err; } - /* check whether the driver supports detach feature, or not */ + /* FIXME: move this to eal, once device flags are relocated there */ if (rte_eth_dev_is_detachable(port_id)) goto err; - if (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PCI) { - ret = rte_eth_dev_get_addr_by_port(port_id, &addr); - if (ret < 0) - goto err; - - ret = rte_eth_dev_detach_pdev(port_id, &addr); - if (ret < 0) - goto err; - - snprintf(name, RTE_ETH_NAME_MAX_LEN, - "%04x:%02x:%02x.%d", - addr.domain, addr.bus, - addr.devid, addr.function); - } else { - ret = rte_eth_dev_detach_vdev(port_id, name); - if (ret < 0) - goto err; - } + snprintf(name, sizeof(rte_eth_devices[port_id].data->name), + "%s", rte_eth_devices[port_id].data->name); + ret = rte_eal_dev_detach(name); + if (ret < 0) + goto err; return 0; err: - RTE_LOG(ERR, EAL, "Driver, cannot detach the device\n"); return ret; } -- 2.7.4