From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BN3-obe.outbound.protection.outlook.com (mail-bn3nam01on0053.outbound.protection.outlook.com [104.47.33.53]) by dpdk.org (Postfix) with ESMTP id EEFA25686 for ; Mon, 24 Oct 2016 13:59:42 +0200 (CEST) Received: from BLUPR0301CA0009.namprd03.prod.outlook.com (10.162.113.147) by CO2PR03MB2375.namprd03.prod.outlook.com (10.166.93.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.679.12; Mon, 24 Oct 2016 11:59:38 +0000 Received: from BN1BFFO11FD025.protection.gbl (2a01:111:f400:7c10::1:121) by BLUPR0301CA0009.outlook.office365.com (2a01:111:e400:5259::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.679.12 via Frontend Transport; Mon, 24 Oct 2016 11:59:37 +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 BN1BFFO11FD025.mail.protection.outlook.com (10.58.144.88) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.669.7 via Frontend Transport; Mon, 24 Oct 2016 11:59:37 +0000 Received: from Tophie.ap.freescale.net ([10.232.14.87]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u9OBwEMV008267; Mon, 24 Oct 2016 04:59:34 -0700 From: Shreyansh Jain To: CC: , , , Shreyansh Jain , Hemant Agrawal Date: Mon, 24 Oct 2016 17:29:30 +0530 Message-ID: <1477310380-17944-12-git-send-email-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1477310380-17944-1-git-send-email-shreyansh.jain@nxp.com> References: <1476539108-13170-1-git-send-email-shreyansh.jain@nxp.com> <1477310380-17944-1-git-send-email-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131217839775914190; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(7916002)(2980300002)(1110001)(1109001)(339900001)(189002)(199003)(105606002)(50986999)(33646002)(76176999)(8676002)(81156014)(5003940100001)(6666003)(356003)(19580395003)(19580405001)(81166006)(305945005)(7846002)(97736004)(2906002)(8666005)(77096005)(36756003)(85426001)(4326007)(8936002)(50466002)(2950100002)(50226002)(92566002)(47776003)(5660300001)(86362001)(189998001)(626004)(68736007)(110136003)(586003)(106466001)(2351001)(5890100001)(229853001)(11100500001)(6916009)(104016004)(87936001)(48376002)(7059030)(473944003); DIR:OUT; SFP:1101; SCL:1; SRVR:CO2PR03MB2375; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD025; 1:6mkwnhqFuebsKz+oIYvcOtthr9hjLpDmmrVCmFaQ7TS92KU6dZUVmFw8w5pio657E+21xVGyReSlvbQ319C0hY+Cfsssp8UQikaBHWA3QRaqV/sIaAYkbGwkCfZjt+F+/nVbi4WIpN96wrl91VG58D0LY8eQRR1BBBMxIEZNhodFFyAyADWFXxkfiE9Y8TF844yNtJcs6qQglRfBpOP9ULxryfzCRHIihDbUJd2o/25klGFDbEfLzlxjrLdrBRFh9AUzOr9pnNdo6NAhJbhZkryTRHcS4aatRlpGuZB3mTkOoeHatHmqGI5btKb631JESTKTeVyq9X4fC6nTCXv2RXyPTjA/kX97CmMSRQbeZLx+9FKdGty3KmvOnzKCh/PC5ITAy+igYT1kqzMA+YMDiGGy3FhYsYMDfHIGMLerhS/F8MUy3/9KVk8UL+5texnQh0PQUFqgKFD+y99tVI6HpD9/ZLJDMDxXvYONNC1g/yFc7S0gb5LGVE6UotDYGlsCl1GL1Z7cen2bUb9j7UslkDFkYF5GMLRP8jEcumik+LTX94fKnZkGxjfIoRDvKVXXo8p3PncoiIgKGZxPA1WH+2YlJdYSXgq4IvZa/ptDrmy0k8SE9bHBcW9oIkK/vlfE7w54UrxvuBlRRGCIk+Tbzi6yBQa/vNl2JnYON4j5ItQf4m5UFYpzmgxDl1fBS2RZvNCF+X6pZwG8QbTE3VAVkZWGRPnMHSgfsBS2Vf89qRg= MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: ba973f97-16e0-4f1f-376f-08d3fc053a7e X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2375; 2:S+eCubRPeWXODi38Y6TD7tzbSHnlfLhoPLC/MbgYoM3otLVjyp6kGy6FTnV6iSGpQFniwF5A+O00wK8KtHC85BGObbEV1AZwxaMKLMosfOjmdYoHw2+TKoXf9AV/162CBERuFUasdgBJ/KtxRkwp0xCouFgAxpTtqKELMpBOlkGy17E29KrGF05hyLJGCF+FvGRll3AP8HzkloIkx4dIEQ==; 3:PpEo5rM/MX+GdbZ3hVHN301Myrg5GdVgDgAshg0JKEiEEERNBkOcW52HU6kAX0geEcb22YBvCqHFa7WOC/zFKjfGbLSGgBlbdNtybq09o7VCsJ/15oxPUQ8vwng7Q47MVNfbbntBKbuZKPNYWgVbWpgLVJnxgcI8bii0jrm15VL51amFAMlQW/MckoXsVScyvrVAl1/XfmvezKMAFTTr6vwi0ty1bh+xEHJYymY6nhnGBIFgXAp+dBDVzUxzvZ1k X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CO2PR03MB2375; X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2375; 25:Ub76RJpraNf6wgxDA6jAK575F93XfRpCMH/5pjjKcvQsYgWPuJUwmd+sJx0mA5zncKfxIdvgumwhVq3wSAo+sdEZLLlEqbSHvU9IKdP+dNQXEPEqbxAoAOzLgjZUFdEb+Ei0fkT4r43yUgBXYEcfhXfoIbsRBr2QcuQN68bZVFW6FcHhF3alTfIQ64TK2uGVVef1mR67vTduopND+2PoJgQFrFuMOytfuho2ZjoyCgBBy7fLuizwWHjgUaS90uJW+c40sp9cdj/h9dRdu/tdWr5umwDOJfCj+jUFtS4xB0rLdBphv9zylS+dLoNklC5fzXo2iJImRwzvv5XOBRcCy9Cn0/jdGfWy3JYGf8klI28tEvqGQ0L8YhTR+1X46C16arBfREaNFY0rhhK4Jbjty7YfCYiDwfNa8SLOndxcWBe+cuzzM4wWDUHZMxz5UYB5aXVXQpK/Z1KbDiDPokj5XC/X139b9Igjs6LSYCVC9pT2qFWtQccTFqMf1AOegeusUd3SBckuTA0DWAgghPSfMQKkGa35p+bBWKPle+Glz2eu/frY5ao3X6Sp/yG2oFqs/UR2dvmQjgTNzYZWbButPAWpsjFvYLpS0rwvd5Mz9yA76OKp7s/RKdO+G+pEhKLbggpzUNa0phuXFxnDoFJgvL1Ted43SpVOvzFnEIlXKAzIqqh0+anHzQLuFge+9K2l4HniRiEtQ7pYURnkTpRbsM3kkz1x15SGKoW8Kj0mZKpoQgv9cjxXfzt8mIwnc4LwPjQoVCvREcYAlXsCvbJ6WziwzbbUnoqNzzN7YJxSEwI= X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2375; 31:U/bhho+lL0cWYqdu3sRiKOxme7QaqR2cQZ7IrrJ4OA3NKsBanPoou5kzVUHqXSpb1l4mNM33Zb/BLbTJ9ZlPiOQ1VNs7zB163HnFhLnqplCRWf909JA6EAItBuxjULTTwQFuBt/LPZxZ1GY3IGq2r/PvSdpHdWBvrAdLqKeGbqx/MokmvXmc3SWQL7d7tdo3pNPAYswrsRsEn5tNnmcGD524GemOeW4c2wbKuxMoo4HSyYm1QZdQf7Pl040/npiIBukmMy8u4Og20gx1pBGNgw==; 4:yU4qmHhj7tI0wkVR6MCgmk6tJKi04pbzsYqlJyetZtR+ZAWT9XUJKghNodr2350PmOlUx9aThsTneaGVsGBj46QvV/GrygFhYVeWqIKz5+bPawT5N0/n3DqXT0Zt2JVsajoWXYFr3wrQShPN43PqjtUSwtSErQ63Np1eEbZ2eFDutnqsSnpExeuSD06UHW2ldGRwH+48wLYdjpsZZO1Y/+kEk+M8mupZF1Ymp6f5G8t64dvBuEm/qG99g2Va1ryPpTO/53ev3Eb+KrKK+6IngLrLIo5BrWU9KeCcxY6hYmFRwEZ0MWdruMqKCn9jKVtJMUg76aWMsMtRL/SNhK6rTLY5OKBJAi42SkTEBb5qFW2cOHQdWigln9GD0nb+uNSmtLiSpdBAGBkq3mfOFcGueakJZeJZmBVpUi4UbTdKvn0BY+dGRoosPKQ9Y3LdXlBBswZQChRRqyP9F4vECr8pT+NVat2WoLehJbwIdks1hJZkphGjVI9BQy2wGTI3LlqxHp+lqPV4CQMCd6+aY7S8zp4gjso1HhLl1ovyC1b+wZ8Mg72A6s3j0cLeE8mBIXyC X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(13023025)(13015025)(13017025)(13018025)(13024025)(5005006)(8121501046)(10201501046)(3002001)(6055026); SRVR:CO2PR03MB2375; BCL:0; PCL:0; RULEID:(400006); SRVR:CO2PR03MB2375; X-Forefront-PRVS: 0105DAA385 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CO2PR03MB2375; 23:ALQv6b5X4Gblc+ATCWslAtkM29X8jIy0D3IcQVHwd?= =?us-ascii?Q?9ytrBQJ1KXZw4+MY/XaBoLI6S4XvKDJuEMuGfnM3PZfeNUffQK2pVweHTbQ1?= =?us-ascii?Q?XJxEHWZOyNUCWuNcaAoYyV3R2/7if7/4xudhUs1qKockczRGgxI/2g/gJKqJ?= =?us-ascii?Q?O1mH8MeZ4MVhPnQnEYyLQnG0y6XmENxiYfqIhG8G/3Lld5w9kSb11UyWSDGp?= =?us-ascii?Q?SREVa366vTmfECHFLdjX+PRvXmzzPHWWt6j6EiCzHBMbJa9HEDx6UvHH/Fu1?= =?us-ascii?Q?BF+Fwz+FxJVaUxzF1Fngd9O+ohh56udhCr5fXSxe7mwt14iKbAz0KehUuKC5?= =?us-ascii?Q?9SmEjqKvX09Vlc0PdJ2sxNgOnUX3oRKAm0RFEOwE+3vo/4y1TLfkQT3+GKgz?= =?us-ascii?Q?B3Je+luIhr0gCxFBmEqsoKCw4r3fptLrbU8h536jpkvTSKNNspb/4Ga0BGhg?= =?us-ascii?Q?20QZySwFI0WTFooilvMAIXfaeHLsNTztTV9t4FjJ0n2RXxHrEKY8AJRjq7qd?= =?us-ascii?Q?YQkBSC7SH2djLgQg8vhxAHtJiRnYKlBMJHrEgESjzt/0xaaO+7gJkUjjxyAy?= =?us-ascii?Q?fURHzN8M8xTQn8tlUCc4HDYl/qPf+JERI6x9qVKz98mFgnu2k3TkvkiCUqYq?= =?us-ascii?Q?qnY/H3WkrFZbdUmuvNyM8dKwr2CdRw5bi/EJfzOvNbTbWYVVGhibQWdDmD7E?= =?us-ascii?Q?Dvle3s0gmq0SXvt3zQNg24ge1T/bmAM7+M285IRBzdUlfxFzpDQ0u3hD8QDq?= =?us-ascii?Q?OM/xQs/yeqrRMkTZgx46l2ZWtzoc1iEh4NuAiSXRAmF7y0NjufWN7aInrOEp?= =?us-ascii?Q?1nM/zyVTIaMcsjtbudIK+4UhV/Nt4UhergqJe7MnFhsMar0akGEm+X6GH5qi?= =?us-ascii?Q?JL5gbEwb9QWnA9lfZNmyae7m6hBFn5Y7Gw46wIzUPaCIX1GEjuvfYbVe+14j?= =?us-ascii?Q?Vv88DT4yOg8US8Vn7ajMIsbxdvDZrpRZ9nf20FZ2LzexeWLUUCEBYm6/0VM+?= =?us-ascii?Q?a58aeS3jAz6uzt/ouJIHwr1uuaDhI2PIEFRZXkIbyb6u1+Up+nfh1rJSHIcp?= =?us-ascii?Q?YwoGx/qexUYwz1XvyfxwFYQsKVRL26kRg+4lvCWeYemdayLCHoiMqSOtyyBY?= =?us-ascii?Q?Qrvdql+JR/Rudw2IBjhZrliCX3iw2PWFczAnxz5BinrQV4RpDpYqAlu3Oj5y?= =?us-ascii?Q?sZJb3rFrA2slgKhHLjGghYXxRL0vx/sgokAtbCdgyCW6zYEXBGSvuKtHI8eA?= =?us-ascii?Q?K6j7qQgeZSssjhaTClPHdJw3Mjh+WqumGUV6LGK?= X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2375; 6:PLkrnkfYn/pHTsbh9XkxedJ7bPzM/jXFD9o7A5BF/Xuvq4NpL6FPM/lERgW2srtmFZXW4QapSdgx0rMRrmBrA7L5P7puVOS6VpHoqJufWZMTZMmHf+W/nrQgjGfXZS0zgkiexkAJ1egPima5rY9Vr18P7k8NPgn9e3VxnU1IKxadsPizDAR99i0FOvTeP3tN9/VflCoTA3mr7lk7A3HPYGC6liNyO+m0ay6f1ANQGDClJPyIJtJYhuU7uAUyu8RR77fceAhRDshokpTT+0SUFwnVgjiSgRAYRVVx8y+A6p17HrUyZqGkKJ4eBy/bTGjx; 5:rp4+x+yTRJ0YZ9VgVNnuayAblo1ZeRL4cygMiTXKnTA+aMb20iVCipAcic0ueWVWGZfYsfD+LejpNpu4vAZPPR3YBEqI+j6Bww6Z9VTLsi2RNjZ4XPGExU6cvk5OJJarUJ85OR75wU442BDiwIis0Q9HFBXNZQrhPs0HFDJ6v5bsulpOURAitxvAvJweF93C; 24:5wkKGMng9yH85UMg6HoE+6oKOXU7Yqy8JfFYGUNbYRoX68VlGdM43UJKuTByjXLdTn8HeQmaITIrHQX/GrYa/rHEhRmoD5cYriDCzU3Fjmw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CO2PR03MB2375; 7:5yvtuK6XyVWLlpmo/UE3j6Ha+7GAD8n2/EaNBFInGmNsdAVfgZ9z4FSc9KLCF73GldsnOFOIbpZ/X8gz+4qzOfOn7tTKmQtOIFNO6sfzWGqBdF6rPBIUDkOXUI0m8peeDupLLEHMU2m7jyPqV04YfCoeSbGc91MA4Q561uyB5TJIPJZI9OXSzd5OelxE3urJ3SWITNQwTCa/bsanfv7TuPf+ESThqFg+f9bXKLiytLxU7hesZevlSwKbjtWuAHg6ujtDoNaXQvGdWhlKmT74BIcw9yxdyUO+P6kpdgO17lwkpoLZnBu6P9BTF+d3MYqsBWSi4my+LxYOL9jRzyLrjOY8Au50ByHRa44Qdx0MXMo= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Oct 2016 11:59:37.3886 (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: CO2PR03MB2375 Subject: [dpdk-dev] [PATCH v5 11/21] eal/soc: implement probing of drivers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Oct 2016 11:59:44 -0000 Each SoC PMD registers a set of callback for scanning its own bus/infra and matching devices to drivers when probe is called. This patch introduces the infra for calls to SoC scan on rte_eal_soc_init() and match on rte_eal_soc_probe(). Patch also adds test case for scan and probe. Signed-off-by: Jan Viktorin Signed-off-by: Shreyansh Jain Signed-off-by: Hemant Agrawal -- v4: - Update test_soc for descriptive test function names - Comments over test functions - devinit and devuninint --> probe/remove - RTE_VERIFY at some places --- app/test/test_soc.c | 205 ++++++++++++++++++++++- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_soc.c | 213 +++++++++++++++++++++++- lib/librte_eal/common/include/rte_soc.h | 83 ++++++++- lib/librte_eal/linuxapp/eal/eal.c | 5 + lib/librte_eal/linuxapp/eal/eal_soc.c | 21 ++- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 4 + 7 files changed, 523 insertions(+), 12 deletions(-) diff --git a/app/test/test_soc.c b/app/test/test_soc.c index ac03e64..b587d5e 100644 --- a/app/test/test_soc.c +++ b/app/test/test_soc.c @@ -87,14 +87,65 @@ static int test_compare_addr(void) */ struct test_wrapper { struct rte_soc_driver soc_drv; + struct rte_soc_device soc_dev; }; +static int empty_pmd0_probe(struct rte_soc_driver *drv, + struct rte_soc_device *dev); +static int empty_pmd0_remove(struct rte_soc_device *dev); + +static void always_find_dev0_cb(void); +static int match_dev0_by_name(struct rte_soc_driver *drv, + struct rte_soc_device *dev); + +static void always_find_dev1_cb(void); +static int match_dev1_by_name(struct rte_soc_driver *drv, + struct rte_soc_device *dev); + +/** + * Dummy probe handler for PMD driver 'pmd0'. + * + * @param drv + * driver object + * @param dev + * device object + * @return + * 0 on success + */ +static int +empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused, + struct rte_soc_device *dev __rte_unused) +{ + return 0; +} + +/** + * Remove handler for PMD driver 'pmd0'. + * + * @param dev + * device to remove + * @return + * 0 on success + */ +static int +empty_pmd0_remove(struct rte_soc_device *dev) +{ + /* Release the memory associated with dev->addr.name */ + free(dev->addr.name); + + return 0; +} + struct test_wrapper empty_pmd0 = { .soc_drv = { .driver = { .name = "empty_pmd0" }, - }, + .probe = empty_pmd0_probe, + .remove = empty_pmd0_remove, + .scan_fn = always_find_dev0_cb, + .match_fn = match_dev0_by_name, + } }; struct test_wrapper empty_pmd1 = { @@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = { .driver = { .name = "empty_pmd1" }, + .scan_fn = always_find_dev1_cb, + .match_fn = match_dev1_by_name, }, }; +/** + * Bus scan by PMD 'pmd0' for adding device 'dev0' + * + * @param void + * @return void + */ +static void +always_find_dev0_cb(void) +{ + /* SoC's scan would scan devices on its bus and add to + * soc_device_list + */ + empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev"); + + TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next); +} + +/** + * Match device 'dev0' with driver PMD pmd0 + * + * @param drv + * Driver with this matching needs to be done; unused here + * @param dev + * device to be matched against driver + * @return + * 0 on successful matched + * 1 if driver<=>device don't match + */ +static int +match_dev0_by_name(struct rte_soc_driver *drv __rte_unused, + struct rte_soc_device *dev) +{ + if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev")) + return 0; + + return 1; +} + +/** + * Bus scan by PMD 'pmd0' for adding device 'dev1' + * + * @param void + * @return void + */ +static void +always_find_dev1_cb(void) +{ + /* SoC's scan would scan devices on its bus and add to + * soc_device_list + */ + empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev"); + + TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next); +} + +/** + * Match device 'dev1' with driver PMD pmd0 + * + * @param drv + * Driver with this matching needs to be done; unused here + * @param dev + * device to be matched against driver + * @return + * 0 on successful matched + * 1 if driver<=>device don't match + */ +static int +match_dev1_by_name(struct rte_soc_driver *drv __rte_unused, + struct rte_soc_device *dev) +{ + if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev")) + return 0; + + return 1; +} + static int count_registered_socdrvs(void) { @@ -148,13 +277,68 @@ test_register_unregister(void) return 0; } +/* Test Probe (scan and match) functionality */ +static int +test_soc_scan_and_match(void) +{ + int drv_count = 0; + struct rte_soc_driver *drv; + + /* Registering dummy drivers */ + rte_eal_soc_register(&empty_pmd0.soc_drv); + rte_eal_soc_register(&empty_pmd1.soc_drv); + /* Assuming that test_register_unregister is working, not verifying + * that drivers are indeed registered + */ + + /* rte_eal_soc_init is called by rte_eal_init, which in turn calls the + * scan_fn of each driver. + */ + TAILQ_FOREACH(drv, &soc_driver_list, next) { + if (drv && drv->scan_fn) + drv->scan_fn(); + drv_count++; + } + + /* rte_eal_init() would perform other inits here */ + + /* Probe would link the SoC devices<=>drivers */ + rte_eal_soc_probe(); + + /* Unregistering dummy drivers */ + rte_eal_soc_unregister(&empty_pmd0.soc_drv); + rte_eal_soc_unregister(&empty_pmd1.soc_drv); + + /* Verify the Unregistering has removed the driver from list */ + TAILQ_FOREACH(drv, &soc_driver_list, next) { + if (drv) + drv_count--; + } + + free(empty_pmd0.soc_dev.addr.name); + + /* If drv_count is anything other than 0, Unregistering failed */ + if (drv_count) { + printf("%s has failed\n", __func__); + return 1; + } + + printf("%s has been successful\n", __func__); + return 0; +} + /* save real devices and drivers until the tests finishes */ struct soc_driver_list real_soc_driver_list = TAILQ_HEAD_INITIALIZER(real_soc_driver_list); +/* save real devices and drivers until the tests finishes */ +struct soc_device_list real_soc_device_list = + TAILQ_HEAD_INITIALIZER(real_soc_device_list); + static int test_soc_setup(void) { struct rte_soc_driver *drv; + struct rte_soc_device *dev; /* no real drivers for the test */ while (!TAILQ_EMPTY(&soc_driver_list)) { @@ -163,12 +347,20 @@ static int test_soc_setup(void) TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next); } + /* And, no real devices for the test */ + while (!TAILQ_EMPTY(&soc_device_list)) { + dev = TAILQ_FIRST(&soc_device_list); + TAILQ_REMOVE(&soc_device_list, dev, next); + TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next); + } + return 0; } static int test_soc_cleanup(void) { struct rte_soc_driver *drv; + struct rte_soc_device *dev; /* bring back real drivers after the test */ while (!TAILQ_EMPTY(&real_soc_driver_list)) { @@ -177,6 +369,13 @@ static int test_soc_cleanup(void) rte_eal_soc_register(drv); } + /* And, bring back real devices after the test */ + while (!TAILQ_EMPTY(&real_soc_device_list)) { + dev = TAILQ_FIRST(&real_soc_device_list); + TAILQ_REMOVE(&real_soc_device_list, dev, next); + TAILQ_INSERT_TAIL(&soc_device_list, dev, next); + } + return 0; } @@ -192,6 +391,10 @@ test_soc(void) if (test_register_unregister()) return -1; + /* Assuming test_register_unregister has succeeded */ + if (test_soc_scan_and_match()) + return -1; + if (test_soc_cleanup()) return -1; diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index 86e3cfd..dfbb1ac 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -171,7 +171,11 @@ DPDK_16.11 { rte_eal_dev_attach; rte_eal_dev_detach; rte_eal_map_resource; + rte_eal_soc_detach; rte_eal_soc_dump; + rte_eal_soc_match; + rte_eal_soc_probe; + rte_eal_soc_probe_one; rte_eal_soc_register; rte_eal_soc_unregister; rte_eal_unmap_resource; diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c index 5dcddc5..256cef8 100644 --- a/lib/librte_eal/common/eal_common_soc.c +++ b/lib/librte_eal/common/eal_common_soc.c @@ -36,6 +36,8 @@ #include #include +#include +#include #include "eal_private.h" @@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list = struct soc_device_list soc_device_list = TAILQ_HEAD_INITIALIZER(soc_device_list); +int +rte_eal_soc_match_compat(struct rte_soc_driver *drv, + struct rte_soc_device *dev) +{ + int i, j; + + RTE_VERIFY(drv != NULL && drv->id_table != NULL); + RTE_VERIFY(dev != NULL && dev->id != NULL); + + for (i = 0; drv->id_table[i].compatible; ++i) { + const char *drv_compat = drv->id_table[i].compatible; + + for (j = 0; dev->id[j].compatible; ++j) { + const char *dev_compat = dev->id[j].compatible; + + if (!strcmp(drv_compat, dev_compat)) + return 0; + } + } + + return 1; +} + +static int +rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv, + struct rte_soc_device *dev) +{ + int ret = 1; + + RTE_VERIFY(drv->match_fn); + + ret = drv->match_fn(drv, dev); + if (ret) { + RTE_LOG(DEBUG, EAL, + " match function failed, skipping\n"); + return ret; + } + + dev->driver = drv; + RTE_VERIFY(drv->probe != NULL); + return drv->probe(drv, dev); +} + +static int +soc_probe_all_drivers(struct rte_soc_device *dev) +{ + struct rte_soc_driver *drv = NULL; + int rc = 0; + + if (dev == NULL) + return -1; + + TAILQ_FOREACH(drv, &soc_driver_list, next) { + rc = rte_eal_soc_probe_one_driver(drv, dev); + if (rc < 0) + /* negative value is an error */ + return -1; + if (rc > 0) + /* positive value means driver doesn't support it */ + continue; + return 0; + } + return 1; +} + +/* If the IDs match, call the remove() function of the driver. */ +static int +rte_eal_soc_detach_dev(struct rte_soc_driver *drv, + struct rte_soc_device *dev) +{ + int ret; + + if ((drv == NULL) || (dev == NULL)) + return -EINVAL; + + ret = drv->match_fn(drv, dev); + if (ret) { + RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n", + drv->driver.name, dev->addr.name); + return ret; + } + + RTE_LOG(DEBUG, EAL, "SoC device %s\n", + dev->addr.name); + + RTE_LOG(DEBUG, EAL, " remove driver: %s\n", drv->driver.name); + + if (drv->remove && (drv->remove(dev) < 0)) + return -1; /* negative value is an error */ + + /* clear driver structure */ + dev->driver = NULL; + + return 0; +} + +/* + * Call the remove() function of all registered drivers for the device. + * + * @param dev + * Device for which detach is to be performed + * @return + * 0 when successful + * -1 if deinitialization fails + * 1 if no driver is found for this device. + */ +static int +soc_detach_all_drivers(struct rte_soc_device *dev) +{ + struct rte_soc_driver *dr = NULL; + int rc = 0; + + if (dev == NULL) + return -1; + + TAILQ_FOREACH(dr, &soc_driver_list, next) { + rc = rte_eal_soc_detach_dev(dr, dev); + if (rc < 0) + /* negative value is an error */ + return -1; + if (rc > 0) + /* positive value means driver doesn't support it */ + continue; + return 0; + } + return 1; +} + +int +rte_eal_soc_detach(const struct rte_soc_addr *addr) +{ + struct rte_soc_device *dev = NULL; + int ret = 0; + + if (addr == NULL) + return -1; + + TAILQ_FOREACH(dev, &soc_device_list, next) { + if (rte_eal_compare_soc_addr(&dev->addr, addr)) + continue; + + ret = soc_detach_all_drivers(dev); + if (ret < 0) + goto err_return; + + TAILQ_REMOVE(&soc_device_list, dev, next); + return 0; + } + return -1; + +err_return: + RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n", + dev->addr.name); + return -1; +} + +int +rte_eal_soc_probe_one(const struct rte_soc_addr *addr) +{ + struct rte_soc_device *dev = NULL; + int ret = 0; + + if (addr == NULL) + return -1; + + TAILQ_FOREACH(dev, &soc_device_list, next) { + if (rte_eal_compare_soc_addr(&dev->addr, addr)) + continue; + + ret = soc_probe_all_drivers(dev); + if (ret < 0) + goto err_return; + return 0; + } + return -1; + +err_return: + RTE_LOG(WARNING, EAL, + "Requested device %s cannot be used\n", addr->name); + return -1; +} + +int +rte_eal_soc_probe(void) +{ + struct rte_soc_device *dev = NULL; + int ret = 0; + + TAILQ_FOREACH(dev, &soc_device_list, next) { + ret = soc_probe_all_drivers(dev); + if (ret < 0) { + RTE_LOG(DEBUG, EAL, "Requested device %s" + " cannot be used\n", dev->addr.name); + /* Failure for a particular device is logged and + * ignored + */ + } + } + + return ret; +} + /* dump one device */ static int soc_dump_one_device(FILE *f, struct rte_soc_device *dev) @@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev) return 0; } -/* dump devices on the bus to an output stream */ void rte_eal_soc_dump(FILE *f) { @@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f) } } -/* register a driver */ void rte_eal_soc_register(struct rte_soc_driver *driver) { + /* For a valid soc driver, match and scan function + * should be provided. + */ + RTE_VERIFY(driver != NULL); + RTE_VERIFY(driver->match_fn != NULL); + RTE_VERIFY(driver->scan_fn != NULL); TAILQ_INSERT_TAIL(&soc_driver_list, driver, next); } -/* unregister a driver */ void rte_eal_soc_unregister(struct rte_soc_driver *driver) { diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h index 4a01af5..030df6f 100644 --- a/lib/librte_eal/common/include/rte_soc.h +++ b/lib/librte_eal/common/include/rte_soc.h @@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list; TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */ TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */ - struct rte_soc_id { const char *compatible; /**< OF compatible specification */ uint64_t priv_data; /**< SoC Driver specific data */ @@ -89,12 +88,29 @@ struct rte_soc_driver; /** * Initialization function for the driver called during SoC probing. */ -typedef int (soc_devinit_t)(struct rte_soc_driver *, struct rte_soc_device *); +typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *); /** * Uninitialization function for the driver called during hotplugging. */ -typedef int (soc_devuninit_t)(struct rte_soc_device *); +typedef int (soc_remove_t)(struct rte_soc_device *); + +/** + * SoC device scan callback, called from rte_eal_soc_init. + * For various SoC, the bus on which devices are attached maynot be compliant + * to a standard platform (or platform bus itself). In which case, extra + * steps are implemented by PMD to scan over the bus and add devices to SoC + * device list. + */ +typedef void (soc_scan_t)(void); + +/** + * Custom device<=>driver match callback for SoC + * Unlike PCI, SoC devices don't have a fixed definition of device + * identification. PMDs can implement a specific matching function in which + * driver and device objects are provided to perform custom match. + */ +typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *); /** * A structure describing a SoC driver. @@ -102,8 +118,10 @@ typedef int (soc_devuninit_t)(struct rte_soc_device *); struct rte_soc_driver { TAILQ_ENTRY(rte_soc_driver) next; /**< Next in list */ struct rte_driver driver; /**< Inherit core driver. */ - soc_devinit_t *devinit; /**< Device initialization */ - soc_devuninit_t *devuninit; /**< Device uninitialization */ + soc_probe_t *probe; /**< Device probe */ + soc_remove_t *remove; /**< Device remove */ + soc_scan_t *scan_fn; /**< Callback for scanning SoC bus*/ + soc_match_t *match_fn; /**< Callback to match dev<->drv */ const struct rte_soc_id *id_table; /**< ID table, NULL terminated */ }; @@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0, } /** + * Default function for matching the Soc driver with device. Each driver can + * either use this function or define their own soc matching function. + * This function relies on the compatible string extracted from sysfs. But, + * a SoC might have different way of identifying its devices. Such SoC can + * override match_fn. + * + * @return + * 0 on success + * -1 when no match found + */ +int +rte_eal_soc_match_compat(struct rte_soc_driver *drv, + struct rte_soc_device *dev); + +/** + * Probe SoC devices for registered drivers. + * + * @return + * 0 on success + * !0 in case of any failure in probe + */ +int rte_eal_soc_probe(void); + +/** + * Probe the single SoC device. + */ +int rte_eal_soc_probe_one(const struct rte_soc_addr *addr); + +/** + * Close the single SoC device. + * + * Scan the SoC devices and find the SoC device specified by the SoC + * address, then call the remove() function for registered driver + * that has a matching entry in its id_table for discovered device. + * + * @param addr + * The SoC address to close. + * @return + * - 0 on success. + * - Negative on error. + */ +int rte_eal_soc_detach(const struct rte_soc_addr *addr); + +/** * Dump discovered SoC devices. + * + * @param f + * File to dump device info in. */ void rte_eal_soc_dump(FILE *f); /** * Register a SoC driver. + * + * @param driver + * Object for SoC driver to register + * @return void */ void rte_eal_soc_register(struct rte_soc_driver *driver); @@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__) /** * Unregister a SoC driver. + * + * @param driver + * Object for SoC driver to unregister + * @return void */ void rte_eal_soc_unregister(struct rte_soc_driver *driver); diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 098ba02..bd775f3 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv) if (rte_eal_pci_probe()) rte_panic("Cannot probe PCI\n"); + /* Probe & Initialize SoC devices */ + if (rte_eal_soc_probe()) + rte_panic("Cannot probe SoC\n"); + rte_eal_mcfg_complete(); return fctret; diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c index 04848b9..3929a76 100644 --- a/lib/librte_eal/linuxapp/eal/eal_soc.c +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c @@ -44,13 +44,28 @@ #include #include -#include "eal_internal_cfg.h" -#include "eal_filesystem.h" -#include "eal_private.h" +#include +#include +#include /* Init the SoC EAL subsystem */ int rte_eal_soc_init(void) { + struct rte_soc_driver *drv; + + /* SoC is disabled by default */ + if (!internal_config.enable_soc) + return 0; + + /* For each registered driver, call their scan routine to perform any + * custom scan for devices (for example, custom buses) + */ + TAILQ_FOREACH(drv, &soc_driver_list, next) { + RTE_VERIFY(drv->scan_fn); + drv->scan_fn(); + /* Ignore all errors from this */ + } + return 0; } diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index 0155025..c28e093 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -175,7 +175,11 @@ DPDK_16.11 { rte_eal_dev_attach; rte_eal_dev_detach; rte_eal_map_resource; + rte_eal_soc_detach; rte_eal_soc_dump; + rte_eal_soc_match; + rte_eal_soc_probe; + rte_eal_soc_probe_one; rte_eal_soc_register; rte_eal_soc_unregister; rte_eal_unmap_resource; -- 2.7.4