From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <shreyansh.jain@nxp.com>
Received: from NAM03-CO1-obe.outbound.protection.outlook.com
 (mail-co1nam03on0086.outbound.protection.outlook.com [104.47.40.86])
 by dpdk.org (Postfix) with ESMTP id DEC77F983
 for <dev@dpdk.org>; Wed, 18 Jan 2017 11:35:32 +0100 (CET)
Received: from BN6PR03CA0072.namprd03.prod.outlook.com (10.173.137.34) by
 DM5PR03MB2473.namprd03.prod.outlook.com (10.168.233.19) with Microsoft SMTP
 Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id
 15.1.845.12; Wed, 18 Jan 2017 10:35:31 +0000
Received: from BL2FFO11FD021.protection.gbl (2a01:111:f400:7c09::144) by
 BN6PR03CA0072.outlook.office365.com (2603:10b6:404:4c::34) with Microsoft
 SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.860.13 via
 Frontend Transport; Wed, 18 Jan 2017 10:35:31 +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
 BL2FFO11FD021.mail.protection.outlook.com (10.173.161.100) with Microsoft
 SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id
 15.1.803.8 via Frontend Transport; Wed, 18 Jan 2017 10:35:30 +0000
Received: from tophie.ap.freescale.net ([10.232.14.39])
 by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id v0IAYYha003396;
 Wed, 18 Jan 2017 03:35:28 -0700
From: Shreyansh Jain <shreyansh.jain@nxp.com>
To: <david.marchand@6wind.com>
CC: <dev@dpdk.org>, <thomas.monjalon@6wind.com>, Shreyansh Jain
 <shreyansh.jain@nxp.com>
Date: Wed, 18 Jan 2017 16:07:56 +0530
Message-ID: <1484735880-17178-9-git-send-email-shreyansh.jain@nxp.com>
X-Mailer: git-send-email 2.7.4
In-Reply-To: <1484735880-17178-1-git-send-email-shreyansh.jain@nxp.com>
References: <1484660264-6531-1-git-send-email-shreyansh.jain@nxp.com>
 <1484735880-17178-1-git-send-email-shreyansh.jain@nxp.com>
X-EOPAttributedMessage: 0
X-Matching-Connectors: 131292093311409311;
 (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)(336005)(39400400002)(39450400003)(39410400002)(39380400002)(39840400002)(39850400002)(39860400002)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(38730400001)(5003940100001)(50466002)(92566002)(48376002)(76176999)(50986999)(6666003)(53936002)(5660300001)(77096006)(54906002)(110136003)(2950100002)(305945005)(85426001)(6916009)(8656002)(97736004)(68736007)(626004)(8676002)(189998001)(356003)(81156014)(8936002)(86362001)(575784001)(106466001)(47776003)(2351001)(36756003)(105606002)(4326007)(81166006)(33646002)(50226002)(104016004)(2906002);
 DIR:OUT; SFP:1101; SCL:1; SRVR:DM5PR03MB2473; H:tx30smr01.am.freescale.net;
 FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; 
X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD021;
 1:BOnEUx7qF+TvNA15fBUYr0VG/e8EVWnTs1oC844UsCXUVo6khEXMpFXczEOpu/JUUGramMs/i7xbtSk5jaCabx7B6vE1BynYJ42SJAzg4h+SpsPHM0/CD5UnI4IrsG2guxr4fiiKziqljjmQdOK8Bj6Rgq+ulBmCqsc/y/mFT1sHxiizJkB8WKv2yIwxryBn62jjhxeFJUkG2KWqltWFOqmup9B8D26B+m9j5kMUL0v7eV3+TH40FOfzhzVkthqZoeVqvXNsc4qY3b4iFrcTKiVtA09OaNggznD3TNbqtlLhByoaznzAQ96royps6HR+suCDoxonN2ntPH9acafzTTfck9HEnhmOTF4FTRfdRIDvmBqCF3I89FxqRR/G2taa7NWR8moskowS+/WVXHHRTgC/S594T3FioMHfKyswzrL3HD8tNABla27otgbQ/qBw5t01W9+irVC1lClM9H23aG0n2OhyG6FXKqY1jkcrOV8RzrOR80tUcRFGzBv4AXmHOA6okBiASKCEi69qXJA7INeGQR9mNYT9P7uD97KsR3bHXxnD4yWXt9kLlaWdTodZA8a/sqVJnKJ3u5N7aUh5eGKq50TnhYZw27ccRLux5BH6XoxaotlL/2LRZP6bAzHLvi+WlM9vFDsju5iyCMbMVtLUfy3qN+1n/K012Qjc5lv77gLeUtZ/+EE0jQsxBDExRks/fAany5QqfkMxnkiUVQ==
MIME-Version: 1.0
Content-Type: text/plain
X-MS-Office365-Filtering-Correlation-Id: 790ed226-6f26-4495-7b56-08d43f8dba19
X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:DM5PR03MB2473;
X-Microsoft-Exchange-Diagnostics: 1; DM5PR03MB2473;
 3:+3FN5Hx9npI44XkR3P1VmOvvCa6ix5/qnMq9YiIlLzkhPFKABOzth5edFQ1tPERW6PrQKKvo7uglGUOu0AjoKN733bDk4ej5QEGGrYsJIApKACygNZJUlqaBHYAkGD3kwbsmzrPPQIJY78VHq0Ly6dLCeLlA5ENYsSOVdrX+QtZmwzUXMuq+Ze+q3oWotCAwCZTP1h8FiSt7eskcG5rWFz1mGm+v8RY+PLme44tpIeljtbigq9TYuCxe0HOurvUXYMNYNOkB4sUGksAPR5Ess2GHR4Yae5F6a7bP4pTg1knxQQNyX25qkh91/rQoWQfrQKLYAOIbTykdpaaS5U1P6FIjd6Rz7NLuQrUME2vgScSAgcCKqB6IKkqQFarF662T;
 25:Pxmx1htOzupym2WD+z4T3+r2BjKSN2/Hu5FpkermLXLL0drsmldneJyDwaa2wDGRVbiIa7mX+y0uua2NTBruP+S9M4N92F/8yobCvnBIw8NBl/8rNRWEnMUP1OLKhQMr8fAXqiSI2r3uMZv4WvfmJJMlkK3tQgqDY/a3UeG0g5mI5B0vpqSrct0+FLL/qfiUYjcE+XhrIeCGyGS/Oze4vRApCl3DoXMrkDIbIblXWNF1vnDK8RygQ2HO1mNDU9xpnj5vK9sKMeQA+b3GpBiMSaRPxqGN6To09/8gTFi7OJ50bPPSP4EJ/KwBaZrjYn0iId0Gv/FRG4qOxh7fAZCDh7P3NkxoREZ+oO8aGCr74BI4X6oqrt4hYA/VYvbTZKMj2BXC0RVk1U35wotz870Nufr148rQZcVI+FPVzMb7cO1j61v5eW4fxoSaeO8JvxbldZbwTUdWLIcnlalgwhyvrQ==
X-Microsoft-Exchange-Diagnostics: 1; DM5PR03MB2473;
 31:g/fTsOd6JchkmOcmOeXajPMvxQopLTmlxbA/50P4q4ARE8u7UXxYjgCdeiwYvQC9vj24nvF8YDVYD7YxGFcX3HmHQA+mUlQeIcyOhJH6DaIablIHNL+kSPnNnq30vnN9Vg3cW0GtYr3oZW16pnlNaSyhxeRZuCnjBFrku5bGPhjZAE5/8kUVsvU41/u/BbkAW7BE7nCbo3SIHlOT0fnCCgZsCwvaLE/kdS9F7I+UU1DwwWoBcAPzTw5Du61IJtxjA+BXpKd3joyG73sJNcNUPQ==
X-Microsoft-Antispam-PRVS: <DM5PR03MB247310C14C4F1FDC0C841AD3907F0@DM5PR03MB2473.namprd03.prod.outlook.com>
X-Exchange-Antispam-Report-Test: UriScan:(185117386973197)(228905959029699);
X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0;
 RULEID:(6095060)(601004)(2401047)(8121501046)(5005006)(13024025)(13015025)(13023025)(13018025)(13017025)(10201501046)(3002001)(6055026)(6096035)(20161123561025)(20161123556025)(20161123563025)(20161123559025)(20161123565025);
 SRVR:DM5PR03MB2473; BCL:0; PCL:0; RULEID:(400006); SRVR:DM5PR03MB2473; 
X-Microsoft-Exchange-Diagnostics: 1; DM5PR03MB2473;
 4:JoHzL/gsJPGVZAiDBT5yW5vDlZ6wSwSulIZcic9XyxvebAVfulvN70PUHUvBC8dZVmLIIenymfkFFJyEUTFU1o/TcFfTDzQCx6wS+wUMDJz07Vd6p7MIQ0IoeOLY6wlbmyI4HpyiqsO9a29kid3Z1t12rfnvoXi7x6HRH8F+G6WzhVwa9lgxbCMTQoU+h07W0ZOSPHs7RuYmzYBB1KTNjQ2VhjFbGHAiml5dZVre7iTI6vEAIZZgm68IYmJOCb73i7tbn1nk8Iv3rX99dbNa1VDE7HTUMPxN6Zjan9DTaC0R8owv+5agDAvRHcwa7RqNGy/r9v2AocEoVMS5OTBh5r3Oj/awdSGITpsim3+CQGCXpRbzBzrmCi7gKpkhgw434leHF7CFEZXldIj5TT4skMcdZm4dGecPy3psoCh514fsyy17G4DV8TCEDTvjLKZtwD8yhByrnZiJNoVU+fibKdtkA7QfjDL43BqQArlJsAMKdvnhHDAP9F3lPWmmfeug0EVoaXRNIx7Jr6nVZ9Fbo48A2k5XKeaNPOb6Fg9AQ2AnBDlZpCfZhxCoM4MamnYj7vOvmiop9xZsIE6YIJWObWWue+LaYAKBdt6HsZdVFSovjCCSPClMp4kdb3fCXaG4lQISWv9URzGt6RhsPcNG5riAUTlqH1V3RVhibp6SojIgUgEPUrKOJhzTA/zog6LAEorwm9m8CVLADmj8MC9FPCkZhSUdTG4DaqzjONhJ9xiGaM15SPDdzBK1LlAclEdiSBXuxfVBiA3c19XG/mOioQ==
X-Forefront-PRVS: 01917B1794
X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM5PR03MB2473;
 23:ZIajGj6QxTzlND2rKVjRhZFmPqxmFLJdFoF7iZ6Kn?=
 =?us-ascii?Q?XIbRI72DeKEatU9rsijhIcv1KLK7R3uQbvInC+huhHvCwIMiHHV/NtkSV+mX?=
 =?us-ascii?Q?rgndpjuw7U97I1lQcKZQ4lz+/yQfZWQv0naByYzGuEQ3rszud8MlHi5mYTXy?=
 =?us-ascii?Q?Nv5P+tKN/EAAXEHrm6CDJOlTihFFeqPzhF+8HaqoOoDb/nj1usiNdczYLMZA?=
 =?us-ascii?Q?ZSfaRUMl4xM1vNebbClUJjyeUpp0ofOT/CN8w149tLjMAzOGpMhZegz0K0ae?=
 =?us-ascii?Q?bTMrHU66L7yRa3eMN5PkvU1RZUDtDvIokCiZtrvFqz0IUUtN/ZS1SblB6U5T?=
 =?us-ascii?Q?wU0J0vivccvIyRUopIhKCDkmg0zoXTLtf7NLWPPYA6WZaqbrhAHQrAQ3hKK+?=
 =?us-ascii?Q?nC4aoOylS8uZ2/zJ13yK+wq6qGHqeK2sledkRdrAKDlq+/XSiVX18N377xaR?=
 =?us-ascii?Q?gdq8FRcWkaRrCh+xFXQXqosarVVX7lMRsYtIEFd6XZJPZZzNj3PS2p4ozlpw?=
 =?us-ascii?Q?WUzmQgu/yzr+GorgQDZH6uMrJM/gae2wUHjWJCplgwEffWoFESs32ZdBC3m1?=
 =?us-ascii?Q?vMKfRg6CMm22kP2ORaiNYbWhAr1BWm0ujZqRjq59+bIWS4EOO3+fDLFPuSTP?=
 =?us-ascii?Q?yhwgx1LUCvMlvxSa/AQmyHGGWiHrjHPwqftbA1N+6mRvnkjM8AVPNusEQUXz?=
 =?us-ascii?Q?K78RRfoxaTlglfbpMUe9rjL0kByO75SahO91Spl4z/PvukYgHJ2taF5gPGgx?=
 =?us-ascii?Q?1bQIdc/wi5ySsVkJaysk2tm+AJchLVlVcFXla6bTyAfU91EGSNps+OBN9HzS?=
 =?us-ascii?Q?vNctEeU4VhmuJtafs3CJi6RqpLvb3sGmsedBzVNNLJfTxVZgX4STl1mkxFl4?=
 =?us-ascii?Q?m3+0+67KoRGrfEJYiqq72MNRvNKCRfmJLBjblwLT/wiVHt6esL64TVCf0Jb6?=
 =?us-ascii?Q?HQr9XTT9gd9QEf/Pu0HMRYs3vkvOnAgdIqyVhLa/PajPyP/SMq3/W/2biy84?=
 =?us-ascii?Q?DBde/19pv9sOf8cRbaC4H6ArYz1e6naLX5PWBfkNK2qRzUOcL4LrLyYaPIRy?=
 =?us-ascii?Q?iXiVKo+8oYwxBz7n3+BINVfsCIbsSc6jPgk0+I/a/qdknrQAO+MXcr+fUaaq?=
 =?us-ascii?Q?5P/rLcobCYgTxvgFf5g7WC+wt3coOBAYHovPo9g94Vc8S5s7relg5UZRley/?=
 =?us-ascii?Q?gl7+N7Eqdbd6BIAHOdzlVma7YMoYHwrGBqgUBWi6BbCOXNoD9BIHkq8/zfQw?=
 =?us-ascii?Q?F3u+9DACRoSbCD3yH+XmBmGX/Oz1kGbmsw0VHwzFAoC2Xr0gRh3K8rOw5rqC?=
 =?us-ascii?Q?ZEIKHUo1N3KzR4btuRwZkCGdQcv/lkTBMdHeof65wBz?=
X-Microsoft-Exchange-Diagnostics: 1; DM5PR03MB2473;
 6:aKkJAjY46Nv2qw8j+lfvBhcpaQd4dmZ1eTv8FsioLpTJ62IkuPPrhivfIPqSkovV3IoKR5Qs0Jf4KERVFp/e5VsPLnxYwU78YE34w4ZlMSjQWDHLkOkCsJCnwnKrZi2Hz3jJJlItoLZzDr6F7b3nyX0uNkBvzXV8NWdUP3EYBaw1cLMCQtEOs5DWGRqe+Eki7+spZkJ9/6T5MHQCOVpsSkoK9sOWx1wr17vxngC/e6bmI67cfc9eLceTGMsEYzHFUkW7qMyLfO7VVhkDNXpFwgPDl24uHZhafO6DBh8oAO+DGIPc2MWNblvv0pDU8PVaMghHc3hAikU+W1ZKUalW/rQSTnFB8MMJp8AAbbVLV4mtffWLuOqGrkylyuW+Dqkb6UwDNQOuZgrf8qAC4B51urbjOAj+UneVeIdW8nr3Wmh/0Vq2pbEDPfzZY/RlIhZO;
 5:w/Xt6RbXfI/lpX9+KMaB4NMuO88rcDJo1fuKbKd1HA9iMkofyfurhztwtcnAjMHjr5ea2Xg70eXl/OOTRIWjrDREMvXyqHQent5hpW4kbql+Z026sqlUagIYwru/wbpfG1Emo7Z3T2AjhuI9cliTD9dY1hJbQ3gryBXF2qWePF/7VDOlzyzR21o4eyqAVC5+;
 24:lpu2d2NxjKJjGMwv0HnHbrkj+PAEs2NHhOMeSEaA2MouwKNzA7bkRtExYAeb05FtNe5uuZKUmDrbE0QZJo0YehKCR1xnL99silkQrT2pCfc=
SpamDiagnosticOutput: 1:99
SpamDiagnosticMetadata: NSPM
X-Microsoft-Exchange-Diagnostics: 1; DM5PR03MB2473;
 7:NMELj0ZOdzvNQXkYffZn1y6q9DMNx20XUsIeyCxEn3hDghZeewntV7EaXuID/QRxzRQ8uiv4tyxWUyj7wPk8QIwyrwBt3f00BgVzuJzZ7yMi3ss/sBnH4CkSmZbyPY8e+67dPutXle1gNSlQUoqws98AP5xAKZd21HNVrI2nuhvBlQgFxQaWEsEN8DoNqVrck8y3FT1cOMUennE1y3Vqp7Cggb3Z2l81I3PyI7X1+ylyE5S1HWF2+9NJ/OtBH2RVfritTs6dbd8UEKV19gYr18Rub4MQ7D5KVFS41h2yjk3VdsjuER7D1mO3rzbPakpPKYJohEB8H/LQks/JwZb4NfAZsJXb+3wnmRjEEGzIjWXFtz6KfxHniiFiLkvc5VmRGh5ImBDp2BNafWofkrCY4dWA3AAvxqipPjYI7QEIS9+RNdvGPXE3Nmg6oV6W7nXqbf0C6mCun0eeZW03uMopFg==
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Jan 2017 10:35:30.9537 (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: DM5PR03MB2473
Subject: [dpdk-dev] [PATCH v9 08/12] eal/pci: add support for PCI bus
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <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: Wed, 18 Jan 2017 10:35:34 -0000

Based on EAL Bus APIs, PCI bus callbacks and support functions are
introduced in this patch.

EAL continues to have direct PCI init/scan calls as well. These would be
removed in subsequent patches to enable bus only PCI devices.

Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 lib/librte_eal/bsdapp/eal/eal.c         |  1 +
 lib/librte_eal/bsdapp/eal/eal_pci.c     | 11 ++++++
 lib/librte_eal/common/eal_common_pci.c  | 33 ++++++++++++++++
 lib/librte_eal/common/include/rte_pci.h | 68 +++++++++++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/eal_pci.c   | 15 ++++++++
 5 files changed, 128 insertions(+)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index f0abd82..a584447 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
 #include <rte_string_fns.h>
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 3a5c315..48bfe24 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -673,3 +673,14 @@ rte_eal_pci_init(void)
 	}
 	return 0;
 }
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_eal_pci_scan,
+		.probe = rte_eal_pci_probe,
+	},
+	.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);
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 7548ab0..d2699bd 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -71,6 +71,7 @@
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -487,3 +488,35 @@ rte_eal_pci_unregister(struct rte_pci_driver *driver)
 	rte_eal_driver_unregister(&driver->driver);
 	TAILQ_REMOVE(&pci_driver_list, driver, next);
 }
+
+/* Add a PCI device to PCI Bus */
+void
+rte_eal_pci_add_device(struct rte_pci_bus *pci_bus,
+		       struct rte_pci_device *pci_dev)
+{
+	TAILQ_INSERT_TAIL(&pci_bus->device_list, pci_dev, next);
+	/* Update Bus references */
+	pci_dev->device.bus = &pci_bus->bus;
+}
+
+/* Insert a PCI 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)
+{
+	TAILQ_INSERT_BEFORE(exist_pci_dev, new_pci_dev, next);
+	/* Update Bus references */
+	new_pci_dev->device.bus = exist_pci_dev->device.bus;
+}
+
+/* Remove a PCI device from PCI bus */
+void
+rte_eal_pci_remove_device(struct rte_pci_device *pci_dev)
+{
+	struct rte_pci_bus *pci_bus;
+
+	pci_bus = container_of(pci_dev->device.bus, struct rte_pci_bus, bus);
+	TAILQ_REMOVE(&pci_bus->device_list, pci_dev, next);
+	/* Update Bus references */
+	pci_dev->device.bus = NULL;
+}
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index adc20b9..05cf693 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -85,6 +85,7 @@ extern "C" {
 #include <rte_debug.h>
 #include <rte_interrupts.h>
 #include <rte_dev.h>
+#include <rte_bus.h>
 
 TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
 TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
@@ -111,6 +112,25 @@ const char *pci_get_sysfs_path(void);
 /** Maximum number of PCI resources. */
 #define PCI_MAX_RESOURCE 6
 
+/** Name of PCI Bus */
+#define PCI_BUS_NAME "PCI"
+
+/* Forward declarations */
+struct rte_pci_device;
+struct rte_pci_driver;
+
+/** List of PCI devices */
+TAILQ_HEAD(rte_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(rte_pci_driver_list, rte_pci_driver);
+
+/* PCI Bus iterators */
+#define FOREACH_DEVICE_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.device_list), next)
+
+#define FOREACH_DRIVER_ON_PCIBUS(p)	\
+		TAILQ_FOREACH(p, &(rte_pci_bus.driver_list), next)
+
 /**
  * A structure describing an ID for a PCI driver. Each driver provides a
  * table of these IDs for each device that it supports.
@@ -206,12 +226,22 @@ typedef int (pci_remove_t)(struct rte_pci_device *);
 struct rte_pci_driver {
 	TAILQ_ENTRY(rte_pci_driver) next;       /**< Next in list. */
 	struct rte_driver driver;               /**< Inherit core driver. */
+	struct rte_pci_bus *pci_bus;            /**< PCI bus reference */
 	pci_probe_t *probe;                     /**< Device Probe function. */
 	pci_remove_t *remove;                   /**< Device Remove function. */
 	const struct rte_pci_id *id_table;	/**< ID table, NULL terminated. */
 	uint32_t drv_flags;                     /**< Flags contolling handling of device. */
 };
 
+/**
+ * Structure describing the PCI bus
+ */
+struct rte_pci_bus {
+	struct rte_bus bus;               /**< Inherit the generic class */
+	struct rte_pci_device_list device_list;  /**< List of PCI devices */
+	struct rte_pci_driver_list driver_list;  /**< List of PCI drivers */
+};
+
 /** Device needs PCI BAR mapping (done with either IGB_UIO or VFIO) */
 #define RTE_PCI_DRV_NEED_MAPPING 0x0001
 /** Device driver supports link state interrupt */
@@ -523,6 +553,44 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 void rte_eal_pci_unregister(struct rte_pci_driver *driver);
 
 /**
+ * Add a PCI device to the PCI Bus (append to PCI Device list). This function
+ * also updates the bus references of the PCI Device (and the generic device
+ * object embedded within.
+ *
+ * @param pci_bus
+ *	PCI Bus reference to which device is to be added
+ * @param pci_dev
+ *	PCI device to add
+ * @return void
+ */
+void rte_eal_pci_add_device(struct rte_pci_bus *pci_bus,
+			    struct rte_pci_device *pci_dev);
+
+/**
+ * Insert a PCI device in the PCI Bus at a particular location in the device
+ * list. It also updates the PCI Bus reference of the new devices to be
+ * inserted.
+ *
+ * @param exist_pci_dev
+ *	Existing PCI device in PCI Bus
+ * @param new_pci_dev
+ *	PCI device to be added before exist_pci_dev
+ * @return void
+ */
+void rte_eal_pci_insert_device(struct rte_pci_device *exist_pci_dev,
+			       struct rte_pci_device *new_pci_dev);
+
+/**
+ * Remove a PCI device from the PCI Bus. This sets to NULL the bus references
+ * in the PCI device object as well as the generic device object.
+ *
+ * @param pci_device
+ *	PCI device to be removed from PCI Bus
+ * @return void
+ */
+void rte_eal_pci_remove_device(struct rte_pci_device *pci_device);
+
+/**
  * Read PCI config space.
  *
  * @param device
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index e2fc219..300064d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -35,6 +35,7 @@
 #include <dirent.h>
 
 #include <rte_log.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
@@ -54,6 +55,9 @@
  * IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
  */
 
+/* Forward declaration of PCI bus */
+struct rte_pci_bus rte_pci_bus;
+
 static int
 pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
 {
@@ -723,3 +727,14 @@ rte_eal_pci_init(void)
 
 	return 0;
 }
+
+struct rte_pci_bus rte_pci_bus = {
+	.bus = {
+		.scan = rte_eal_pci_scan,
+		.probe = rte_eal_pci_probe,
+	},
+	.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);
-- 
2.7.4