get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/17057/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 17057,
    "url": "http://patches.dpdk.org/api/patches/17057/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1479360605-20558-5-git-send-email-shreyansh.jain@nxp.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1479360605-20558-5-git-send-email-shreyansh.jain@nxp.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1479360605-20558-5-git-send-email-shreyansh.jain@nxp.com",
    "date": "2016-11-17T05:30:03",
    "name": "[dpdk-dev,RFC,4/6] eal/common: handle bus abstraction for device/driver objects",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "600c0d0e2578457e73bcec862c6269f092de4a12",
    "submitter": {
        "id": 497,
        "url": "http://patches.dpdk.org/api/people/497/?format=api",
        "name": "Shreyansh Jain",
        "email": "shreyansh.jain@nxp.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1479360605-20558-5-git-send-email-shreyansh.jain@nxp.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/17057/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/17057/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id CF93558CF;\n\tThu, 17 Nov 2016 06:29:12 +0100 (CET)",
            "from NAM03-CO1-obe.outbound.protection.outlook.com\n\t(mail-co1nam03on0058.outbound.protection.outlook.com [104.47.40.58])\n\tby dpdk.org (Postfix) with ESMTP id B443B558B\n\tfor <dev@dpdk.org>; Thu, 17 Nov 2016 06:28:15 +0100 (CET)",
            "from BY2PR03CA069.namprd03.prod.outlook.com (10.141.249.42) by\n\tCY4PR03MB2472.namprd03.prod.outlook.com (10.168.165.8) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id\n\t15.1.707.6; Thu, 17 Nov 2016 05:28:13 +0000",
            "from BN1AFFO11FD006.protection.gbl (2a01:111:f400:7c10::130) by\n\tBY2PR03CA069.outlook.office365.com (2a01:111:e400:2c5d::42) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.707.6 via\n\tFrontend Transport; Thu, 17 Nov 2016 05:28:12 +0000",
            "from tx30smr01.am.freescale.net (192.88.168.50) by\n\tBN1AFFO11FD006.mail.protection.outlook.com (10.58.52.66) with\n\tMicrosoft SMTP Server (version=TLS1_0,\n\tcipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.721.5\n\tvia Frontend Transport; Thu, 17 Nov 2016 05:28:12 +0000",
            "from Tophie.ap.freescale.net ([10.232.14.87])\n\tby tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id\n\tuAH5S1pt018741; Wed, 16 Nov 2016 22:28:10 -0700"
        ],
        "Authentication-Results": "spf=fail (sender IP is 192.88.168.50)\n\tsmtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed)\n\theader.d=none; nxp.com; dmarc=fail action=none header.from=nxp.com;\n\tnxp.com; \n\tdkim=none (message not signed) header.d=none;",
        "Received-SPF": "Fail (protection.outlook.com: domain of nxp.com does not\n\tdesignate 192.88.168.50 as permitted sender)\n\treceiver=protection.outlook.com; \n\tclient-ip=192.88.168.50; helo=tx30smr01.am.freescale.net;",
        "X-IncomingTopHeaderMarker": "OriginalChecksum:; UpperCasedChecksum:;\n\tSizeAsReceived:682; Count:10",
        "From": "Shreyansh Jain <shreyansh.jain@nxp.com>",
        "To": "<david.marchand@6wind.com>",
        "CC": "<dev@dpdk.org>, Shreyansh Jain <shreyansh.jain@nxp.com>",
        "Date": "Thu, 17 Nov 2016 11:00:03 +0530",
        "Message-ID": "<1479360605-20558-5-git-send-email-shreyansh.jain@nxp.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1479360605-20558-1-git-send-email-shreyansh.jain@nxp.com>",
        "References": "<1479360605-20558-1-git-send-email-shreyansh.jain@nxp.com>",
        "X-IncomingHeaderCount": "10",
        "X-EOPAttributedMessage": "0",
        "X-Matching-Connectors": "131238340927004812;\n\t(91ab9b29-cfa4-454e-5278-08d120cd25b8); ()",
        "X-Forefront-Antispam-Report": "CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI;\n\tSFV:NSPM;\n\tSFS:(10009020)(6009001)(7916002)(2980300002)(1110001)(1109001)(336004)(339900001)(199003)(189002)(189998001)(50986999)(110136003)(106466001)(105606002)(87936001)(50226002)(8936002)(85426001)(68736007)(97736004)(2351001)(76176999)(81166006)(6666003)(5660300001)(6916009)(8676002)(5003940100001)(356003)(36756003)(33646002)(4326007)(305945005)(2906002)(48376002)(92566002)(7846002)(8666005)(626004)(2950100002)(81156014)(77096005)(47776003)(104016004)(50466002)(86362001)(7059030)(21314002)(217873001);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR03MB2472;\n\tH:tx30smr01.am.freescale.net; \n\tFPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; ",
        "X-Microsoft-Exchange-Diagnostics": [
            "1; BN1AFFO11FD006;\n\t1:eaOzfdW3MSz5WMYj/l0XEnUnADSfouIXgzXpVc4O9sjyxvanD4uxeSo0Rw7ETdUcgjlneDlwV62qZr1BXlznqaLgHuJyDG3A+ef70xF1aRUMjTu19t3yb+j9ilhv5mdM8MusswL0NdMz0lfCfI3ScbZRYotAQ1kPueMTezTL+6DtOF3qbgQZfJN3qX+AAB47AA48GrJamfhiOsxDU9oElMPISR5A/K+a20mT1FUeLuqjDQi3/0irpeOvHJRaROreuKO92ZRvGvresZeh7e8do89oXdj8j5XtUn+HVmvFOa3CfL0enHCxuOEa+FIOEvkTaDfxHwTXybomuH31Ht0H1QDuUG1Jpato/yzonb3gU9sykVQCbJpy1FFVnGwyrNqC+44AkULn3W8svTFjcj9HFWwiy/gIWCLXzOcyW7oPj+kT6BJHQ3Y4xv5blOvCjqVCwnGB4Q/H4GInyW+dWGlH6Pt6lCyJGZtPGOJemSH4xfCqHh6kS9ZVIqGa+Xa0+QKiPnj5que4f1sHqeSN307exKVwRVzT2QiJjoEtIP9ScEa74PajSFt/z54leaG3WSlaFwAMbv/EFqUItIINdK2WIiTaY+7JZEhg8askbhUYpHxY9R/3E0yE4hy1YV5XrJDPkaNwLQ1MEj8y4pYAfj8wHCuy65r9OP7/Drm5xq99aTO8dw5x51xTIn9jqhZiDQ8ffqak9IRS4/LCdaVfzRmmf1ABjm+BkWWOmg7plYru4Po=",
            "1; CY4PR03MB2472;\n\t2:ZGleAwPSvlRBp6BUMMi9P3f+pmyp16eo+CkoXw4mtGJmc4CjjPTjIYa0bbwChjT3glxfMQNO5ToEQWQ++GRtZcBpCT/StgBl+HN1cJlarzENNkYtA6r2jDnzRlhjANxeGbSdn1F8MxAPE4I+4BTVx3scqvVIrtIRJl0yVoor0Xo=;\n\t3:lFOSaPxBluxv9DORrFanIi39Wa4XUScwoa7vPFkESDneptprhBoPF152QA40sU3qlEU29p5SGvwj5vA91MBIizoQRM1/kQhN+Wb1GZBRpx7DbarLX7HX1W6f94wfm6y6FiDBexua4gF+c1FRs+9d24GAbBAzD+XEfSwdHXor1gtpO0TGF3U51yIGs3Y4qi24bg8NCheAZHv2OjbBE+WMOfC+wi8ti3abbPo0QfYb+QATmL+d2MewDrHOec8m+u7u4YNLjr0ATwpHYimwVC+K6A==;\n\t25:mL5/6TDuNfGJPEqqOrEvZF3Enq51dDJXn2HwNKC39mZw8tJQyeEQcIC+l3Ga3N42ICU9DSnXFr3yTeIGt9BVzlN1P2QrmRPZm8m8PSRb33mh88Fe1wMjkREWtDUz7undFv6QHRtavaGlLL4aQ6Tgv4AFsH4F1PhLD7alpXamjh7waOPHRg7HXnZbgWx4DFoEltjCVuGW/PjFoqQbUcpAVtmRmNyicDGq94Hee1DqJqoB+GpOvejciFC8IP5uvR1piG28vPhKj2L3GeBieBurI6jzjj8rjf0iVTmUW16uWur87dPa7jR3rVN+fvzkawQWxCStDJ6CgbvKghR5u1HPdrqJy5Zibujl7HeYeuMn65kCohmxU7G/9H0qUA7QvjLWkMVooTUrfJPRhFFfHaUM/rL9rnHz9ojjG+9PAsEBCxvcAsUtr3luFXtAj6tW5yj3CGUADF5yRs9lo4sjxGetEQ==",
            "1; CY4PR03MB2472;\n\t31:RfZSbmpm5i7kRE+4wNLQbYHzVXyJS7NQkCwYMH1DverqJcY2mJGzbfTFJtBWAVt6dqaIKriwvxcXFMNBh85b/rXo/Ws+GdQVW76xw1Vqm+GcwZGd/eT/fQ5VoL6vewhbEG3EMvgubySq+A4jZtB8EtWIGI6Y/LzLCvfx574VdT2sdFX5Vfjq07pWtUS/ToVzX7xyEUwuxHFxS4QBAfCgMnhAFn3o2gdQ2Sn69JonAV2I7MxvbnHRdpJuX9EajQUB3TOhZBpTalCytOk8Oncn+Q==;\n\t4:aPh8okXjZykxUFEdjRma+M0f4nd5l16LbpZw4Gy+78OpunQ9e1/NlLBdvqtB8NSMsR/kcBqB0YdHg6sAXdenSFhJamu3XxSwLX6bFkvMFt82CFvAFTolDkKA0tpMz8r3acxFPGmI773WzYuTncYZMsBwRS/ZkjW0hhKY6SEE8qMmXBW4daFNGWAkQYhAYSioqJCFizlLVvADPUwxtYWjVuT4WOt/kQjFcJ93XE9R9gMn1Fw5qf56uLEMVKqbY8zPkskoTwuGjvBxCjMOkzVwwfItmX+LA+T/I/EiX/iSVq/oIyBI3iJvDC/oEWPijLjxzKCGtQFKxDSUMqkolWoG1txi69W1HxGwKrniuAq4ZmwGOyB5AqsBc/j/SBbZD99rvdzz1NBy3NVkyq5/SnuUJ8EfsmG74fuo8mGaPeEQagbR+ZPKN0a/mTzI87EaqvhLtJ04J9HZTOKc7eIMWhZn+0yB135/nB5y0HdjLR2DgZiBv7RdcXbIUDg1kwHCR8wC8TqUsMo7/52EQmjnSI+uHQYu+E+IC46aSZ+7dMl7jIeJW6K2JHzpOLS5SN3dG0oPbbiZ2JuX42HRqDlm0Jl8Hg==",
            "=?us-ascii?Q?1; CY4PR03MB2472;\n\t23:YVBjRbWPgYpaZY74oZ5oKtlBF7k6jpFWggCOT24bU?=\n\t=?us-ascii?Q?te7beZKOGsAlMHcUcHu3w0OtYZt/FNLG+nCkzH17fndqW6DS33CrUS7x0Uzc?=\n\t=?us-ascii?Q?VqpvtwBz0GZuJiR6/CoqtLuEScCX6LHFZjv308Osr8eASYMFuV4WioHU/W6D?=\n\t=?us-ascii?Q?ArG1fv31xNlH5zQ8wwUACkjeTMDxM2Zt50qZk1JYjK04b1cGA65HYsT9cj5t?=\n\t=?us-ascii?Q?B5TAj2QlBxgPDxprxIMYIAROateK/4s2OOnbVc17yyC1kyTz2VtC7QGJe0JM?=\n\t=?us-ascii?Q?KfwV4XuNDGmeIOiL/2Ff0T66N8tVXckYKoPhdiTQzhyLLoVD3GAgbYkZ9OWO?=\n\t=?us-ascii?Q?DDGW19hJ7BCP+nQV6diJTIQnEqd9+IcTQDgtSl72BP0HvS0+uZLPdal+m2fQ?=\n\t=?us-ascii?Q?94VRJzu18BCDHKqpV/zGTZXGPHZR1Z5g1tslJ6YNDCqIfzeI9cKQvZ66aRG4?=\n\t=?us-ascii?Q?1EnoB7EE5wepcKGre7shn0KL62yp+GW3ohwSo8bwWKg/ZZYiio6gIISzhsEs?=\n\t=?us-ascii?Q?eYRi1W4A/K14a7XbXLMcN8aZb6kSGsiuDYqMAbXHq8z0vGffZXmuOLfoYq3q?=\n\t=?us-ascii?Q?VSFOV9JD4V60m7dsTbee2yUBz0CNDra5Amm4QvwELxZ6FeDB/6nvtdq3Mzfs?=\n\t=?us-ascii?Q?r1h2eiMSsKyl+mYOznP/PPhk6AvHPXRdPOkAI7xhgrbLcvlta0PVxETrabua?=\n\t=?us-ascii?Q?VKi5B1DT/Zkd4lNL3cuszyAYm7VycDRhsqpc5A3gzoOJllQYByrd6BROwV5g?=\n\t=?us-ascii?Q?ny35h+uzu/yD1fmUyOQ8EqQrE9YijW3gMHHHOK7REKxk7JN/V79w9s4bM37H?=\n\t=?us-ascii?Q?/yTPtUSGd+ablqUrn5C2YJOvhK+uWoWvljwqHi6luprLl+bXJZvolQpHZtYf?=\n\t=?us-ascii?Q?KA3ZkPbpNg3RrbJPWZmHv6id/DMKq8nRTQn9LZsbdDRELWzngMRXVOx+oznE?=\n\t=?us-ascii?Q?0ntkQOOS0EPtRCjGobzdPbXkztDEbiZl7VGe4XDMh1QrgQe8ZYQu8STc/h4B?=\n\t=?us-ascii?Q?AAO9+sertMsakztZG7V8fGhgewbJ/o+6FlWe1ZxuXwaAkXNruqyufyrrcX7a?=\n\t=?us-ascii?Q?/QnlfxKAR9SXQZMn9pQ4A/OM5VkVOSeVYM9FHKXQVuDs7f195KPgnO6RAlUR?=\n\t=?us-ascii?Q?2PBvN1Rc8iTYRgUATVLyqBwKX6SzEjXx/XlUAOqmCkEt6lHG7oYAQ=3D=3D?=",
            "1; CY4PR03MB2472;\n\t6:CgiNolzcrYdMsaofcnyar9JrKUiaQXnqT74WcNmTaDMSltW2nESslQae2wJIGbLcGAIVdIM+nKvTvlE3NCtcuGHSaaleoBaP+BtSNySMuJqsjW1+VZ4jP40fRQ/6Jx/s4o3FmgB1/f23Ag/vX0rkUbv4+ceHRi5+mxNQaB/Nf21e0kQ0WH61rlMiSYSQGL3mr6spOWGEQQ+cAFVII9vFp1tpEaPrLPSU0vB4kaEEZppIshtNOXtExwRcPCzvWq17d3RGxGoSF/S7yEreK/IDQuRj2hZ5EA2bQJO4Ok1FAk8erxz87p5w4zv4N7K9yskh9JKRLZaOZ+Vwa59iM/0r7g==;\n\t5:B10OqI3iulXBWD////clBzGrt0gEMv/pY6LQ6TT6dJrdTfDQ//Myqn/+9uvnMKqk4ZxrlodKhVSSCEf7UmBE7SPTy/mDbe7zZhv0rhu3UR/WGPowdzXbN2ZQf0uI8Z0T9LD6GSc2vHIh+qRAWs5cQessjFzmXk/4pILHEnEzsp+bNPfoisJdD9Nu//LILxz2;\n\t24:WrQdi9rt4FCoa0OYyqjtmfSnCcUN4t6Gk9MRudRckL1N8pjqnVMvDZ2tXaTNmXuDQgjx04vc49ZLrsr0n8BPGvGOixHAyLDQwjfWR1KVCu8=",
            "1; CY4PR03MB2472;\n\t7:tdaAwisT2n0aNssCS3bFwvBLLjd1hF8+Dp+/wg52ptq8uFQSyNoh/4cebngRBdQ0iMqyQe854UXjoTJ+u0VCgI9lE1Kmig3CgF3ZOm06ikfnLx34OuAlnM8sFj6pkBGTRtOwO0Q9Ld94fbpPViUvN5f3DH1cKx7BLVAdDSBxKt4TLGH/A8rF7WiNOScSM5tU0vDKakfTDb/iAzxggvJy/ktitXBI8BZ0uyUuVEb8JK09So/WbmxUtN4LOEKXi4J6kauZrWYpU0BX0KZhYjzz1xclsatXEZ0VvnJfMS7vUcuVxlY7ApxwwRrW1vbtH/Re58leZFJtlTzR1uJf2BPAFH4gJ6yyogK7qq5pZ79jVG4="
        ],
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-MS-Office365-Filtering-Correlation-Id": "86ec2f1a-b219-40b8-3f2b-08d40eaa8652",
        "X-Microsoft-Antispam": "UriScan:; BCL:0; PCL:0; RULEID:(22001);\n\tSRVR:CY4PR03MB2472; ",
        "X-Microsoft-Antispam-PRVS": "<CY4PR03MB24723A1739C7B6046B6B2B7690B10@CY4PR03MB2472.namprd03.prod.outlook.com>",
        "X-Exchange-Antispam-Report-Test": "UriScan:(185117386973197);",
        "X-Exchange-Antispam-Report-CFA-Test": "BCL:0; PCL:0;\n\tRULEID:(6095035)(601004)(2401047)(13023025)(13015025)(13024025)(5005006)(13018025)(8121501046)(13017025)(3002001)(10201501046)(6055026)(6096035);\n\tSRVR:CY4PR03MB2472; BCL:0; PCL:0; RULEID:(400006); SRVR:CY4PR03MB2472;",
        "X-Forefront-PRVS": "01294F875B",
        "SpamDiagnosticOutput": "1:99",
        "SpamDiagnosticMetadata": "NSPM",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "17 Nov 2016 05:28:12.5132\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-Id": "5afe0b00-7697-4969-b663-5eab37d5f47e",
        "X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp": "TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e;\n\tIp=[192.88.168.50]; \n\tHelo=[tx30smr01.am.freescale.net]",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "HybridOnPrem",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "CY4PR03MB2472",
        "Subject": "[dpdk-dev] [RFC PATCH 4/6] eal/common: handle bus abstraction for\n\tdevice/driver objects",
        "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>,\n\t<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>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Primary changes done by this patch are based on:\n - Devices belong to the bus hence the device list is bus instance\n   specific\n - Similarly, drivers belong to the bus and thus they too are enclosed\n   within the bus instance.\n - All device insertion and driver registration should proceed through\n   bus APIs. A new file, eal_common_bus.c has been added for that.\n\nExiting driver registration and device insert/remove APIs have been\nmodified to work with bus on which device/driver belong. On the same\nlines, the PCI common functions have been modified to work with bus rather\nthan device/driver directly.\n\nrte_eal_pci_scan is no longer an exposed API. It is part of the bus\nimplementation. Though, probe continues to be part of the common PCI\noperations.\n\nProbe has been split into match and probe. Match has been moved to bus/*\ncode and is a hook now. EAL code would be modified to handle this hook.\n\nMissing/Grey area:\n - Some API like inserting a device at a particular position in the device\n   list are missing. Same for driver. These are needed for cases where\n   device update is done rather than addition.\n - Probe is a property of a driver but it should be initiated from a bus,\n   for example when added a new device (hotplugging). At present\n   rte_driver has the probe hook. This should be wrapped around some API\n   at the bus level so that bus can search through multiple drivers\n   associated with it for calling probe.\n\nSigned-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>\n---\n lib/librte_eal/common/eal_common_bus.c  | 188 ++++++++++++++++++++++++++\n lib/librte_eal/common/eal_common_dev.c  |  31 +++--\n lib/librte_eal/common/eal_common_pci.c  | 226 +++++++++++++++++++-------------\n lib/librte_eal/common/include/rte_pci.h |  11 +-\n 4 files changed, 342 insertions(+), 114 deletions(-)\n create mode 100644 lib/librte_eal/common/eal_common_bus.c",
    "diff": "diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c\nnew file mode 100644\nindex 0000000..3de1ac7\n--- /dev/null\n+++ b/lib/librte_eal/common/eal_common_bus.c\n@@ -0,0 +1,188 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2016 NXP\n+ *   All rights reserved.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of NXP nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <stdio.h>\n+#include <string.h>\n+#include <inttypes.h>\n+#include <sys/queue.h>\n+\n+#include <rte_dev.h>\n+#include <rte_devargs.h>\n+#include <rte_debug.h>\n+#include <rte_devargs.h>\n+#include <rte_log.h>\n+\n+#include \"eal_private.h\"\n+\n+/** @internal\n+ * Add a device to a bus.\n+ */\n+void\n+rte_eal_bus_add_device(struct rte_bus *bus, struct rte_device *dev)\n+{\n+\t/* XXX all the additions can be address ordered ?\n+\t * for example, calling rte_eal_compare_pci_addr and getting <=\n+\t * and performing insert a specific location\n+\t */\n+\tRTE_VERIFY(bus);\n+\tRTE_VERIFY(dev);\n+\n+\tTAILQ_INSERT_TAIL(&bus->device_list, dev, next);\n+}\n+\n+/** @internal\n+ * Remove a device from its bus.\n+ */\n+void\n+rte_eal_bus_remove_device(struct rte_device *dev)\n+{\n+\tstruct rte_bus *bus;\n+\tRTE_VERIFY(bus);\n+\tRTE_VERIFY(dev);\n+\n+\tbus = dev->bus;\n+\tTAILQ_REMOVE(&bus->device_list, dev, next);\n+}\n+\n+/** @internal\n+ * Associate a driver with a bus.\n+ */\n+void\n+rte_eal_bus_add_driver(struct rte_bus *bus, struct rte_driver *drv)\n+{\n+\tRTE_VERIFY(bus);\n+\tRTE_VERIFY(drv);\n+\n+\tTAILQ_INSERT_TAIL(&bus->driver_list, drv, next);\n+}\n+\n+/** @internal\n+ * Disassociate a driver from bus.\n+ */\n+void\n+rte_eal_bus_remove_driver(struct rte_driver *drv)\n+{\n+\tstruct rte_bus *bus;\n+\tRTE_VERIFY(bus);\n+\tRTE_VERIFY(drv);\n+\n+\tbus = drv->bus;\n+\tTAILQ_REMOVE(&bus->driver_list, dev, next);\n+}\n+\n+/**\n+ * Scan all the associated buses\n+ */\n+int\n+rte_eal_bus_scan(void)\n+{\n+\tint ret = 0;\n+\tstruct rte_bus *bus;\n+\n+\tif (TAILQ_EMPTY(&rte_bus_list)) {\n+\t\treturn 0;\n+\t}\n+\n+\tTAILQ_FOREACH(bus, &rte_bus_list, next) {\n+\t\tret = bus->scan();\n+\t\tif (ret) {\n+\t\t\tRTE_LOG(ERR, EAL, \"Scan for [%s] bus failed.\\n\",\n+\t\t\t\tbus->name);\n+\t\t\tcontinue; /* not a reason to break other bus scan */\n+\t\t}\n+\t}\n+\n+\t/* This function essentially never returns an error - in case of error\n+\t * no devices (or limited devices) are available to the application\n+\t * which then can fail/report error.\n+\t */\n+\treturn 0;\n+}\n+\n+/**\n+ * Get the bus handle using its name\n+ */\n+struct rte_bus *\n+rte_eal_get_bus(const char *bus_name)\n+{\n+\tstruct rte_bus *bus;\n+\n+\tRTE_VERIFY(bus_name);\n+\n+\tTAILQ_FOREACH(bus, &rte_bus_list, next) {\n+\t\tRTE_VERIFY(bus->name);\n+\n+\t\tif (!strncmp(bus_name, bus->name)) {\n+\t\t\tRTE_LOG(DEBUG, EAL, \"Returning Bus object %p\\n\", bus);\n+\t\t\treturn bus;\n+\t\t}\n+\t}\n+\n+\t/* Unable to find bus requested */\n+\treturn NULL;\n+}\n+\n+/* register a bus */\n+void\n+rte_eal_bus_register(struct rte_bus *bus)\n+{\n+\t/* 3 conditions must meet:\n+\t * 1. scan hook should be defined.\n+\t * 2. match hook should be defined.\n+\t * 3. Name should be a valid string. (valid?)\n+\t */\n+\tRTE_VERIFY(bus);\n+\tRTE_VERIFY(bus->scan);\n+\tRTE_VERIFY(bus->probe);\n+\tRTE_VERIFY(bus->name && strlen(bus->name));\n+\n+\t/* Initialize the driver and device list associated with the bus */\n+\tTAILQ_HEAD_INITIALIZER(&(bus->driver_list));\n+\tTAILQ_HEAD_INITIALIZER(&(bus->device_list));\n+\n+\tTAILQ_INSERT_TAIL(&rte_bus_list, bus, next);\n+\tRTE_LOG(DEBUG, EAL, \"Registered [%s] bus.\\n\", bus->name);\n+}\n+\n+/* unregister a bus */\n+void\n+rte_eal_bus_unregister(struct rte_bus *bus)\n+{\n+\t/* All devices and drivers associated with the bus should have been\n+\t * 'device->uninit' and 'driver->remove()' already.\n+\t */\n+\tRTE_VERIFY(TAILQ_EMPTY(&(bus->driver_list)));\n+\tRTE_VERIFY(TAILQ_EMPTY(&(bus->device_list)));\n+\n+\tTAILQ_REMOVE(&rte_bus_list, bus, next);\n+}\ndiff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c\nindex 4f3b493..bb8d266 100644\n--- a/lib/librte_eal/common/eal_common_dev.c\n+++ b/lib/librte_eal/common/eal_common_dev.c\n@@ -45,35 +45,44 @@\n \n #include \"eal_private.h\"\n \n-/** Global list of device drivers. */\n-static struct rte_driver_list dev_driver_list =\n-\tTAILQ_HEAD_INITIALIZER(dev_driver_list);\n-/** Global list of device drivers. */\n-static struct rte_device_list dev_device_list =\n-\tTAILQ_HEAD_INITIALIZER(dev_device_list);\n-\n /* register a driver */\n void\n rte_eal_driver_register(struct rte_driver *driver)\n {\n-\tTAILQ_INSERT_TAIL(&dev_driver_list, driver, next);\n+\tstruct rte_bus *bus;\n+\n+\tRTE_VERIFY(driver && driver->bus);\n+\tbus = driver->bus;\n+\tTAILQ_INSERT_TAIL(&(bus->driver_list), driver, next);\n }\n \n /* unregister a driver */\n void\n rte_eal_driver_unregister(struct rte_driver *driver)\n {\n-\tTAILQ_REMOVE(&dev_driver_list, driver, next);\n+\tstruct rte_bus;\n+\n+\tRTE_VERIFY(driver && driver->bus);\n+\tbus = driver->bus;\n+\tTAILQ_REMOVE(&(bus->driver_list), driver, next);\n }\n \n void rte_eal_device_insert(struct rte_device *dev)\n {\n-\tTAILQ_INSERT_TAIL(&dev_device_list, dev, next);\n+\tstruct rte_bus *bus;\n+\n+\tRTE_VERIFY(dev && dev->bus);\n+\tbus = dev->bus;\n+\tTAILQ_INSERT_TAIL(&(bus->device_list), dev, next);\n }\n \n void rte_eal_device_remove(struct rte_device *dev)\n {\n-\tTAILQ_REMOVE(&dev_device_list, dev, next);\n+\tstruct rte_bus *bus;\n+\n+\tRTE_VERIFY(dev && dev->bus);\n+\tbus = dev->bus;\n+\tTAILQ_REMOVE(&(bus->device_list), dev, next);\n }\n \n int\ndiff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c\nindex 971ad20..7a6d258 100644\n--- a/lib/librte_eal/common/eal_common_pci.c\n+++ b/lib/librte_eal/common/eal_common_pci.c\n@@ -82,12 +82,13 @@\n \n #include \"eal_private.h\"\n \n-struct pci_driver_list pci_driver_list =\n-\tTAILQ_HEAD_INITIALIZER(pci_driver_list);\n-struct pci_device_list pci_device_list =\n-\tTAILQ_HEAD_INITIALIZER(pci_device_list);\n-\n #define SYSFS_PCI_DEVICES \"/sys/bus/pci/devices\"\n+#define PCI_BUS_NAME \"pci_bus\"\n+\n+static struct rte_bus_list pci_bus_list =\n+\tTAILQ_HEAD_INITIALIZER(pci_bus_list);\n+\n+struct rte_bus pci_bus;\n \n const char *pci_get_sysfs_path(void)\n {\n@@ -160,64 +161,40 @@ static int\n rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)\n {\n \tint ret;\n-\tconst struct rte_pci_id *id_table;\n-\n-\tfor (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {\n-\n-\t\t/* check if device's identifiers match the driver's ones */\n-\t\tif (id_table->vendor_id != dev->id.vendor_id &&\n-\t\t\t\tid_table->vendor_id != PCI_ANY_ID)\n-\t\t\tcontinue;\n-\t\tif (id_table->device_id != dev->id.device_id &&\n-\t\t\t\tid_table->device_id != PCI_ANY_ID)\n-\t\t\tcontinue;\n-\t\tif (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&\n-\t\t\t\tid_table->subsystem_vendor_id != PCI_ANY_ID)\n-\t\t\tcontinue;\n-\t\tif (id_table->subsystem_device_id != dev->id.subsystem_device_id &&\n-\t\t\t\tid_table->subsystem_device_id != PCI_ANY_ID)\n-\t\t\tcontinue;\n-\t\tif (id_table->class_id != dev->id.class_id &&\n-\t\t\t\tid_table->class_id != RTE_CLASS_ANY_ID)\n-\t\t\tcontinue;\n-\n-\t\tstruct rte_pci_addr *loc = &dev->addr;\n-\n-\t\tRTE_LOG(INFO, EAL, \"PCI device \"PCI_PRI_FMT\" on NUMA socket %i\\n\",\n-\t\t\t\tloc->domain, loc->bus, loc->devid, loc->function,\n-\t\t\t\tdev->device.numa_node);\n-\n-\t\t/* no initialization when blacklisted, return without error */\n-\t\tif (dev->device.devargs != NULL &&\n-\t\t\tdev->device.devargs->type ==\n-\t\t\t\tRTE_DEVTYPE_BLACKLISTED_PCI) {\n-\t\t\tRTE_LOG(INFO, EAL, \"  Device is blacklisted, not initializing\\n\");\n-\t\t\treturn 1;\n-\t\t}\n-\n-\t\tRTE_LOG(INFO, EAL, \"  probe driver: %x:%x %s\\n\", dev->id.vendor_id,\n-\t\t\t\tdev->id.device_id, dr->driver.name);\n+\tstruct rte_pci_addr *loc = &dev->addr;\n+\n+\tRTE_LOG(INFO, EAL, \"PCI device \"PCI_PRI_FMT\" on NUMA socket %i\\n\",\n+\t\t\tloc->domain, loc->bus, loc->devid, loc->function,\n+\t\t\tdev->device.numa_node);\n+\n+\t/* no initialization when blacklisted, return without error */\n+\tif (dev->device.devargs != NULL &&\n+\t\tdev->device.devargs->type ==\n+\t\t\tRTE_DEVTYPE_BLACKLISTED_PCI) {\n+\t\tRTE_LOG(INFO, EAL, \"  Device is blacklisted, not initializing\\n\");\n+\t\treturn 1;\n+\t}\n \n-\t\tif (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {\n-\t\t\t/* map resources for devices that use igb_uio */\n-\t\t\tret = rte_eal_pci_map_device(dev);\n-\t\t\tif (ret != 0)\n-\t\t\t\treturn ret;\n-\t\t} else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&\n-\t\t\t\trte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\t\t/* unbind current driver */\n-\t\t\tif (pci_unbind_kernel_driver(dev) < 0)\n-\t\t\t\treturn -1;\n-\t\t}\n+\tRTE_LOG(INFO, EAL, \"  probe driver: %x:%x %s\\n\", dev->id.vendor_id,\n+\t\t\tdev->id.device_id, dr->driver.name);\n+\n+\tif (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {\n+\t\t/* map resources for devices that use igb_uio */\n+\t\tret = rte_eal_pci_map_device(dev);\n+\t\tif (ret != 0)\n+\t\t\treturn ret;\n+\t} else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&\n+\t\t\trte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\t/* unbind current driver */\n+\t\tif (pci_unbind_kernel_driver(dev) < 0)\n+\t\t\treturn -1;\n+\t}\n \n-\t\t/* reference driver structure */\n-\t\tdev->driver = dr;\n+\t/* reference driver structure */\n+\tdev->driver = dr;\n \n-\t\t/* call the driver probe() function */\n-\t\treturn dr->probe(dr, dev);\n-\t}\n-\t/* return positive value if driver doesn't support this device */\n-\treturn 1;\n+\t/* call the driver probe() function */\n+\treturn dr->probe(dr, dev);\n }\n \n /*\n@@ -284,6 +261,7 @@ static int\n pci_probe_all_drivers(struct rte_pci_device *dev)\n {\n \tstruct rte_pci_driver *dr = NULL;\n+\tstruct rte_bus *pci_bus;\n \tint rc = 0;\n \n \tif (dev == NULL)\n@@ -293,15 +271,21 @@ pci_probe_all_drivers(struct rte_pci_device *dev)\n \tif (dev->driver != NULL)\n \t\treturn 0;\n \n-\tTAILQ_FOREACH(dr, &pci_driver_list, next) {\n-\t\trc = rte_eal_pci_probe_one_driver(dr, dev);\n-\t\tif (rc < 0)\n-\t\t\t/* negative value is an error */\n-\t\t\treturn -1;\n-\t\tif (rc > 0)\n-\t\t\t/* positive value means driver doesn't support it */\n-\t\t\tcontinue;\n-\t\treturn 0;\n+\tTAILQ_FOREACH(dr, &(pci_bus->driver_list), next) {\n+\t\trc = pci_bus->match(dr, dev);\n+\t\tif (!rc) {\n+\t\t\trc = rte_eal_pci_probe_one_driver(dr, dev);\n+\t\t\tif (rc < 0)\n+\t\t\t\t/* negative value is an error */\n+\t\t\t\treturn -1;\n+\t\t\tif (rc > 0)\n+\t\t\t\t/* positive value means driver doesn't support\n+\t\t\t\t * it\n+\t\t\t\t */\n+\t\t\t\tcontinue;\n+\t\t\treturn 0;\n+\t\t}\n+\t\t/* Else, continue to next driver */\n \t}\n \treturn 1;\n }\n@@ -314,13 +298,19 @@ pci_probe_all_drivers(struct rte_pci_device *dev)\n static int\n pci_detach_all_drivers(struct rte_pci_device *dev)\n {\n-\tstruct rte_pci_driver *dr = NULL;\n+\tstruct rte_pci_driver *pci_drv= NULL;\n+\tstruct rte_driver *drv = NULL;\n+\tstruct rte_bus *pci_bus;\n \tint rc = 0;\n \n \tif (dev == NULL)\n \t\treturn -1;\n \n-\tTAILQ_FOREACH(dr, &pci_driver_list, next) {\n+\tRTE_VERIFY(dev->device->bus);\n+\tpci_bus = dev->device->bus;\n+\n+\tTAILQ_FOREACH(drv, &pci_bus->driver_list, next) {\n+\t\tpci_drv = container_of(drv, struct rte_pci_driver, driver);\n \t\trc = rte_eal_pci_detach_dev(dr, dev);\n \t\tif (rc < 0)\n \t\t\t/* negative value is an error */\n@@ -340,19 +330,28 @@ pci_detach_all_drivers(struct rte_pci_device *dev)\n int\n rte_eal_pci_probe_one(const struct rte_pci_addr *addr)\n {\n-\tstruct rte_pci_device *dev = NULL;\n+\tstruct rte_bus *pci_bus = NULL;\n+\tstruct rte_device *dev = NULL;\n+\tstruct rte_pci_device *pci_dev = NULL;\n \tint ret = 0;\n \n \tif (addr == NULL)\n \t\treturn -1;\n \n+\tpci_bus = rte_eal_get_bus(PCI_BUS_NAME);\n+\tif (!pci_bus) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Unable to find PCI bus\\n\");\n+\t\treturn -1;\n+\t}\n+\n \t/* update current pci device in global list, kernel bindings might have\n \t * changed since last time we looked at it.\n \t */\n \tif (pci_update_device(addr) < 0)\n \t\tgoto err_return;\n \n-\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n+\tTAILQ_FOREACH(dev, &pci_bus->device_list, next) {\n+\t\tpci_dev = container_of(dev, struct rte_pci_device, device);\n \t\tif (rte_eal_compare_pci_addr(&dev->addr, addr))\n \t\t\tcontinue;\n \n@@ -376,22 +375,31 @@ err_return:\n int\n rte_eal_pci_detach(const struct rte_pci_addr *addr)\n {\n-\tstruct rte_pci_device *dev = NULL;\n+\tstruct rte_pci_device *pci_dev = NULL;\n+\tstruct rte_bus *pci_bus = NULL;\n+\tstruct rte_device *dev = NULL;\n \tint ret = 0;\n \n \tif (addr == NULL)\n \t\treturn -1;\n \n-\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n-\t\tif (rte_eal_compare_pci_addr(&dev->addr, addr))\n+\tpci_bus = rte_eal_get_bus(PCI_BUS_NAME);\n+\tif (!pci_bus) {\n+\t\tRTE_LOG(DEBUG, EAL, \"Unable to find PCI bus\\n\");\n+\t\treturn -1;\n+\t}\n+\n+\tTAILQ_FOREACH(dev, &(bus->device_list), next) {\n+\t\tpci_dev = container_of(dev, struct rte_pci_device, device);\n+\t\tif (rte_eal_compare_pci_addr(&pci_dev->addr, addr))\n \t\t\tcontinue;\n \n-\t\tret = pci_detach_all_drivers(dev);\n+\t\tret = pci_detach_all_drivers(pci_dev);\n \t\tif (ret < 0)\n \t\t\tgoto err_return;\n \n-\t\tTAILQ_REMOVE(&pci_device_list, dev, next);\n-\t\tfree(dev);\n+\t\tTAILQ_REMOVE(&pci_bus->device_list, dev, next);\n+\t\tfree(pci_dev);\n \t\treturn 0;\n \t}\n \treturn -1;\n@@ -411,31 +419,42 @@ err_return:\n int\n rte_eal_pci_probe(void)\n {\n-\tstruct rte_pci_device *dev = NULL;\n+\tstruct rte_device *dev = NULL;\n+\tstruct rte_bus *pci_bus;\n+\tstruct rte_pci_device *pci_dev;\n \tstruct rte_devargs *devargs;\n \tint probe_all = 0;\n \tint ret = 0;\n \n+\tpci_bus = rte_eal_get_bus(PCI_BUS_NAME);\n+\tif (!pci_bus) {\n+\t\tRTE_LOG(INFO, EAL, \"(%s): No such bus exists\\n\", PCI_BUS_NAME);\n+\t\t/* Cannot continue ahead and this is not an error */\n+\t\treturn;\n+\t}\n+\n \tif (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)\n \t\tprobe_all = 1;\n \n-\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n+\tTAILQ_FOREACH(dev, &(pci_bus->device_list), next) {\n+\t\tpci_dev = container_of(dev, struct rte_pci_device, device);\n \n \t\t/* set devargs in PCI structure */\n-\t\tdevargs = pci_devargs_lookup(dev);\n+\t\tdevargs = pci_devargs_lookup(pci_dev);\n \t\tif (devargs != NULL)\n-\t\t\tdev->device.devargs = devargs;\n+\t\t\tpci_dev->device.devargs = devargs;\n \n \t\t/* probe all or only whitelisted devices */\n \t\tif (probe_all)\n-\t\t\tret = pci_probe_all_drivers(dev);\n+\t\t\tret = pci_probe_all_drivers(pci_dev);`\n \t\telse if (devargs != NULL &&\n \t\t\tdevargs->type == RTE_DEVTYPE_WHITELISTED_PCI)\n-\t\t\tret = pci_probe_all_drivers(dev);\n+\t\t\tret = pci_probe_all_drivers(pci_dev);\n \t\tif (ret < 0)\n \t\t\trte_exit(EXIT_FAILURE, \"Requested device \" PCI_PRI_FMT\n-\t\t\t\t \" cannot be used\\n\", dev->addr.domain, dev->addr.bus,\n-\t\t\t\t dev->addr.devid, dev->addr.function);\n+\t\t\t\t \" cannot be used\\n\", pci_dev->addr.domain,\n+\t\t\t\t pci_dev->addr.bus, pci_dev->addr.devid,\n+\t\t\t\t pci_dev->addr.function);\n \t}\n \n \treturn 0;\n@@ -465,10 +484,19 @@ pci_dump_one_device(FILE *f, struct rte_pci_device *dev)\n void\n rte_eal_pci_dump(FILE *f)\n {\n-\tstruct rte_pci_device *dev = NULL;\n+\tstruct rte_device *dev = NULL;\n+\tstruct rte_pci_device *pci_dev = NULL;\n+\tstruct rte_bus *bus;\n \n-\tTAILQ_FOREACH(dev, &pci_device_list, next) {\n-\t\tpci_dump_one_device(f, dev);\n+\tbus = rte_eal_get_bus(PCI_BUS_NAME);\n+\tif (!bus) {\n+\t\tRTE_LOG(INFO, EAL, \"(%s): No such bus exists\\n\", PCI_BUS_NAME);\n+\t\treturn;\n+\t}\n+\n+\tTAILQ_FOREACH(dev, &(bus->device_list), next) {\n+\t\tpci_dev = container_of(dev, struct rte_pci_device, device);\n+\t\tpci_dump_one_device(f, pci_dev);\n \t}\n }\n \n@@ -476,7 +504,16 @@ rte_eal_pci_dump(FILE *f)\n void\n rte_eal_pci_register(struct rte_pci_driver *driver)\n {\n-\tTAILQ_INSERT_TAIL(&pci_driver_list, driver, next);\n+\tstruct rte_bus *pci_bus;\n+\n+\tpci_bus = rte_eal_get_bus(PCI_BUS_NAME);\n+\tif (!pci_bus) {\n+\t\tRTE_LOG(INFO, EAL, \"(%s) No such bus exists\\n\", PCI_BUS_NAME);\n+\t\treturn;\n+\t\t/* TODO: How to return error from here? */\n+\t}\n+\n+\tdriver->driver->bus = pci_bus;\n \trte_eal_driver_register(&driver->driver);\n }\n \n@@ -484,6 +521,9 @@ rte_eal_pci_register(struct rte_pci_driver *driver)\n void\n rte_eal_pci_unregister(struct rte_pci_driver *driver)\n {\n-\trte_eal_driver_unregister(&driver->driver);\n-\tTAILQ_REMOVE(&pci_driver_list, driver, next);\n+\tstruct rte_bus *pci_bus;\n+\n+\tpci_bus = driver->driver->bus;\n+\trte_eal_driver_unregister(&pci_bus, &driver->driver);\n+\tdriver->driver->bus = NULL;\n }\ndiff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h\nindex 9ce8847..cffc449 100644\n--- a/lib/librte_eal/common/include/rte_pci.h\n+++ b/lib/librte_eal/common/include/rte_pci.h\n@@ -110,7 +110,7 @@ const char *pci_get_sysfs_path(void);\n \n /** Maximum number of PCI resources. */\n #define PCI_MAX_RESOURCE 6\n-\n+/\n /**\n  * A structure describing an ID for a PCI driver. Each driver provides a\n  * table of these IDs for each device that it supports.\n@@ -360,15 +360,6 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,\n }\n \n /**\n- * Scan the content of the PCI bus, and the devices in the devices\n- * list\n- *\n- * @return\n- *  0 on success, negative on error\n- */\n-int rte_eal_pci_scan(void);\n-\n-/**\n  * Probe the PCI bus for registered drivers.\n  *\n  * Scan the content of the PCI bus, and call the probe() function for\n",
    "prefixes": [
        "dpdk-dev",
        "RFC",
        "4/6"
    ]
}