From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <shreyansh.jain@nxp.com>
Received: from NAM03-DM3-obe.outbound.protection.outlook.com
 (mail-dm3nam03on0042.outbound.protection.outlook.com [104.47.41.42])
 by dpdk.org (Postfix) with ESMTP id 90FED6CD0
 for <dev@dpdk.org>; Fri, 16 Sep 2016 06:32:52 +0200 (CEST)
Received: from BN3PR0301CA0024.namprd03.prod.outlook.com (10.160.180.162) by
 MWHPR03MB2448.namprd03.prod.outlook.com (10.169.200.142) with Microsoft SMTP
 Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id
 15.1.619.10; Fri, 16 Sep 2016 04:32:51 +0000
Received: from BY2FFO11FD050.protection.gbl (2a01:111:f400:7c0c::107) by
 BN3PR0301CA0024.outlook.office365.com (2a01:111:e400:4000::34) with Microsoft
 SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384)
 id 15.1.619.10 via Frontend Transport; Fri, 16 Sep 2016 04:32:52 +0000
Authentication-Results: spf=fail (sender IP is 192.88.168.50)
 smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed)
 header.d=none;nxp.com; dmarc=fail action=none header.from=nxp.com;nxp.com;
 dkim=none (message not signed) header.d=none;
Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not
 designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; 
 client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net;
Received: from tx30smr01.am.freescale.net (192.88.168.50) by
 BY2FFO11FD050.mail.protection.outlook.com (10.1.15.187) with Microsoft SMTP
 Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.619.6
 via Frontend Transport; Fri, 16 Sep 2016 04:32:50 +0000
Received: from Tophie.ap.freescale.net ([10.232.14.87])
 by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u8G4Trfw029256;
 Thu, 15 Sep 2016 21:32:47 -0700
From: Shreyansh Jain <shreyansh.jain@nxp.com>
To: <dev@dpdk.org>
CC: <viktorin@rehivetech.com>, David Marchand <david.marchand@6wind.com>,
 <hemant.agrawal@nxp.com>, Thomas Monjalon <thomas.monjalon@6wind.com>,
 Shreyansh Jain <shreyansh.jain@nxp.com>
Date: Fri, 16 Sep 2016 09:59:51 +0530
Message-ID: <1474000200-16705-17-git-send-email-shreyansh.jain@nxp.com>
X-Mailer: git-send-email 2.7.4
In-Reply-To: <1474000200-16705-1-git-send-email-shreyansh.jain@nxp.com>
References: <1466510566-9240-1-git-send-email-shreyansh.jain@nxp.com>
 <1474000200-16705-1-git-send-email-shreyansh.jain@nxp.com>
X-EOPAttributedMessage: 0
X-Matching-Connectors: 131184739711533280;
 (91ab9b29-cfa4-454e-5278-08d120cd25b8); ()
X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI;
 SFV:NSPM;
 SFS:(10009020)(6009001)(7916002)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(305945005)(50466002)(68736007)(47776003)(104016004)(50226002)(8936002)(2906002)(36756003)(5660300001)(77096005)(86362001)(586003)(5890100001)(81156014)(50986999)(8676002)(8666005)(76176999)(7846002)(85426001)(110136003)(87936001)(189998001)(48376002)(97736004)(5003940100001)(81166006)(626004)(19580395003)(19580405001)(33646002)(105606002)(2351001)(106466001)(92566002)(356003)(229853001)(2950100001)(4326007)(575784001)(7059030);
 DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR03MB2448; H:tx30smr01.am.freescale.net;
 FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; 
X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD050;
 1:g9KWZoGIr618m1wyKPCiQ75vsKRtghJHsIwhVs5qKIKzV4oQx6irsEFRlO5R2WCQTFvOxHkNMnnNeKX9aAvVkZMBEarUzX/7ueP1joqStXctyVqEkxkx7ZjO/9kRza4AyvFx8FQG+WaZzRFshc5AYG7nLDa8xrrY24NYcyEb8DbmAZCCdVa8NN8GGKishJ1adc0qSrQT8F8JipzmwQKgPmH+YYDpDa14+GX8J5Evo0y1qYzt9wUaDlemVcGn3DUtDLAmTaaiFMxKeiPKwGSkUFbVIkYoeZeTUP8/PCLj81bGH2mLMqtksjYkbOpfoC6GPQNZIggkOkTQqDjbycuDOh5fC19BrdD6kyak33ve7QCtX4DNisWj7CHuLiQ2N4L0NKX/KAEVOyqrMqM+XwFY5LHn+IQcEvEL1kB4cokCqCQLg8rpOCSaYASKouUjir9K6Ee/tyrJNFEgzAYZ4M3E9aCDcNdV2EJGDzQv8+cYD7MN8lv3i3mU7NZT23KCIiYHPrkcxgZgFRE7pLz+2pAR1KaGHv8bDvlkmibKAqsEk2cg+fLr3nA2sfY1GasgFVJvIQSG3T7h81wlwi6ircBuphcVy/VcB6jP7zx9+iVwQUssgsdPY1aS16U1sLRq3eh5RkQvLodF5w8eH8mhOwqa2WxZRRPOqKiI7c+Sr8NF+hgPxQHegCThRQ2nuHwOHsouueLK94U5CRituDbsEgsiyudB31oRrFfvI4+QFfeD9mQ=
MIME-Version: 1.0
Content-Type: text/plain
X-MS-Office365-Filtering-Correlation-Id: c270885a-0523-4b10-35e8-08d3ddea84d9
X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2448;
 2:yto5QcBoTuFo/q4Pal4zU2EuAo0eJKnZzGKYxdC6Lw8yGR8GIhHTlwXCiogPNtKk5iVOkYcnv+tpx771JX7L3Hn9RqPBQPs3t0DFQaFyZ8g0gEyfUPVgyPMO5+jeuLi39vIUyn5nIvNLQdbj7nzo/QirV3uVHKxFIB24G57JO6Ln1jJXTS8bUUprZlmmopbr;
 3:1g7pBvFNoWuyDCNf2hTe3rvGpeLZ4KbGfk1wK2VbibSPtmgQCn6ZX0r5iyd0OCrDGpHAt1hz3x37AMgBRg04HbF7t8rAdFSIN+gKkR8cVTC0jG45iUmdKjH1NzMhxwhlVfCx7NesX1UGpYfLlHP9Aq0gHxjx48KQdWnV79t4r+cDZ0Ws9tHNalF4S2oUp6EbHFqKMl2DbwGlXpt18ffCyhIElAfMCKyDTyLLSJaVgoQ=;
 25:sPWit0CYCT45CW2F85sFKo0L95z9oqrmlYA7ErGIZLFaaX+OdHVP75UEtelEOzCbDAo9Sp9gN5pUzwn9fii7uTwr8rg4aACmG4KWG7UjQbo5Z9N/aMECpWWjDVo9YJSrMiW4yaKYSzXHTvbKwVPvrpagpZUBBX2bHexuHuY6T8SlkBhuhRoTTQ8KeoPeyRxqH65BrPzi6scH3NMj8kEmcv3q3DrSRe1/Lk8CR5gS/5GHWMjxoffYUpOcH1SQGi8M6dwVihYipQ+ms11wuOFmQtypzkJpsFxRR2idLknblfKI8lyt6tMWtfuLvARIJu7Xg+I9mbbEdIFf+AeIqxFCnnBTTsvax5sIv3u3aiv/89+fFTggGhCPA4NoRfxT1R2bkvXleSVKTzA8DWtlkiwb54kP46zwadK+DucKDyKG2ok=
X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:MWHPR03MB2448;
X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2448;
 31:td6pKVznBmggvzw0K8nIigLfwshuAMoUL4eYXKVnwiHTdkIDOC6zwSn6Uj7fMrtcEu6ENzHWUo7nNESooZ3oirUYtVPd9h/Wyo2pg/npu/G3SN1+UErT9axQl9CO04ztlMHQ5htDxeMOoDbm/vzSpRaasyYpiSGWaQrexnUwNHqyPxbqyoX+UpAsuD+pwWfBe95yShRv6t/2++8+xLwMAUVB5t4cs/UxnnXEtsPjCv8=;
 4:T9qllA4sOeQd8sD6qQBv7vG62OvuMrKjXTPMhF7LPsQ4Cm3HL+EpDSRPVIdOR2AkjJIBEdStf8hHJ12I9IW6aQ1kDmeHZG5AJMShK4DTezEszWNGJr05MmtgdyWv/KZlvURCB3pXFFvYvCJ11wS5lMXu/YSqd+383R82piXoI/ah1uMHg8wGqBRrBAiPNRSIkuam2OqVqnaSziIPSVTJF6TUoa7UJIknflAtdUQngKvbc5PJ9dSr8uIPGZxXAvN9jVhExq8dC+TXfiVeBMfl3xgJQc4i9mEwnKRgWOSOM6sBzV0EiLzoMopy1M/3hksDOcKMtaeicDG08LbW3Fw1PD/B5mnle5GLKL3BjLGpyvF7YwcQ5BUxTlfLGHDDc9nIPacpLqQvzt4FVMVFJSjrT49iLBeYzl4TI/HE/WkD9aj6ENXUwrgakeZlZ1Sk2RKso9fvdjk/yIIuwSndmkgu05WPSviu60mv2ZdpsLBF2ymjoZQlnEHhbe2qy6LswmoLkkm6ZQ2iFxe/q9pnSbXoPEAzfu9PbOhK8KsMkZR8ybkuRl1+rnwvjauWUzAwdBsmHkk9fBycQLBlYKVJak8fcw==
X-Microsoft-Antispam-PRVS: <MWHPR03MB2448695BD06423A94B99C9F590F30@MWHPR03MB2448.namprd03.prod.outlook.com>
X-Exchange-Antispam-Report-Test: UriScan:(185117386973197)(17755550239193);
X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0;
 RULEID:(6040176)(601004)(2401047)(13015025)(8121501046)(5005006)(13017025)(13018025)(13023025)(13024025)(10201501046)(3002001)(6055026);
 SRVR:MWHPR03MB2448; BCL:0; PCL:0; RULEID:(400006); SRVR:MWHPR03MB2448; 
X-Forefront-PRVS: 0067A8BA2A
X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR03MB2448;
 23:6GG0IR05JVLXknE9UzQXLdhlTiovYXlDWVRrCyvm9?=
 =?us-ascii?Q?HQWviV5O449XpsPZ+csvxWiroUKzdcE7/LoN83j1nhF9LXY/kvyS/COcRzQX?=
 =?us-ascii?Q?MS8SbsHFG3wiVb2XCKcc5JudjKps0hcyVTmT6AkT38hsKPG2y5mqg61tXhUO?=
 =?us-ascii?Q?GrwmlrB2cy/3R3kc20qOAWz+rWybwjD2sXRUr0Ivsw+7zukKZGjJbIbyeN+C?=
 =?us-ascii?Q?rhdtWEEkhuhO7xK4QdnP/XTO3fgRlninYXXx2979I0nKYSaUsORjK0szMrIs?=
 =?us-ascii?Q?lxleQNbJ4mA10RgrzJmA2+FCTKrGrOA3TqqgKIwu+LY6EGGA205BmAe8Eicp?=
 =?us-ascii?Q?9TzjILq8dgVYXeOPNzfB07AOINHF4EXwBdgdXsVpmjAULB2P+C0t8yXje5/U?=
 =?us-ascii?Q?mzCelUjw7o30ppNBgwVxnPZc8t+S/5qJX5U9mkOwwhpbmJstK8UJGNvBTCBw?=
 =?us-ascii?Q?mSdrDwVhsZeRnwGNl3529dXq+whtL/rdMYtw4jm+vu0utkODYYQBeXm1cN5X?=
 =?us-ascii?Q?Ff0Gi5pUXyuPdYCjQDxn/Ce7dhOeMX1ua+ZbS4GC1YqPUE0sf+2yXsmgcCkq?=
 =?us-ascii?Q?WkYnm50tckXywsU7Y5DkU5b9WBFONCKjsBwWLR5UTDpYuvQJYx7g4ZMtE1ko?=
 =?us-ascii?Q?ixxw3xtbJQc3B7+W01wvNFDFqnPo+JOG7XYrYKMl8kF4btC0/q0zTnkDFwoJ?=
 =?us-ascii?Q?pgLoMkyHNPr5OjPjI0XVQxU5GcVUETH65aUbW2fld9F6s2+GPK4G5HEcb5Ir?=
 =?us-ascii?Q?7GcAicgx9ke0BHI16rWe3+Ox5R+3hccxSvsLrR52kzGUbC29YJ1ajZU9OCrR?=
 =?us-ascii?Q?tFsgzdueV2HZvWFSU+slNUKHDrXhgYVQKC4/xLpTHyOioaLekVseB3dcIjLi?=
 =?us-ascii?Q?AWABrG/LBh0642t+XmYmIb+aPTs+znEx1KuZKtuG+YJvzjBKgimE7joTPa0p?=
 =?us-ascii?Q?9OIOV6C8JrsHeH2QZW5RDkSNfrHNfXzM5lfZTLw6I4E129sVpt5LelDCXJHs?=
 =?us-ascii?Q?KDjYjSKIOjoGRNGjH1p4kwvuJMZdQX/bbqPzhLDY3RpIlOjSpQLHo7DPRWzp?=
 =?us-ascii?Q?RWmxH3gwL48flOska312qXN3f0aiTZCrRgQRakzlobQ83Df7wwGNfRngU/WD?=
 =?us-ascii?Q?DELuuuI80rwvyGLsYLzk8tKes9TdJxQoz33qhnIotj7Kd5J5FLayF/cqKi2F?=
 =?us-ascii?Q?ZWlPZuqWd4M9g4JCD/AcTJRGvHoSZFFKv8u?=
X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2448;
 6:jD0/XcbPezkFaN88+1d7ywzlSNZfuxADXqIXkpAPVLROOb9ufDYpPUuvZyrzQth3QHZ6PDAES/5DM+9SdGRK5p/TCAfD07EKB/I+nmaC+N6rPDPfucu3VXW30F6Isyt9iFhn3e5+ZyayV6O0Lr8cPdqniLQNiQaAP9qMHLyEEqgrfczzM2MNbryIiV7B7vPjyHPqr9RT6PdboCY4R1B/qeKauymbi8l6BeOedwP0c+/PE37Jr6xx1h872ditlFpSMlL7FUo7SmvEQCi28RlUL3GRrhs7iEmVrh7RHMQeRg0=;
 5:edRcyNE6dZeE7KCheUebR+GruqC94AexiINYtAVDP4Phek+QhTYdwXE1teuwocHRNR5mNAEGiApcHzBZSabMarICwRkLqBZejQUkZLNy841tYqhKJQH1IagzZOdpT275Xc2MwwCxSF3f0RiPsrtU/vJ7g+nlzklAN1QHIpIy0N4=;
 24:GnavaCEqBQ3wmqj8vNSmAZ18A+yD2AE/sn9//OVhgyrK5U7fcAvmuJAW+NKIkul3Zr82BkdhFHS3KP3QRpC6qR1iZpoddu3yr1ObW5rAgnA=;
 7:hM2zzjc+7TqPK/Zzm93O2CWxNt+MjOg16pcFRnVL0q9UqvvBuge0ldo5wWuUYaOXucaHOKAxKz1FRJZgMTghGszdYR4MYmyYeC+lm8/mGLkw+FALJxBISqCrT1dN5R6RvcxeHIKdN0SJzZI87me5BRZ7/QtcsV21KTcypiUZwAN1V/KZak6kYub8eUgTDUDGacMwmlNlfffbZl7ASGvWLTN4/2p272fLf2dNkRx7liR7jHOH7h78mxP2Y59fipF4
SpamDiagnosticOutput: 1:99
SpamDiagnosticMetadata: NSPM
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Sep 2016 04:32:50.8257 (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.168.50];
 Helo=[tx30smr01.am.freescale.net]
X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem
X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR03MB2448
Subject: [dpdk-dev] [PATCH v10 16/25] eal: extract vdev infra
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Fri, 16 Sep 2016 04:32:53 -0000

From: Jan Viktorin <viktorin@rehivetech.com>

Move all PMD_VDEV-specific code into a separate module and header
file to not polute the generic code anymore. There is now a list
of virtual devices available.

The rte_vdev_driver integrates the original rte_driver inside
(C inheritance). The rte_driver will be however change in the
future to serve as a common base for all other types of drivers.

The existing PMDs (PMD_VDEV) are to be modified later (there is
no change for them at the moment).

Unlike DRIVER_REGISTER_PCI, DRIVER_EXPORT_NAME is not being called on vdev
registration.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

---
Changes since v9:
 - Add DRIVER_EXPORT_NAME() to DRIVER_REGISTER_* macro.
   Patch for change from David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/bsdapp/eal/Makefile              |   1 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   3 +
 lib/librte_eal/common/Makefile                  |   2 +-
 lib/librte_eal/common/eal_common_dev.c          |  54 +-----------
 lib/librte_eal/common/eal_common_vdev.c         | 112 ++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_vdev.h        |  85 ++++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile            |   1 +
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   3 +
 8 files changed, 207 insertions(+), 54 deletions(-)
 create mode 100644 lib/librte_eal/common/eal_common_vdev.c
 create mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 7a0fea5..5a3fc1d 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -69,6 +69,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 7b3d409..ec61017 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -168,4 +168,7 @@ DPDK_16.11 {
 
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_vdrv_register;
+	rte_eal_vdrv_unregister;
+
 } DPDK_16.07;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index bb9810d..dfd64aa 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
 INC += rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_version.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_dev.h
+INC += rte_hexdump.h rte_devargs.h rte_dev.h rte_vdev.h
 INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 88f9d3f..555e0d9 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -64,32 +64,6 @@ rte_eal_driver_unregister(struct rte_driver *driver)
 }
 
 int
-rte_eal_vdev_init(const char *name, const char *args)
-{
-	struct rte_driver *driver;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	TAILQ_FOREACH(driver, &dev_driver_list, next) {
-		if (driver->type != PMD_VDEV)
-			continue;
-
-		/*
-		 * search a driver prefix in virtual device name.
-		 * For example, if the driver is pcap PMD, driver->name
-		 * will be "eth_pcap", but "name" will be "eth_pcapN".
-		 * So use strncmp to compare.
-		 */
-		if (!strncmp(driver->name, name, strlen(driver->name)))
-			return driver->init(name, args);
-	}
-
-	RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-	return -EINVAL;
-}
-
-int
 rte_eal_dev_init(void)
 {
 	struct rte_devargs *devargs;
@@ -98,7 +72,7 @@ rte_eal_dev_init(void)
 	/*
 	 * Note that the dev_driver_list is populated here
 	 * from calls made to rte_eal_driver_register from constructor functions
-	 * embedded into PMD modules via the PMD_REGISTER_DRIVER macro
+	 * embedded into PMD modules via the DRIVER_REGISTER_VDEV macro
 	 */
 
 	/* call the init function for each virtual device */
@@ -125,32 +99,6 @@ rte_eal_dev_init(void)
 	return 0;
 }
 
-int
-rte_eal_vdev_uninit(const char *name)
-{
-	struct rte_driver *driver;
-
-	if (name == NULL)
-		return -EINVAL;
-
-	TAILQ_FOREACH(driver, &dev_driver_list, next) {
-		if (driver->type != PMD_VDEV)
-			continue;
-
-		/*
-		 * search a driver prefix in virtual device name.
-		 * For example, if the driver is pcap PMD, driver->name
-		 * will be "eth_pcap", but "name" will be "eth_pcapN".
-		 * So use strncmp to compare.
-		 */
-		if (!strncmp(driver->name, name, strlen(driver->name)))
-			return driver->uninit(name);
-	}
-
-	RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
-	return -EINVAL;
-}
-
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_pci_addr addr;
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
new file mode 100644
index 0000000..462517f
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -0,0 +1,112 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   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 RehiveTech 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 <string.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_vdev.h>
+#include <rte_common.h>
+
+struct vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
+
+/* register a driver */
+void
+rte_eal_vdrv_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_vdrv_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
+
+int
+rte_eal_vdev_init(const char *name, const char *args)
+{
+	struct rte_vdev_driver *driver;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (driver->driver.type != PMD_VDEV)
+			continue;
+
+		/*
+		 * search a driver prefix in virtual device name.
+		 * For example, if the driver is pcap PMD, driver->name
+		 * will be "eth_pcap", but "name" will be "eth_pcapN".
+		 * So use strncmp to compare.
+		 */
+		if (!strncmp(driver->driver.name, name,
+			    strlen(driver->driver.name)))
+			return driver->driver.init(name, args);
+	}
+
+	RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+	return -EINVAL;
+}
+
+int
+rte_eal_vdev_uninit(const char *name)
+{
+	struct rte_vdev_driver *driver;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	TAILQ_FOREACH(driver, &vdev_driver_list, next) {
+		if (driver->driver.type != PMD_VDEV)
+			continue;
+
+		/*
+		 * search a driver prefix in virtual device name.
+		 * For example, if the driver is pcap PMD, driver->name
+		 * will be "eth_pcap", but "name" will be "eth_pcapN".
+		 * So use strncmp to compare.
+		 */
+		if (!strncmp(driver->driver.name, name,
+			     strlen(driver->driver.name)))
+			return driver->driver.uninit(name);
+	}
+
+	RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+	return -EINVAL;
+}
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
new file mode 100644
index 0000000..9c5cc54
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vdev.h
@@ -0,0 +1,85 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 RehiveTech. All rights reserved.
+ *
+ *   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 RehiveTech 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.
+ */
+
+#ifndef RTE_VDEV_H
+#define RTE_VDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_dev.h>
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(vdev_driver_list, rte_vdev_driver);
+
+/**
+ * A virtual device driver abstraction.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next; /**< Next in list. */
+	struct rte_driver driver;          /**< Inherited general driver. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be registered.
+ */
+void rte_eal_vdrv_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev_driver structure describing the driver
+ *   to be unregistered.
+ */
+void rte_eal_vdrv_unregister(struct rte_vdev_driver *driver);
+
+#define DRIVER_REGISTER_VDEV(nm, vdrv)\
+RTE_INIT(vdrvinitfn_ ##vdrv);\
+static void vdrvinitfn_ ##vdrv(void)\
+{\
+	(vdrv).driver.name = RTE_STR(nm);\
+	rte_eal_vdrv_register(&vdrv);\
+} \
+DRIVER_EXPORT_NAME(nm, __COUNTER__)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 193957f..4e206f0 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memory.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index c0bd391..b8bfd4b 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -172,4 +172,7 @@ DPDK_16.11 {
 
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
+	rte_eal_vdrv_register;
+	rte_eal_vdrv_unregister;
+
 } DPDK_16.07;
-- 
2.7.4