From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-CO1-obe.outbound.protection.outlook.com (mail-co1nam03on0048.outbound.protection.outlook.com [104.47.40.48]) by dpdk.org (Postfix) with ESMTP id 5A6C9690F for ; Mon, 26 Dec 2016 13:51:04 +0100 (CET) Received: from BN6PR03CA0029.namprd03.prod.outlook.com (10.175.124.15) by DM2PR0301MB0752.namprd03.prod.outlook.com (10.160.97.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.803.11; Mon, 26 Dec 2016 12:51:01 +0000 Received: from BN1BFFO11FD030.protection.gbl (2a01:111:f400:7c10::1:179) by BN6PR03CA0029.outlook.office365.com (2603:10b6:404:10c::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.803.11 via Frontend Transport; Mon, 26 Dec 2016 12:51:01 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) 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.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 BN1BFFO11FD030.mail.protection.outlook.com (10.58.144.93) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.789.10 via Frontend Transport; Mon, 26 Dec 2016 12:51:00 +0000 Received: from Tophie.ap.freescale.net ([10.232.14.87]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id uBQCl90S011201; Mon, 26 Dec 2016 05:50:57 -0700 From: Shreyansh Jain To: CC: , , Shreyansh Jain Date: Mon, 26 Dec 2016 18:20:42 +0530 Message-ID: <1482756644-13726-11-git-send-email-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1482756644-13726-1-git-send-email-shreyansh.jain@nxp.com> References: <1481893853-31790-1-git-send-email-shreyansh.jain@nxp.com> <1482756644-13726-1-git-send-email-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131272302611791911; (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)(336005)(7916002)(39860400002)(39410400002)(39450400003)(39850400002)(39400400002)(39840400002)(39380400002)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(356003)(47776003)(106466001)(2351001)(69596002)(8676002)(33646002)(48376002)(110136003)(5660300001)(105606002)(6916009)(6666003)(68736007)(50466002)(2950100002)(36756003)(77096006)(81156014)(81166006)(38730400001)(305945005)(50226002)(626004)(8936002)(76176999)(50986999)(104016004)(8656002)(92566002)(85426001)(86362001)(575784001)(5003940100001)(4326007)(2906002)(97736004)(189998001)(7059030); DIR:OUT; SFP:1101; SCL:1; SRVR:DM2PR0301MB0752; H:az84smr01.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD030; 1:CiicNUqym3+EgMv+B83nAD14G51+2hD1e2Adz//NKewj+qMbA26v5YWUhCA4NSVd4aImoG3Jr5mjroWZAXWkpE82GvDsUwzK2ekLT+1uZ5f0W8LbmQrSE5XUZ+mEnB+UsUZ8PX4OTpNVyrYqsLKaGrJHbQRDv3bfZ3B9cxUEgF5u4qD1yA7y4d43MwnG3F6l3NI2pYxjT4BWtOKPiCbNhZHPGb4ntGG38OD26Vjy7S40wP83KmZga1F2EYqxdj1HlE754P/i2Zl9luzINgdTpYfjLRCYWETZO/FoIr3BtU1wglHAoKhhTY4AAS70Ubu0k1CfAzlTitsGA+a+X2Wy9fgysSQfreM3UgWyAWH/VVt6epSqvfJKjdu6Rt/LLOpN2pxOJ1HBWkt0kJwha7C7xrW/WtvZhHgCCp/P/0zBVpAF7V2t7Cr8wBTsbQtdRndGB9obo8mPq5ZcHmEOUw58mGpk5FRaMk0zjrg65NzjCBlbG/BtUsdj/d3p4jT37JJLdwuXhk09Pm1fTlokbgpKI7wWsyoZJepJd3Lj23akqtWGdRsnHBoWc0vpmqsm8DpXdz0a3Ql2tbGlqLQQR2Le0uf/DVVaZnnvsN6pTS4Xj2i9EFdnlyXXr2W0nMYuBpa8f/N21DbcUc6ty6mHFqsRCZwNUF4RBnJDmGFURRVgD4LF0uykY+8+TUWXl+UwYEfMvC5AzVy4zwdxVJ1VYCrP+kazYVo7Aer0XAtjYxq7c9Y= MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: b22ad1fa-a284-4c45-f51f-08d42d8dd869 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:DM2PR0301MB0752; X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 3:eVx6W02DYV3yUutsH2nlhfcWDz/3cWgOV5lG5orXY42K/rlCmDmWk4OwlpggL0VEE+0cO5EqYV6tETdplSF/Sx+dxF3MJijtsgibvDATncHfh3zsq7ABo5Pq6DBwVa0wFQnkTThFCuGPbPdZhUTwsESPSGkhxxfRYB65V2BN+0DSazZUTMT6oZCNpr3BSjMzRSGB8DR1VvoI5D04LRAEIbR9rAkSISmCG9HFYQ8o2xm0ufnJDgEd3U8P7W/NMw3BpJcKW1Gel4/CUbUvpgR04vF9JJ6zdLKqGI+/Q8b8ZXx5ADn/gQrvMo4r64PQJ8vGGf70E4EBDmqAF61PmGlpILvLhJe+0fzZmkERXShjxzg= X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 25:Y/9i8TJMiuHqnx4hcC7JAKQbKruN9B+s/oeO2sTea8RpiPL41LsV27dz7+qdHtuSF/qegjmkAwV/d3wEFnpdFW9+HWZN6wY4/sTkXy9eDnmJw+Ax6RnmsG1pSQnOW8QOxO54wcWQBMuEICkobPAbevlhbyfl4TzwyKObx444TgRMuG8Ju4n08GXdTSiPpHjve3V5QkUcPJWyvXWiVz5L/W2zKZ6xX4w3xKCZzr4mV+arpawCwoYZ74s6t7B6hCRHzmnyNFneJynvawjdvqBSIV3+QFmbpBhGcQczk8yTSNME7bV/o6dg7oM4l6eoyUMpWZvbjjqY3DMUrkO+foOinbMuvRWlWllNeRp0Cnf/cNuGKvVSqJ/+KmpE4Hh2bNXklm0POLwHakg0/8cIVFkNF3VemIxdIUW+RIao3ePy7sLUzEpGkqOB/e4mtBEVaDDrcA1gJx1kvj1zMAtDfV8lqe/wTnTSVvA102A/4b00i2ljBNzJoqHKWlKZ8HF9//zM6Zb4L9YPR/a/kKer643wLqWtdnvdnxi2oKbMSLyM823CC5MnEH/JACblsbD/L8WdxLsbLURxW+94LweZT0yCYKD6e03W9tF/xxkMpYWN3xslu2AxAj/GgnZ+Oo7yFGAAF+cnFTyDJyGCGXcl5yRjvjRspa+Co5Xq+P7KoNafvIJB+AW5WArxpIwqAQTz7N8bLH8VAlWI/zBM0WV4Wkp9uwuakVCatzokSXc73txfW7kdA3XA1gS52khUcYMszFJasvO9RzpRLeyHOhXgOiQaGS0ROzggIG2FSzVomKXLE0rid1n4qFQUfDYuf75ZE75P X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 31:ZRKXSlTuKhVL8qEjraQen8WiHTSBwKlVEBvLDmB4iaVZwpnleUQ7SQnWh1XDNzh7FMv2+084br3Ad6mdqm/CF0d/+is2ci39gYym9N8wOPWTBjZaxF4fot6GxYctdht902hLDZVFsk03Rs0/WZtumiSLjRmoo4CJu9OmExTbIZa9GkwgTXD9vGKV6gtxMkZolPd1HdmyME8qmomyS257kVZtGECjIOnN/mfm6l2WW3hDoSp7XPmC/yq/S0BEgPihia6lVi1luOH8JBAQGQXcMQjcZ+cmYT5rwLS3ssw9yVU= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095060)(601004)(2401047)(13017025)(13024025)(13023025)(13015025)(13018025)(5005006)(8121501046)(10201501046)(3002001)(6055026)(6096035)(20161123561025)(20161123559025)(20161123556025)(20161123563025)(20161123565025); SRVR:DM2PR0301MB0752; BCL:0; PCL:0; RULEID:(400006); SRVR:DM2PR0301MB0752; X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 4:M909VqyZTWNVqBDH6irrf9ihQTMdGMfMxU9yufxdJ1hzAx/E3/EOObonJg7Ygv8gbcHfwm/03VaaSsaah40zAiBEr5PLd9UGSzgW7/tc/TrHCQV28mry/EZSiQEqYxWUGBUawnXmNrDBA421ikCHdBMLrJJsQUllesx+xtOz9OY8jrWmCgpKpNehaliN4XyZYdgkCtB2xQkV0Xr8BNVTZxRjfuSvEnMeqhY8PhjScZZH5Wg8xyVpO758yHct3TZR/vMAzlBymsOfCTt+aWO74a3jxD9vL8zEE4hcdi6SO0k8+u5tm7MkrQAWkXnA2es2Rrnf8mW1VZc18KLHeYoPXwvtW7/ZsAfIyoxu3ll0djdvfYoQw1EvPHbh+tfRqaA25cXqBsljjkq9wdbnjh4nJfh+wd6p4xc4Mr4CnvC5WJ9GEFw+Hy8ln8aakfL+brt8jHBirsich8aETdveU8MqGQF3/R3JU5lPddfHDmbJ09QbeMi0Q8IlADpJkPm+RVh90xfV3I+NiLz+ZBazzmXAnPduPZpg+FjWbHglxqyOyg1tpBGl0riKeQEpobZHMUlVB+f5sdD5g0IoxyBSSkJ0amHKFPoCRA65kvVaYW3a+co50W9WAxGstaKyl9jVKF8nWULKEdvpxoCorSkKc7IGh7u4HWqD/oG9pEj1x5m/d4evxK2j1pAj3wR8+OZPH7LXB8feSI/d17g5lNRKia15LjU1WilcXWWmUzdUqPhfPfY= X-Forefront-PRVS: 016885DD9B X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM2PR0301MB0752; 23:kXvQjK5HmKdCifa3J4uZT/EkDFQZv01jzmb+bXp?= =?us-ascii?Q?uv6aJ676iB/7qohVz8fSwTcZsxk8jkzKpNqw6Bjh+v/vx3yEuTwJEokS/Ec6?= =?us-ascii?Q?O0GEBB7k0VpUnPp4uhDOBdKcoVyF9q+TaLjL2xGXFpp1nKGx4o404ObCsYhE?= =?us-ascii?Q?jziNHyvyrc25NWIuj+86Cs3szZNC+iUZXQX+1Xhf3rOJ/lVNi/K54Cw626eN?= =?us-ascii?Q?ZNyYHjRhM3l3M7cYXW6jeW+CTjn19vVp8vmdlzjdhdW/vRN4h1WFFUOP/mcN?= =?us-ascii?Q?ROTBZ9sgwex0g3Qh3Kr+depozUbvGzggwxol1w2pImAPQfq/bsvTLCfDYGYy?= =?us-ascii?Q?sTLLtWgMOvrJz4EeYKW7ujytps5hIYx8gYCuGX1LQu6TyCDy0qUAJSBZDUNj?= =?us-ascii?Q?DF7Wqr0NgCjCBk6lC5gUrC8l3dKh+4NZPEM0pGK6gwceLgrKBZ8hv9eJBESJ?= =?us-ascii?Q?jxS5I+woLwczDzj//SbOvO+8S0iY12ra3uAqtIHaQrGaE+wpes9sMpfmywW2?= =?us-ascii?Q?COTt18+B/iGfDb9RB3HoW6gR4wPch3v0PIZQ9lB2XlIekP/V4UVLSAIyO6nH?= =?us-ascii?Q?DQ3lOPZfZy4MwlEd9Gjou44FCYFyOxbOC0IlYZ32Des0CT7O4BDKg/tNOCjC?= =?us-ascii?Q?Qc85n814wUMZHnCRl8Y4HoYnMOzFbGdOflCGUO/Wmr66IjPTy6kjYmG1ZdDk?= =?us-ascii?Q?yTpycc/9RcDDNlouy5oWvyEyu6KvnJslDqM1Aue6uTt0MI/xVZJrMN9g5oh7?= =?us-ascii?Q?IpsJJSaaCrUIC7JTNh6kNyltapVLVAwCYnc4l08sfCfA9BINz/0IA8rDZ6Dy?= =?us-ascii?Q?draYhpemuTFqHRmi7jsKaYhekVVfgymlvmNKORIVH1NjPS4a7afqL8RgABjK?= =?us-ascii?Q?Ru9hiB/nL4/x7+T74bW3gx3+LK4SXhwkRkM7pklQ1FYxzV8juBkCc7sVRfIs?= =?us-ascii?Q?IuUlCwNIcGzc2aU4GyItn6FPyku0lhBmOX6s5SpfH1s1fhoX/1gLseM+w8dw?= =?us-ascii?Q?yqM7UqR5qxmcwYvxK+TUU16E6q4ryDJch+8EH5DgGD01xUPBRIGQcMxnrKnS?= =?us-ascii?Q?XHmic7TYmhw4lASH7oB2M6C6Z1ig0wNbtlIqEVbozhjAjc5Bgj6Qq1perU1A?= =?us-ascii?Q?OSboKmnY4mbKOnDQ4JJNUGZQt2tbM80FOuh5K57T2CjL4pga2O4V7kx1j7SH?= =?us-ascii?Q?CgNUUKzpFRkPh6Y/lbHJb5y+kDOy8Ny6J9bSZwj87zoTh+sOFJb8jkpOgzyH?= =?us-ascii?Q?TVh55lwJzZ+IlCgd5h6wHWBHKSsW9J153N7XGKnFlRGl/Hc2HScdcpaBme02?= =?us-ascii?Q?Ho3xNSBFC2RAIKWFWJA5DiohER//8jL313JB+53jwMDyz?= X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 6:R3QRZmGGLJWhBalxGuJlTbL+qRJYDyufiRsqstmPp2/xBg9VSIrIdthQSKVwrH3BqG46SneaHxg2bKeGlwEzNuN3HqohWWyhH97ECFaIw/fD7++2080JbHdlthIDjNX6CGX5PMmq2tdoxJQGiFK8PKwA7M7zhnQYEmFkEL3W1cNF2Q0mp4SPfMY0BT3CFKl0d2GbYq28Fs8oW5epAuXbjndPeccB5yoYmQOOP8CWmyjdPyumbJdpNqnmY7kpBFhcXH4DT96ZxGe5rKMfMMqjgOQNtn57b+wFAuENW4uyu8Zltyf/bRYPBINgRH0h7govZnqFlIwgThWIMYZVMT42t8tDvefHx/KGNwlNz9FJGNdf02U+8T+Qz8QIVxUymn4EX1Bs0YXiwxbCx9GudQWZsyUs9jd4jnqi/JSovdyeHTEA5OeqgUAVdB+WUrMOtpJf; 5:zmc0Sn528pbQdKmz5D+M5q9LxRD8OJOzJAYifPlk9O5Uhq20Xi0cKrYCLxQMNZlR37Yrhs7vFAHEO0GpVuORRSc39WtEBEESiwFsUgFbdDRog/7VOoOc6RhRtj6YalLgBJwk5r+FGES6PKGl0/f3vQf4vAzzusIhWznhgObVZbZ++wVMHeobq9+73jN09jrC; 24:6oFaDND6ImQoBhjEvVIjAmUJGGLoJKdogapTFTu5dP9pfS1GQSfJ6aot6Or2thuO8ctmVFaD4tf4RYqq4z0calDTNlyfvp6/Zpz5WjEVua0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM2PR0301MB0752; 7:wkwRuoTV373fmmE0v3mMnB/c7du0SMGI8F04w9JvuUCj8WkrkJaOO+lzX2xsQo4O5NPn+qesQPmjJPalEMvlG7/Rh29ItAkkSA/dVwS5V2oGqrO/ex4W66wehvna4HxP9QPNtfjg8x6c9CQnYok6zsKAJ67kwWAbcUDEY06IOrh/Hd+JKzh3U8TMt9jGyTKfaIoEyNQC5W0HQgJj1qYe/L5kNuERRvZLZA7Xm3D4+rHBZOllO7TLXjbhhntGfDWG+AkwOwJYIZT1Po5Gz7BK/egt5bJi6Z8OZ4/BBBlFHQbGrb6nzv/rfOYgrGF+N4NOiTo5mSjWdWC5yd0IHFcbi3c90ER8IqKfvPVkvUBbemOWnYDgQhIxEbsWei/aH26sR5toeyABAU2DYVE+Kmp5aSG2IE+uHvfDJfZPqbQjbaypbeCuW0H7PHsk++5OsA9CtGes1waYHzb0EdEmzxkRmw== X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Dec 2016 12:51:00.8203 (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: DM2PR0301MB0752 Subject: [dpdk-dev] [PATCH v4 10/12] eal: enable PCI bus and PCI test framework 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: Mon, 26 Dec 2016 12:51:05 -0000 Register a PCI bus with Scan/match and probe callbacks. Necessary changes in EAL layer for enabling bus interfaces. PCI devices and drivers now reside within the Bus object. Now that PCI bus handles the scan/probe methods, independent calls to PCI scan and probe can be removed from the code. PCI device and driver list are also removed. rte_device and rte_driver list continue to exist. As does the VDEV lists. Changes to test_pci: - use a dummy test_pci_bus for all PCI test driver registrations - this reduces the need for cleaning global list - add necessary callbacks for invoking scan and probing/matching using EAL PCI scan code Note: With this patch, all PCI PMDs would cease to work because of lack rte_driver->probe/remove implementations. Next patch would do that. Signed-off-by: Shreyansh Jain --- app/test/test_pci.c | 154 +++++++++++------ lib/librte_eal/bsdapp/eal/eal.c | 8 +- lib/librte_eal/bsdapp/eal/eal_pci.c | 52 +++--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 7 +- lib/librte_eal/common/eal_common_pci.c | 212 ++++++++++++++---------- lib/librte_eal/common/eal_private.h | 14 +- lib/librte_eal/common/include/rte_pci.h | 53 +++--- lib/librte_eal/linuxapp/eal/eal.c | 8 +- lib/librte_eal/linuxapp/eal/eal_pci.c | 57 ++++--- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 7 +- 10 files changed, 332 insertions(+), 240 deletions(-) diff --git a/app/test/test_pci.c b/app/test/test_pci.c index f9b84db..e95b758 100644 --- a/app/test/test_pci.c +++ b/app/test/test_pci.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -61,10 +62,18 @@ int test_pci_run = 0; /* value checked by the multiprocess test */ static unsigned pci_dev_count; +static struct rte_bus *pci_bus; /* global reference to a Test PCI bus */ static int my_driver_init(struct rte_pci_driver *dr, struct rte_pci_device *dev); +/* Test PCI bus. */ +struct rte_bus test_pci_bus = { + .name = "test_pci_bus", + .scan = rte_eal_pci_scan, + .match = rte_eal_pci_match, +}; + /* IXGBE NICS */ struct rte_pci_id my_driver_id[] = { {RTE_PCI_DEVICE(0x0001, 0x1234)}, @@ -79,7 +88,9 @@ struct rte_pci_id my_driver_id2[] = { struct rte_pci_driver my_driver = { .driver = { - .name = "test_driver" + .name = "test_driver", + .probe = rte_eal_pci_probe, + .remove = rte_eal_pci_remove, }, .probe = my_driver_init, .id_table = my_driver_id, @@ -88,7 +99,9 @@ struct rte_pci_driver my_driver = { struct rte_pci_driver my_driver2 = { .driver = { - .name = "test_driver2" + .name = "test_driver2", + .probe = rte_eal_pci_probe, + .remove = rte_eal_pci_remove, }, .probe = my_driver_init, .id_table = my_driver_id2, @@ -108,14 +121,67 @@ my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr, return 0; } +/* dump devices on the bus */ +static void +do_pci_device_dump(FILE *f) +{ + int i; + struct rte_pci_device *dev = NULL; + struct rte_device *r_dev = NULL; + + TAILQ_FOREACH(r_dev, &pci_bus->device_list, next) { + dev = container_of(r_dev, struct rte_pci_device, device); + + fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus, + dev->addr.devid, dev->addr.function); + fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id, + dev->id.device_id); + + for (i = 0; i != sizeof(dev->mem_resource) / + sizeof(dev->mem_resource[0]); i++) { + fprintf(f, " %16.16"PRIx64" %16.16"PRIx64"\n", + dev->mem_resource[i].phys_addr, + dev->mem_resource[i].len); + } + } +} + +/* Dummy implementation for rte_eal_pci_probe() over test_pci_bus */ +static int +do_pci_bus_probe(void) +{ + int ret; + struct rte_device *device; + struct rte_driver *driver; + + TAILQ_FOREACH(device, &pci_bus->device_list, next) { + TAILQ_FOREACH(driver, &pci_bus->driver_list, next) { + ret = pci_bus->match(driver, device); + if (!ret) { + if (!driver->probe) + continue; + + device->driver = driver; + ret = driver->probe(driver, device); + if (ret != 0) + return ret; + } + } + } + + return 0; +} + static void blacklist_all_devices(void) { struct rte_pci_device *dev = NULL; + struct rte_device *device = NULL; unsigned i = 0; char pci_addr_str[16]; - TAILQ_FOREACH(dev, &pci_device_list, next) { + TAILQ_FOREACH(device, &(pci_bus->device_list), next) { + dev = container_of(device, struct rte_pci_device, device); snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT, dev->addr.domain, dev->addr.bus, dev->addr.devid, dev->addr.function); @@ -142,19 +208,11 @@ static void free_devargs_list(void) } } -/* backup real devices & drivers (not used for testing) */ -struct pci_driver_list real_pci_driver_list = - TAILQ_HEAD_INITIALIZER(real_pci_driver_list); -struct pci_device_list real_pci_device_list = - TAILQ_HEAD_INITIALIZER(real_pci_device_list); - REGISTER_LINKED_RESOURCE(test_pci_sysfs); static int test_pci_setup(void) { - struct rte_pci_device *dev; - struct rte_pci_driver *dr; const struct resource *r; int ret; @@ -167,22 +225,19 @@ test_pci_setup(void) ret = setenv("SYSFS_PCI_DEVICES", "test_pci_sysfs/bus/pci/devices", 1); TEST_ASSERT_SUCCESS(ret, "failed to setenv"); - /* Unregister original devices & drivers lists */ - while (!TAILQ_EMPTY(&pci_driver_list)) { - dr = TAILQ_FIRST(&pci_driver_list); - rte_eal_pci_unregister(dr); - TAILQ_INSERT_TAIL(&real_pci_driver_list, dr, next); - } + /* Create a new Bus called 'test_pci_bus' */ + /* Bus doesn't exist; Create the test bus */ + printf("Creating a Test PCI bus\n"); + rte_eal_bus_register(&test_pci_bus); + pci_bus = &test_pci_bus; - while (!TAILQ_EMPTY(&pci_device_list)) { - dev = TAILQ_FIRST(&pci_device_list); - TAILQ_REMOVE(&pci_device_list, dev, next); - TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next); - } + printf("Scan for Test devices and add to bus\n"); + ret = pci_bus->scan(pci_bus); - ret = rte_eal_pci_scan(NULL); TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus"); - rte_eal_pci_dump(stdout); + + printf("Dump of all devices scanned:\n"); + do_pci_device_dump(stdout); return 0; } @@ -190,8 +245,8 @@ test_pci_setup(void) static int test_pci_cleanup(void) { - struct rte_pci_device *dev; - struct rte_pci_driver *dr; + struct rte_device *dev = NULL; + struct rte_driver *dr = NULL; const struct resource *r; int ret; @@ -203,28 +258,23 @@ test_pci_cleanup(void) ret = resource_rm_by_tar(r); TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name); + TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified"); + /* * FIXME: there is no API in DPDK to free a rte_pci_device so we * cannot free the devices in the right way. Let's assume that we * don't care for tests. */ - while (!TAILQ_EMPTY(&pci_device_list)) { - dev = TAILQ_FIRST(&pci_device_list); - TAILQ_REMOVE(&pci_device_list, dev, next); + TAILQ_FOREACH(dev, &(pci_bus->device_list), next) { + rte_eal_bus_remove_device(dev); + dev->driver = NULL; } - /* Restore original devices & drivers lists */ - while (!TAILQ_EMPTY(&real_pci_driver_list)) { - dr = TAILQ_FIRST(&real_pci_driver_list); - TAILQ_REMOVE(&real_pci_driver_list, dr, next); - rte_eal_pci_register(dr); + TAILQ_FOREACH(dr, &(pci_bus->driver_list), next) { + rte_eal_bus_remove_driver(dr); } - while (!TAILQ_EMPTY(&real_pci_device_list)) { - dev = TAILQ_FIRST(&real_pci_device_list); - TAILQ_REMOVE(&real_pci_device_list, dev, next); - TAILQ_INSERT_TAIL(&pci_device_list, dev, next); - } + rte_eal_bus_unregister(pci_bus); return 0; } @@ -234,16 +284,19 @@ test_pci_blacklist(void) { struct rte_devargs_list save_devargs_list; - printf("Dump all devices\n"); - TEST_ASSERT(TAILQ_EMPTY(&pci_driver_list), - "pci_driver_list not empty"); + TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified"); + + TEST_ASSERT(TAILQ_EMPTY(&pci_bus->driver_list), + "PCI Driver list not empty"); - rte_eal_pci_register(&my_driver); - rte_eal_pci_register(&my_driver2); + /* Add test drivers to Bus */ + rte_eal_bus_add_driver(pci_bus, &(my_driver.driver)); + rte_eal_bus_add_driver(pci_bus, &(my_driver2.driver)); pci_dev_count = 0; - printf("Scan bus\n"); - rte_eal_pci_probe(); + + printf("Probe the Test Bus\n"); + do_pci_bus_probe(); if (pci_dev_count == 0) { printf("no device detected\n"); @@ -257,8 +310,8 @@ test_pci_blacklist(void) blacklist_all_devices(); pci_dev_count = 0; - printf("Scan bus with all devices blacklisted\n"); - rte_eal_pci_probe(); + printf("Probe bus with all devices blacklisted\n"); + do_pci_bus_probe(); free_devargs_list(); devargs_list = save_devargs_list; @@ -270,8 +323,9 @@ test_pci_blacklist(void) test_pci_run = 1; - rte_eal_pci_unregister(&my_driver); - rte_eal_pci_unregister(&my_driver2); + /* Clear the test drivers added to Test Bus */ + rte_eal_bus_remove_driver(&(my_driver.driver)); + rte_eal_bus_remove_driver(&(my_driver2.driver)); return 0; } diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c index 2c223de..f801076 100644 --- a/lib/librte_eal/bsdapp/eal/eal.c +++ b/lib/librte_eal/bsdapp/eal/eal.c @@ -562,9 +562,6 @@ rte_eal_init(int argc, char **argv) if (rte_eal_timer_init() < 0) rte_panic("Cannot init HPET or TSC timers\n"); - if (rte_eal_pci_init() < 0) - rte_panic("Cannot init PCI\n"); - eal_check_mem_on_local_socket(); if (eal_plugins_init() < 0) @@ -613,10 +610,7 @@ rte_eal_init(int argc, char **argv) rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER); rte_eal_mp_wait_lcore(); - /* Probe & Initialize PCI devices */ - if (rte_eal_pci_probe()) - rte_panic("Cannot probe PCI\n"); - + /* Probe all the buses and devices/drivers on them */ if (rte_eal_bus_probe()) rte_panic("Cannot probe devices\n"); diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c index 56b506e..2190d0d 100644 --- a/lib/librte_eal/bsdapp/eal/eal_pci.c +++ b/lib/librte_eal/bsdapp/eal/eal_pci.c @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -240,7 +241,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx, } static int -pci_scan_one(int dev_pci_fd, struct pci_conf *conf) +pci_scan_one(struct rte_bus *bus, int dev_pci_fd, struct pci_conf *conf) { struct rte_pci_device *dev; struct pci_bar_io bar; @@ -313,19 +314,23 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) } /* device is valid, add in list (sorted) */ - if (TAILQ_EMPTY(&pci_device_list)) { - TAILQ_INSERT_TAIL(&pci_device_list, dev, next); + if (TAILQ_EMPTY(&bus->device_list)) { + rte_eal_bus_add_device(bus, &dev->device); } else { struct rte_pci_device *dev2 = NULL; + struct rte_device *r_dev2; int ret; - TAILQ_FOREACH(dev2, &pci_device_list, next) { + TAILQ_FOREACH(r_dev2, &bus->device_list, next) { + dev2 = container_of(r_dev2, struct rte_pci_device, + device); ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr); if (ret > 0) continue; else if (ret < 0) { - TAILQ_INSERT_BEFORE(dev2, dev, next); + rte_eal_bus_insert_device(bus, &dev2->device, + &dev->device); return 0; } else { /* already registered */ dev2->kdrv = dev->kdrv; @@ -337,7 +342,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) return 0; } } - TAILQ_INSERT_TAIL(&pci_device_list, dev, next); + rte_eal_bus_add_device(bus, &dev->device); } return 0; @@ -352,7 +357,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf) * list. Call pci_scan_one() for each pci entry found. */ int -rte_eal_pci_scan(struct rte_bus *bus __rte_unused) +rte_eal_pci_scan(struct rte_bus *bus) { int fd; unsigned dev_count = 0; @@ -365,6 +370,10 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused) .matches = &matches[0], }; + /* for debug purposes, PCI can be disabled */ + if (internal_config.no_pci) + return 0; + fd = open("/dev/pci", O_RDONLY); if (fd < 0) { RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__); @@ -380,7 +389,7 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused) } for (i = 0; i < conf_io.num_matches; i++) - if (pci_scan_one(fd, &matches[i]) < 0) + if (pci_scan_one(bus, fd, &matches[i]) < 0) goto error; dev_count += conf_io.num_matches; @@ -398,9 +407,9 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused) } int -pci_update_device(const struct rte_pci_addr *addr) +pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr) { - int fd; + int fd = -1; struct pci_conf matches[2]; struct pci_match_conf match = { .pc_sel = { @@ -418,6 +427,9 @@ pci_update_device(const struct rte_pci_addr *addr) .matches = &matches[0], }; + if (!bus) + goto error; + fd = open("/dev/pci", O_RDONLY); if (fd < 0) { RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__); @@ -433,7 +445,7 @@ pci_update_device(const struct rte_pci_addr *addr) if (conf_io.num_matches != 1) goto error; - if (pci_scan_one(fd, &matches[0]) < 0) + if (pci_scan_one(bus, fd, &matches[0]) < 0) goto error; close(fd); @@ -659,17 +671,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p) return ret; } -/* Init the PCI EAL subsystem */ -int -rte_eal_pci_init(void) -{ - /* for debug purposes, PCI can be disabled */ - if (internal_config.no_pci) - return 0; +struct rte_bus pci_bus = { + .scan = rte_eal_pci_scan, + .match = rte_eal_pci_match, +}; - if (rte_eal_pci_scan(NULL) < 0) { - RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__); - return -1; - } - return 0; -} +RTE_REGISTER_BUS(pci, pci_bus); diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index 51115f4..4874902 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -6,8 +6,6 @@ DPDK_2.0 { eal_parse_sysfs_value; eal_timer_source; lcore_config; - pci_device_list; - pci_driver_list; per_lcore__lcore_id; per_lcore__rte_errno; rte_calloc; @@ -41,7 +39,6 @@ DPDK_2.0 { rte_eal_mp_wait_lcore; rte_eal_parse_devargs_str; rte_eal_pci_dump; - rte_eal_pci_probe; rte_eal_pci_probe_one; rte_eal_pci_register; rte_eal_pci_scan; @@ -188,5 +185,9 @@ DPDK_17.02 { rte_eal_bus_remove_device; rte_eal_bus_remove_driver; rte_eal_bus_unregister; + rte_eal_pci_match; + rte_eal_pci_probe; + rte_eal_pci_remove; + rte_eal_pci_scan; } DPDK_16.11; diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c index b7be6aa..ce19b9a 100644 --- a/lib/librte_eal/common/eal_common_pci.c +++ b/lib/librte_eal/common/eal_common_pci.c @@ -71,6 +71,7 @@ #include #include +#include #include #include #include @@ -82,11 +83,6 @@ #include "eal_private.h" -struct pci_driver_list pci_driver_list = - TAILQ_HEAD_INITIALIZER(pci_driver_list); -struct pci_device_list pci_device_list = - TAILQ_HEAD_INITIALIZER(pci_device_list); - #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices" const char *pci_get_sysfs_path(void) @@ -206,39 +202,10 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev) { int ret; - struct rte_driver *driver; - struct rte_device *device; - struct rte_pci_addr *loc; if ((dr == NULL) || (dev == NULL)) return -EINVAL; - driver = &dr->driver; - device = &dev->device; - loc = &dev->addr; - - RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", - loc->domain, loc->bus, loc->devid, loc->function, - dev->device.numa_node); - - /* no initialization when blacklisted, return without error */ - if (dev->device.devargs != NULL && - dev->device.devargs->type == - RTE_DEVTYPE_BLACKLISTED_PCI) { - RTE_LOG(INFO, EAL, " Device is blacklisted, not" - " initializing\n"); - return 1; - } - - /* The device is not blacklisted; Check if driver supports it */ - ret = rte_eal_pci_match(driver, device); - if (ret) { - /* Match of device and driver failed */ - RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n", - driver->name); - return 1; - } - RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id, dev->id.device_id, dr->driver.name); @@ -271,23 +238,11 @@ static int rte_eal_pci_detach_dev(struct rte_pci_driver *dr, struct rte_pci_device *dev) { - int ret; - struct rte_driver *driver = NULL; - struct rte_device *device; struct rte_pci_addr *loc; if ((dr == NULL) || (dev == NULL)) return -EINVAL; - driver = &(dr->driver); - device = &(dev->device); - - ret = rte_eal_pci_match(driver, device); - if (ret) { - /* Device and driver don't match */ - return 1; - } - loc = &dev->addr; RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", @@ -316,9 +271,9 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr, * failed, return 1 if no driver is found for this device. */ static int -pci_probe_all_drivers(struct rte_pci_device *dev) +pci_probe_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev) { - struct rte_pci_driver *dr = NULL; + struct rte_driver *r_dr = NULL; int rc = 0; if (dev == NULL) @@ -328,8 +283,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev) if (dev->driver != NULL) return 0; - TAILQ_FOREACH(dr, &pci_driver_list, next) { - rc = rte_eal_pci_probe_one_driver(dr, dev); + TAILQ_FOREACH(r_dr, &bus->driver_list, next) { + rc = rte_eal_pci_probe(r_dr, &dev->device); if (rc < 0) /* negative value is an error */ return -1; @@ -347,15 +302,17 @@ pci_probe_all_drivers(struct rte_pci_device *dev) * failed, return 1 if no driver is found for this device. */ static int -pci_detach_all_drivers(struct rte_pci_device *dev) +pci_detach_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev) { struct rte_pci_driver *dr = NULL; + struct rte_driver *r_dr = NULL; int rc = 0; if (dev == NULL) return -1; - TAILQ_FOREACH(dr, &pci_driver_list, next) { + TAILQ_FOREACH(r_dr, &bus->driver_list, next) { + dr = container_of(r_dr, struct rte_pci_driver, driver); rc = rte_eal_pci_detach_dev(dr, dev); if (rc < 0) /* negative value is an error */ @@ -376,22 +333,31 @@ int rte_eal_pci_probe_one(const struct rte_pci_addr *addr) { struct rte_pci_device *dev = NULL; + struct rte_device *r_dev = NULL; + struct rte_bus *bus; int ret = 0; if (addr == NULL) return -1; + bus = rte_eal_bus_get("pci"); + if (!bus) { + RTE_LOG(ERR, EAL, "PCI Bus not registered\n"); + return -1; + } + /* update current pci device in global list, kernel bindings might have * changed since last time we looked at it. */ - if (pci_update_device(addr) < 0) + if (pci_update_device(bus, addr) < 0) goto err_return; - TAILQ_FOREACH(dev, &pci_device_list, next) { + TAILQ_FOREACH(r_dev, &bus->device_list, next) { + dev = container_of(r_dev, struct rte_pci_device, device); if (rte_eal_compare_pci_addr(&dev->addr, addr)) continue; - ret = pci_probe_all_drivers(dev); + ret = pci_probe_all_drivers(bus, dev); if (ret) goto err_return; return 0; @@ -412,20 +378,29 @@ int rte_eal_pci_detach(const struct rte_pci_addr *addr) { struct rte_pci_device *dev = NULL; + struct rte_device *r_dev = NULL; + struct rte_bus *bus; int ret = 0; if (addr == NULL) return -1; - TAILQ_FOREACH(dev, &pci_device_list, next) { + bus = rte_eal_bus_get("pci"); + if (!bus) { + RTE_LOG(ERR, EAL, "PCI Bus is not registered\n"); + return -1; + } + + TAILQ_FOREACH(r_dev, &bus->device_list, next) { + dev = container_of(r_dev, struct rte_pci_device, device); if (rte_eal_compare_pci_addr(&dev->addr, addr)) continue; - ret = pci_detach_all_drivers(dev); + ret = pci_detach_all_drivers(bus, dev); if (ret < 0) goto err_return; - TAILQ_REMOVE(&pci_device_list, dev, next); + rte_eal_bus_remove_device(r_dev); free(dev); return 0; } @@ -438,41 +413,73 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr) return -1; } -/* - * Scan the content of the PCI bus, and call the probe() function for - * all registered drivers that have a matching entry in its id_table - * for discovered devices. - */ int -rte_eal_pci_probe(void) +rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device) { - struct rte_pci_device *dev = NULL; - struct rte_devargs *devargs; - int probe_all = 0; int ret = 0; + struct rte_devargs *devargs; + struct rte_pci_device *pci_dev; + struct rte_pci_driver *pci_drv; + struct rte_pci_addr *loc; - if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0) - probe_all = 1; + if (!driver || !device) + return -1; - TAILQ_FOREACH(dev, &pci_device_list, next) { + pci_dev = container_of(device, struct rte_pci_device, device); + pci_drv = container_of(driver, struct rte_pci_driver, driver); - /* set devargs in PCI structure */ - devargs = pci_devargs_lookup(dev); - if (devargs != NULL) - dev->device.devargs = devargs; + loc = &pci_dev->addr; - /* probe all or only whitelisted devices */ - if (probe_all) - ret = pci_probe_all_drivers(dev); - else if (devargs != NULL && - devargs->type == RTE_DEVTYPE_WHITELISTED_PCI) - ret = pci_probe_all_drivers(dev); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT - " cannot be used\n", dev->addr.domain, dev->addr.bus, - dev->addr.devid, dev->addr.function); + RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", + loc->domain, loc->bus, loc->devid, loc->function, + pci_dev->device.numa_node); + + /* Fetch the devargs associated with the device */ + devargs = pci_devargs_lookup(pci_dev); + if (devargs != NULL) + pci_dev->device.devargs = devargs; + + /* no initialization when blacklisted, return without error */ + if (pci_dev->device.devargs != NULL && + pci_dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) { + RTE_LOG(INFO, EAL, " Device is blacklisted, not" + " initializing\n"); + return 1; } + ret = rte_eal_pci_probe_one_driver(pci_drv, pci_dev); + if (ret < 0) { + RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT + " cannot be used\n", pci_dev->addr.domain, + pci_dev->addr.bus, pci_dev->addr.devid, + pci_dev->addr.function); + return ret; + } + return 0; +} + +int +rte_eal_pci_remove(struct rte_device *device) +{ + int ret = 0; + struct rte_pci_device *pci_dev; + + if (!device) + return -1; + + pci_dev = container_of(device, struct rte_pci_device, device); + + if (!pci_dev->driver) + return -1; + + ret = rte_eal_pci_detach_dev(pci_dev->driver, pci_dev); + if (ret < 0) { + RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT + " cannot be used\n", pci_dev->addr.domain, + pci_dev->addr.bus, pci_dev->addr.devid, + pci_dev->addr.function); + return ret; + } return 0; } @@ -501,8 +508,17 @@ void rte_eal_pci_dump(FILE *f) { struct rte_pci_device *dev = NULL; + struct rte_device *r_dev = NULL; + struct rte_bus *bus; - TAILQ_FOREACH(dev, &pci_device_list, next) { + bus = rte_eal_bus_get("pci"); + if (!bus) { + RTE_LOG(ERR, EAL, "PCI Bus not registered\n"); + return; + } + + TAILQ_FOREACH(r_dev, &bus->device_list, next) { + dev = container_of(r_dev, struct rte_pci_device, device); pci_dump_one_device(f, dev); } } @@ -511,14 +527,32 @@ rte_eal_pci_dump(FILE *f) void rte_eal_pci_register(struct rte_pci_driver *driver) { - TAILQ_INSERT_TAIL(&pci_driver_list, driver, next); - rte_eal_driver_register(&driver->driver); + struct rte_bus *bus; + + RTE_VERIFY(driver); + + bus = rte_eal_bus_get("pci"); + if (!bus) { + RTE_LOG(ERR, EAL, "PCI Bus not registered\n"); + return; + } + + rte_eal_bus_add_driver(bus, &driver->driver); } /* unregister a driver */ void rte_eal_pci_unregister(struct rte_pci_driver *driver) { - rte_eal_driver_unregister(&driver->driver); - TAILQ_REMOVE(&pci_driver_list, driver, next); + struct rte_bus *bus; + + RTE_VERIFY(driver); + + bus = driver->driver.bus; + if (!bus) { + RTE_LOG(ERR, EAL, "PCI Bus not registered\n"); + return; + } + + rte_eal_bus_remove_driver(&driver->driver); } diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h index 9e7d8f6..06ec172 100644 --- a/lib/librte_eal/common/eal_private.h +++ b/lib/librte_eal/common/eal_private.h @@ -108,16 +108,6 @@ int rte_eal_timer_init(void); */ int rte_eal_log_init(const char *id, int facility); -/** - * Init the PCI infrastructure - * - * This function is private to EAL. - * - * @return - * 0 on success, negative on error - */ -int rte_eal_pci_init(void); - struct rte_pci_driver; struct rte_pci_device; @@ -126,13 +116,15 @@ struct rte_pci_device; * * This function is private to EAL. * + * @param bus + * The PCI bus on which device is connected * @param addr * The PCI Bus-Device-Function address to look for * @return * - 0 on success. * - negative on error. */ -int pci_update_device(const struct rte_pci_addr *addr); +int pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr); /** * Unbind kernel driver for this device diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index e5e58dd..1647672 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -86,12 +86,6 @@ extern "C" { #include #include -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. */ - -extern struct pci_driver_list pci_driver_list; /**< Global list of PCI drivers. */ -extern struct pci_device_list pci_device_list; /**< Global list of PCI devices. */ - /** Pathname of PCI devices directory. */ const char *pci_get_sysfs_path(void); @@ -376,6 +370,40 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr, int rte_eal_pci_scan(struct rte_bus *bus); /** + * Probe callback for the PCI bus + * + * For each matched pair of PCI device and driver on PCI bus, perform devargs + * check, and call a series of callbacks to allocate ethdev/cryptodev instances + * and intializing them. + * + * @param driver + * Generic driver object matched with the device + * @param device + * Generic device object to initialize + * @return + * - 0 on success. + * - !0 on error. + */ +int +rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device); + +/** + * Remove callback for the PCI bus + * + * Called when a device needs to be removed from a bus; wraps around the + * PCI specific implementation layered over rte_pci_driver->remove. Default + * handler used by PCI PMDs + * + * @param device + * rte_device object referring to device to be removed + * @return + * - 0 for successful removal + * - !0 for failure in removal of device + */ +int +rte_eal_pci_remove(struct rte_device *device); + +/** * Match the PCI Driver and Device using the ID Table * * @param drv @@ -390,19 +418,6 @@ int rte_eal_pci_match(struct rte_driver *drv, struct rte_device *dev); /** - * Probe the PCI bus for registered drivers. - * - * Scan the content of the PCI bus, and call the probe() function for - * all registered drivers that have a matching entry in its id_table - * for discovered devices. - * - * @return - * - 0 on success. - * - Negative on error. - */ -int rte_eal_pci_probe(void); - -/** * Map the PCI device resources in user space virtual memory address * * Note that driver should not call this function when flag diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 1a17891..2a20e90 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -803,9 +803,6 @@ rte_eal_init(int argc, char **argv) if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) rte_panic("Cannot init logs\n"); - if (rte_eal_pci_init() < 0) - rte_panic("Cannot init PCI\n"); - #ifdef VFIO_PRESENT if (rte_eal_vfio_setup() < 0) rte_panic("Cannot init VFIO\n"); @@ -884,10 +881,7 @@ rte_eal_init(int argc, char **argv) rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER); rte_eal_mp_wait_lcore(); - /* Probe & Initialize PCI devices */ - if (rte_eal_pci_probe()) - rte_panic("Cannot probe PCI\n"); - + /* Probe all the buses and devices/drivers on them */ if (rte_eal_bus_probe()) rte_panic("Cannot probe devices\n"); diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index 4a0207d..314effa 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -228,7 +229,8 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev) /* Scan one pci sysfs entry, and fill the devices list from it. */ static int -pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) +pci_scan_one(struct rte_bus *bus, const char *dirname, + const struct rte_pci_addr *addr) { char filename[PATH_MAX]; unsigned long tmp; @@ -346,21 +348,23 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) dev->kdrv = RTE_KDRV_NONE; /* device is valid, add in list (sorted) */ - if (TAILQ_EMPTY(&pci_device_list)) { - rte_eal_device_insert(&dev->device); - TAILQ_INSERT_TAIL(&pci_device_list, dev, next); + if (TAILQ_EMPTY(&bus->device_list)) { + rte_eal_bus_add_device(bus, &dev->device); } else { struct rte_pci_device *dev2; + struct rte_device *r_dev2; int ret; - TAILQ_FOREACH(dev2, &pci_device_list, next) { + TAILQ_FOREACH(r_dev2, &bus->device_list, next) { + dev2 = container_of(r_dev2, struct rte_pci_device, + device); ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr); if (ret > 0) continue; if (ret < 0) { - TAILQ_INSERT_BEFORE(dev2, dev, next); - rte_eal_device_insert(&dev->device); + rte_eal_bus_insert_device(bus, &dev2->device, + &dev->device); } else { /* already registered */ dev2->kdrv = dev->kdrv; dev2->max_vfs = dev->max_vfs; @@ -370,15 +374,14 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr) } return 0; } - rte_eal_device_insert(&dev->device); - TAILQ_INSERT_TAIL(&pci_device_list, dev, next); + rte_eal_bus_add_device(bus, &dev->device); } return 0; } int -pci_update_device(const struct rte_pci_addr *addr) +pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr) { char filename[PATH_MAX]; @@ -386,7 +389,7 @@ pci_update_device(const struct rte_pci_addr *addr) pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid, addr->function); - return pci_scan_one(filename, addr); + return pci_scan_one(bus, filename, addr); } /* @@ -440,13 +443,22 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr) * list */ int -rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused) +rte_eal_pci_scan(struct rte_bus *bus_p) { struct dirent *e; DIR *dir; char dirname[PATH_MAX]; struct rte_pci_addr addr; + if (!bus_p) { + RTE_LOG(ERR, EAL, "PCI Bus is not registered\n"); + return -1; + } + + /* for debug purposes, PCI can be disabled */ + if (internal_config.no_pci) + return 0; + dir = opendir(pci_get_sysfs_path()); if (dir == NULL) { RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n", @@ -465,7 +477,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused) snprintf(dirname, sizeof(dirname), "%s/%s", pci_get_sysfs_path(), e->d_name); - if (pci_scan_one(dirname, &addr) < 0) + if (pci_scan_one(bus_p, dirname, &addr) < 0) goto error; } closedir(dir); @@ -711,18 +723,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p) return ret; } -/* Init the PCI EAL subsystem */ -int -rte_eal_pci_init(void) -{ - /* for debug purposes, PCI can be disabled */ - if (internal_config.no_pci) - return 0; - - if (rte_eal_pci_scan(NULL) < 0) { - RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__); - return -1; - } +struct rte_bus pci_bus = { + .scan = rte_eal_pci_scan, + .match = rte_eal_pci_match, +}; - return 0; -} +RTE_REGISTER_BUS(pci, pci_bus); diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index abfe93e..239f2fc 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -6,8 +6,6 @@ DPDK_2.0 { eal_parse_sysfs_value; eal_timer_source; lcore_config; - pci_device_list; - pci_driver_list; per_lcore__lcore_id; per_lcore__rte_errno; rte_calloc; @@ -41,7 +39,6 @@ DPDK_2.0 { rte_eal_mp_wait_lcore; rte_eal_parse_devargs_str; rte_eal_pci_dump; - rte_eal_pci_probe; rte_eal_pci_probe_one; rte_eal_pci_register; rte_eal_pci_scan; @@ -192,5 +189,9 @@ DPDK_17.02 { rte_eal_bus_remove_device; rte_eal_bus_remove_driver; rte_eal_bus_unregister; + rte_eal_pci_match; + rte_eal_pci_probe; + rte_eal_pci_remove; + rte_eal_pci_scan; } DPDK_16.11; -- 2.7.4