From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0062.outbound.protection.outlook.com [104.47.34.62]) by dpdk.org (Postfix) with ESMTP id 3C0BA6CC2 for ; Mon, 24 Oct 2016 13:59:50 +0200 (CEST) Received: from BLUPR0301CA0005.namprd03.prod.outlook.com (10.162.113.143) by BN3PR03MB2370.namprd03.prod.outlook.com (10.166.74.153) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.669.16; Mon, 24 Oct 2016 11:59:48 +0000 Received: from BN1BFFO11FD035.protection.gbl (2a01:111:f400:7c10::1:196) by BLUPR0301CA0005.outlook.office365.com (2a01:111:e400:5259::15) 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:48 +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 BN1BFFO11FD035.mail.protection.outlook.com (10.58.144.98) 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:48 +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 u9OBwEMZ008267; Mon, 24 Oct 2016 04:59:45 -0700 From: Shreyansh Jain To: CC: , , , Shreyansh Jain Date: Mon, 24 Oct 2016 17:29:34 +0530 Message-ID: <1477310380-17944-16-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: 131217839881957790; (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)(86362001)(11100500001)(87936001)(97736004)(36756003)(5003940100001)(85426001)(33646002)(50986999)(19580395003)(19580405001)(4326007)(77096005)(2906002)(76176999)(50466002)(8666005)(48376002)(356003)(47776003)(8936002)(6916009)(50226002)(2950100002)(81156014)(8676002)(5660300001)(626004)(110136003)(92566002)(189998001)(68736007)(229853001)(106466001)(586003)(6666003)(81166006)(2351001)(104016004)(305945005)(105606002)(7846002)(7059030)(403724002); DIR:OUT; SFP:1101; SCL:1; SRVR:BN3PR03MB2370; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD035; 1:O/QAx+0MBQxSZ9QIcamLggU0Z+LydWcBfo7jqa3eB9sp7nLF721/8FuGz1cesOt+xkogO0pA6/HX/pilRzIA4beyey46M1UAIOo2RfhIuMrZCeSda3x+CCALFv4s8hjMZ4hZqmONlE8sx6VbGAtzLdobFUbKYIx2MrP9uEOQpH10RHo62r72PDR8KBTwmgaRuh5kNNYQ0QXGUdTnOdmJy3zqB3PNgZbJy7JyYaHCwca8d3rOnzTGCWYUBHKqqRa9IjYtQhqYAe20docqzSBlMx0RdM5NoQN9D4Adhzn3QPA1/wJk9bx0hu7Jhz9Vc1ALKjS7gdoxbefSq1ulX8xSGBhTx/znZpj1A82fZ1IEPlPW8z8KzY+6/Om0cdrc0SQCKKnvDuepvpZpMC0U1zYZ7LdHDU9CdfOPbUFg3FR6I/odEGpdvrXobDVRNE7DLUYiSVh7rd6oAJReYSBjP7/O/hdV2p9zyYxC8n9nMveSrkuoGyOXXiDcko7mNurFyHCBK339VYPcjRTe+4eZ1KpfyIWmwLIZjcNpOJKa8O8Wl70sCqggasv+HHxa0D/+JGt4edinuU/71z4Ymbtx7S7Fnx5peLZQD93c2QNdJpCOiqV/Jt1aE290AtcFzbvk0mLvvUn00HawrE0ewB7d73cu7aPPtqYhZctuExxyvSnnnUDaOWvuM9H/MPVpXprnx/dnBb2KhHnKiDZaHRJP/wh+2cCVjQn4A1LwOf/Hx5+bYcI= MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 8c9a003b-a88f-428e-503c-08d3fc0540d0 X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2370; 2:qMg5LS5rMydTxYkq9qW03RzicR6qd5v4Tz/RQ4PlQx1nZYokupXHLQoXYt426ZP6sCJ8TIH8BNSIrpT1I6hQ2JCTCsvPzTbAD3dSbOF89EzGHIazuCoggH5wDh34JGrxkbRc7bCncq0GBVtNV9xYlaK3BGFMKVzyOievLow7WqIiS/83c0qTFTQE2c12jg3nOrGor8AoLWB8OZqUanZmvA==; 3:V9SsIdyZ+Rp+02K+KLRe5wSt2yBuqiVvMG/7pOoW8c9ZpQZlCtzN4IK0A+Ba/muv9FL/b8Mp67qwPigBtdv3avxj9RPrn5vUkmu3/3X0OtOk6jEOkXroSDSvMzFVwhEtLy866/YZ9jFyrV5H5l6cmzAlY9mFc/eC7u8SxCu1B9DLMYiq5jtX6W7YW1SSW/UfWxG5LpVjPhX1b7Wvc8Ypyrshz0hlVo4Z6Q6MvO5DnVN449xgU59xvnGPLTQWFKOr; 25:kzEIJncE4g2qkuI4KEMC7mzfR/weniPOP8dx//m5HUTP8RHDWIBapou5aTq/KroLyaGJIPu7qIU+PG7uOZzbe84JXQZQma/cHV+EodiTrk355/+dnC++4zaYBOOyTbdt7aRFYBwqk2QLmIMPlt71ndhKGImHy+PnZU7/eDPH3NLRqf7NovrRZnBCz2iGqEb+D1dD7oqOw9KPBrv0rdeeGn9OuRMu5km4X6gv2lPT5gD1vIwxw7BX5PagQPvTHYx3zr8Bj08oPLuUnhUkip9/tQsOXNflFXGhuQJupHA06wN2oFjjoqfNbrd6wGpUJZdPLrWsbaNmx/EIqnUS3PdNuMCpMTj8MAipUUnKckDgvacpAcPkMtryrhgo+0FHXzOKB+xtNeMu1dZS0U6WLvaX7qfMUp2psQMTy94gxtvNsRUK3rOnXpc01n7OT6MGiBkugXA3LulrJL48RSi8obM45Q== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR03MB2370; X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2370; 31:h+XO4QeUhXtKgD+BUnppDdgYtpBM+vBIL4drY3hAmTu80U82MOPHiVSSQKLPo9FihD35xNYbOvr23UPpGVVZnBFT/5hr4HACqM7Ke++mnlY8vIe1hOjwpPbstLfMQwRGeNUHjBgv4CVXYy0s3OBd+UDALSFDZB6AaqbdYt2tFKnUzyFvz34reBqausikzjayAOifB6TyYtiJyA+d0fx9I+uqTU+K2PjFOiV/Q8eMyokUzLuaA+sIPqb13WJzxVCIYoUgyOcKbxaB0S+oiL3UbR1o4yRQtOXfhQ1rSCds/KY=; 4:iTxF2S2smagNr9ZQqcrOWc3IkIzcbrWG+fJYmlf/x6pFmZxEGBstrDsasDQbutZ8BMCB3TwTwoqoTWVPLuDiKvaERdYPPAEH3brlecjrbLLMxPoLoTxzQt0+n6Tm9cR5HbW0rwiXKgnIK1lQAfU/E9CMc4GVadwY/qRBn/VlweG2Yp19waAM9A7F8rVbWkOyrb5W4k6JZEZXrV9WbsO9yzzrgeveiZnrVjT3ckKcW65wV8ihR5sy4Tf2Z/eH0kYCFYJ3TbKubaDz/kK8URgLbsumXxbc8xbB8C+DzOTQZRTt8YIsbpSvD2ATBrbZuC3shu/shTkm0AE+xrUaJSL7muin+3LpnRbO7w7OivL056mTTDLm9q6hzCtriAAegZqKbjt3iS2nnq5JHAiaijXG015x361nSbO5PSRyOgMuVjHoDDwtMfSPYkikWcQ6BGdrWBOtmF+jnrmXhr0Hao/gGpWGUsXa1h3bm7txNi08s9Gzd2loQDDmMseIQwpveudPvjj9Bwc3wA1/PThX09rMolD6bi/U5OK7b0hEh17PIU0ZFhK/HxUsNbU0eCdklozq 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)(13018025)(13024025)(13015025)(13017025)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:BN3PR03MB2370; BCL:0; PCL:0; RULEID:(400006); SRVR:BN3PR03MB2370; X-Forefront-PRVS: 0105DAA385 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN3PR03MB2370; 23:z9yDcHmHiuX4W+FLvKYMIlRt2hFHm/EIAtq9fqhBt?= =?us-ascii?Q?b1yxWJXOyBsjI8qk8RD+D1zX0t2LyBS+5gsuzzD95n0iwdiP7OVu8Gj5jdRj?= =?us-ascii?Q?PQevuNtErmiBRQjz3yXap9/6wOj+c7DLhPRf3GoVapixRSc8/X14LgaHPNO5?= =?us-ascii?Q?qg35j1wcWR6yz3qKDIR0DONi+CQR+0CG7sfegrTDx7zpanw5HETOEbKVM0GY?= =?us-ascii?Q?NE4eSeqmJ+SMg566d5x05J8RuOxwFE8b7LXg+cgg6rZ5LvgHurCmmM5c3O1n?= =?us-ascii?Q?PSgeINV2GHfVcYJYf6Bh9aO3zWO3vuDxmfT+1pS9cUGQceun/iOFHu2ipo+b?= =?us-ascii?Q?7vVBsviqqq36XhtapVVUh6msJzcd/UbWjkUOo7kELRAO7GkTqZJEh9SCOUX7?= =?us-ascii?Q?zkLdDIL4ZXTgczUB4niMZPx0DI/EsIo3y1JtwnqTAoxHVZIPHrSBitDJ7Rnc?= =?us-ascii?Q?KGURMe7FOxdastYliYe/j5zMX4O/fIS3Lo7rwShUXRgAsTNXuog45P9wnNet?= =?us-ascii?Q?d7CoSwNnwIgprSYgXwwKHr1KwSkJpeFPY4MqZq5UNpDsgN/xDCykyjGBwiv0?= =?us-ascii?Q?FfK2MT04K+lyylgiHNTeP9D4fv0bwp4VR72BzI6cgJgdVVd2mD5EycLhDDzq?= =?us-ascii?Q?Yk71d+lYif8WvHmURD3vPiDF27ygEZjyKpuzv3dv4s6G1PQUUGnho3PDOFWp?= =?us-ascii?Q?U0hA6SnrCCvP5FmJzwlvdGc1niXErkHGKIeSYY9fBxCPgtnAX1CLNw9BimC8?= =?us-ascii?Q?ek2F7IfT1xSdqDhJZGBkRqTT4My2v4AOE6WQt5a/9ZlNf/gv8/K9EDulGAgx?= =?us-ascii?Q?BdqomzZy9VuBMUGaBHTOqQSNzWexowgZZaBL4TOnW3H/BfehfAJnO/gj45Ci?= =?us-ascii?Q?lCUWHNUiG4qMMOmuXbkFGmIUHJHa0EHB4ALPKkq4RHRagLSkjYNIDST/Zht5?= =?us-ascii?Q?4Lm1H33Kp3c4CEVqJCzevJQgK5+qRiOjk8uNYKP+NZLPTha4+9SErpYjRETw?= =?us-ascii?Q?XTz6wgtw5Dv5pPVXK2dhWEjVStcwCQKZ4XYNKhTRhIckZa0UzvT77nwHZi8e?= =?us-ascii?Q?0KhIHHsJs7PmEU0WG/hd/Mp/LQZTKVdmYGVJMSilfXOpofR1sxshrWl7+VN4?= =?us-ascii?Q?IV6SAltJ8Zpvv0yGXCCz4Z1sDCZR7rUDHgxVSezYTnTx1ivhO2XCl5P7DTzh?= =?us-ascii?Q?WZ9x0NKW1mqPbQwAKTNv88oqV4Z16hpnlmI8c5cP1NI+wVSocmSeN6OTw=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2370; 6:ICdBP3myNqu88woXhw+CBi6dpvLR3JZBWxbWem3TRBWhJJUaQ1TGfR28rsdrfv9uECePdccQDbpsy+9dqZkI/hVUgd6WRgHb85fcZHzK/SZItpnHM7uNNnfxIHGLyg7JrKdPfdX8h65HTYDoXj5tZHQO2c34FFMK0wnP3lJrbE7wC2nf4E0QD2Wi/DEPxQRGGbgHLo0zvVP4cAS6Qma1XbSxYrNCsV6UWHBXf+i9HacdGNeAyP7o2M3PSqYBArtbXjd86uoXP8NRLwsFNapsV2belO+aOvl+gH4ZRlmmphaXYuCVG99rzTBsm2Yh/+/6; 5:nvM0a9pN+5jSkMJzWinn9qPXOgcG26T4YohPupjp3aABCqk6l22USQqwhbjF+Oi9cmEJU87IPD7tUTzzysjE2BfP0iFeXk4pfCa67/P8izDlw6ZOnj1uFzQajCQkoBuD9urfxKb2HTPcIi31VswRYkoo0BEr7SyzTq0aVK5RxjjzEIZeMJxjURsBQXkq9SjU; 24:CiZS4ybc0QV65h11e4t6+YXNbrzuDXgBF6vSSywMxXaFxYU+pHZSABBzurIALcmsgflxZpQNs0dzQfDB8JrLAtL6nPIbW2/Dvmhm+JK+g1k= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN3PR03MB2370; 7:outEMffyPeF3O1phmGpygQ/IqrMNjL1lz5IwYKgrNnBrY6Ouz43EBVjNjGIp2T6yAMF/Nt53KCoW2t/+XOvAb6nESklwkAm9XDv9AbqBavpXrMt4c5hJgc7lxpixYvqptnuLP7SwvP1sKks/wREmBh9A+/0d8xi/tfonqc66z5QPedQK91kWRCm3aCM/a/0a+O0Dh1q1RR4Hg7mOrTf+8pSF/Psm8VG+y2D8/NuNQ82mu7e3v2Z2JejnyZe1M1tW1FLXTcubG6FJZ1Uzokay+NVvjSmhInZ0uum0T2TiawH6ivtnagWMni9NmMFGAnwcSX7Xg8AMQP+5/XQplNHuCvT7/3bEHU4oxDx3lSzcAd0= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Oct 2016 11:59:48.0085 (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: BN3PR03MB2370 Subject: [dpdk-dev] [PATCH v5 15/21] eal/soc: add default scan for Soc devices 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:51 -0000 From: Jan Viktorin Default implementation which scans the sysfs platform devices hierarchy. For each device, extract the ueven and convert into rte_soc_device. The information populated can then be used in probe to match against the drivers registered. Signed-off-by: Jan Viktorin [Shreyansh: restructure commit to be an optional implementation] Signed-off-by: Shreyansh Jain -- v5: - Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus - Fix comments over scan and match functions --- lib/librte_eal/common/include/rte_soc.h | 16 +- lib/librte_eal/linuxapp/eal/eal_soc.c | 315 ++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+), 2 deletions(-) diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h index 1f5f81b..a9b3129 100644 --- a/lib/librte_eal/common/include/rte_soc.h +++ b/lib/librte_eal/common/include/rte_soc.h @@ -64,7 +64,10 @@ 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 */ + union { + const char *compatible; /**< OF compatible specification */ + char *_compatible; + }; uint64_t priv_data; /**< SoC Driver specific data */ }; @@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr) } /** - * Default function for matching the Soc driver with device. Each driver can + * Helper function for scanning for new SoC devices on platform bus. + * + * @return + * 0 on success + * !0 on failure to scan + */ +int rte_eal_soc_scan_platform_bus(void); + +/** + * Helper 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 diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c index 3929a76..d8dfe97 100644 --- a/lib/librte_eal/linuxapp/eal/eal_soc.c +++ b/lib/librte_eal/linuxapp/eal/eal_soc.c @@ -48,6 +48,321 @@ #include #include +/** Pathname of SoC devices directory. */ +#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices" + +static const char * +soc_get_sysfs_path(void) +{ + const char *path = NULL; + + path = getenv("SYSFS_SOC_DEVICES"); + if (path == NULL) + return SYSFS_SOC_DEVICES; + + return path; +} + +static char * +dev_read_uevent(const char *dirname) +{ + char filename[PATH_MAX]; + struct stat st; + char *buf; + ssize_t total = 0; + int fd; + + snprintf(filename, sizeof(filename), "%s/uevent", dirname); + fd = open(filename, O_RDONLY); + if (fd < 0) { + RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename); + return strdup(""); + } + + if (fstat(fd, &st) < 0) { + RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename); + close(fd); + return NULL; + } + + if (st.st_size == 0) { + close(fd); + return strdup(""); + } + + buf = malloc(st.st_size + 1); + if (buf == NULL) { + RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n", + filename); + close(fd); + return NULL; + } + + while (total < st.st_size) { + ssize_t rlen = read(fd, buf + total, st.st_size - total); + if (rlen < 0) { + if (errno == EINTR) + continue; + + RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename); + + free(buf); + close(fd); + return NULL; + } + if (rlen == 0) /* EOF */ + break; + + total += rlen; + } + + buf[total] = '\0'; + close(fd); + + return buf; +} + +static const char * +dev_uevent_find(const char *uevent, const char *key) +{ + const size_t keylen = strlen(key); + const size_t total = strlen(uevent); + const char *p = uevent; + + /* check whether it is the first key */ + if (!strncmp(uevent, key, keylen)) + return uevent + keylen; + + /* check 2nd key or further... */ + do { + p = strstr(p, key); + if (p == NULL) + break; + + if (p[-1] == '\n') /* check we are at a new line */ + return p + keylen; + + p += keylen; /* skip this one */ + } while (p - uevent < (ptrdiff_t) total); + + return NULL; +} + +static char * +strdup_until_nl(const char *p) +{ + const char *nl = strchr(p, '\n'); + if (nl == NULL) + return strdup(p); /* no newline, copy until '\0' */ + + return strndup(p, nl - p); +} + +static int +dev_parse_uevent(struct rte_soc_device *dev, const char *uevent) +{ + const char *of; + const char *compat_n; + char *err; + long n; + char compat[strlen("OF_COMPATIBLE_NNNN=")]; + long i; + + of = dev_uevent_find(uevent, "OF_FULLNAME="); + if (of == NULL) + return 1; /* don't care about this device */ + + dev->addr.fdt_path = strdup_until_nl(of); + if (dev->addr.fdt_path == NULL) { + RTE_LOG(ERR, PMD, + "Failed to alloc memory for fdt_path\n"); + return -1; + } + + RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n", + dev->addr.name, dev->addr.fdt_path); + + compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N="); + if (compat_n == NULL) { + RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n"); + return -1; + } + + n = strtoul(compat_n, &err, 0); + if (*err != '\n' && err != NULL) { + RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n", + err); + goto fail_fdt_path; + } + + if (n == 0) + return 1; /* cannot match anything */ + if (n > 9999) { /* match NNNN */ + RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n); + goto fail_fdt_path; + } + + dev->id = calloc(n + 1, sizeof(*dev->id)); + if (dev->id == NULL) { + RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n"); + free(dev->addr.fdt_path); + return -1; + } + + for (i = 0; i < n; ++i) { + snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i); + const char *val; + + val = dev_uevent_find(uevent, compat); + if (val == NULL) { + RTE_LOG(ERR, EAL, "%s was not found\n", compat); + goto fail_id; + } + + dev->id[i]._compatible = strdup_until_nl(val); + if (dev->id[i]._compatible == NULL) { + RTE_LOG(ERR, PMD, + "Failed to alloc memory for compatible\n"); + goto fail_id; + } + + RTE_LOG(DEBUG, EAL, " compatible: %s\n", + dev->id[i].compatible); + } + + dev->id[n]._compatible = NULL; /* mark last one */ + + return 0; + +fail_id: + while (i-- >= 0) + free(dev->id[i]._compatible); + free(dev->id); +fail_fdt_path: + free(dev->addr.fdt_path); + return -1; +} + +static void +dev_content_free(struct rte_soc_device *dev) +{ + int i; + + if (dev->addr.fdt_path) + free(dev->addr.fdt_path); + + if (dev->id != NULL) { + for (i = 0; dev->id[i]._compatible; ++i) + free(dev->id[i]._compatible); + + free(dev->id); + dev->id = NULL; + } +} + +/** + * Scan one SoC sysfs entry, and fill the devices list from it. + * We require to have the uevent file with records: OF_FULLNAME and + * OF_COMPATIBLE array (with at least one entry). Otherwise, such device + * is skipped. + */ +static int +soc_scan_one(const char *dirname, const char *name) +{ + struct rte_soc_device *dev; + char *uevent; + int ret; + + uevent = dev_read_uevent(dirname); + if (uevent == NULL) + return -1; + + if (uevent[0] == '\0') { + /* ignore directory without uevent file */ + free(uevent); + return 1; + } + + dev = malloc(sizeof(*dev) + strlen(name) + 1); + if (dev == NULL) { + RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name); + free(uevent); + return -1; + } + + memset(dev, 0, sizeof(*dev)); + dev->addr.name = (char *) (dev + 1); + strcpy(dev->addr.name, name); + + ret = dev_parse_uevent(dev, uevent); + if (ret) + goto fail; + free(uevent); /* not needed anymore */ + + /* device is valid, add in list (sorted) */ + if (TAILQ_EMPTY(&soc_device_list)) { + TAILQ_INSERT_TAIL(&soc_device_list, dev, next); + } else { + struct rte_soc_device *dev2; + + TAILQ_FOREACH(dev2, &soc_device_list, next) { + ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr); + if (ret > 0) + continue; + + if (ret < 0) { + TAILQ_INSERT_BEFORE(dev2, dev, next); + } else { /* already registered */ + dev_content_free(dev2); + dev2->addr.fdt_path = dev->addr.fdt_path; + dev2->id = dev->id; + free(dev); + } + return 0; + } + TAILQ_INSERT_TAIL(&soc_device_list, dev, next); + } + + return 0; + +fail: + free(uevent); + dev_content_free(dev); + free(dev); + return ret; +} + +int +rte_eal_soc_scan_platform_bus(void) +{ + struct dirent *e; + DIR *dir; + char dirname[PATH_MAX]; + + dir = opendir(soc_get_sysfs_path()); + if (dir == NULL) { + RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n", + __func__, strerror(errno)); + return -1; + } + + while ((e = readdir(dir)) != NULL) { + if (e->d_name[0] == '.') + continue; + + snprintf(dirname, sizeof(dirname), "%s/%s", + soc_get_sysfs_path(), e->d_name); + if (soc_scan_one(dirname, e->d_name) < 0) + goto error; + } + closedir(dir); + return 0; + +error: + closedir(dir); + return -1; +} + /* Init the SoC EAL subsystem */ int rte_eal_soc_init(void) -- 2.7.4