From patchwork Sat Oct 15 13:45:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 16607 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 89AFA8D8F; Sat, 15 Oct 2016 15:44:56 +0200 (CEST) Received: from NAM02-CY1-obe.outbound.protection.outlook.com (mail-cys01nam02on0068.outbound.protection.outlook.com [104.47.37.68]) by dpdk.org (Postfix) with ESMTP id 092218D88 for ; Sat, 15 Oct 2016 15:44:50 +0200 (CEST) Received: from BN3PR0301CA0042.namprd03.prod.outlook.com (10.160.180.180) by BLUPR03MB328.namprd03.prod.outlook.com (10.141.48.27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.669.12; Sat, 15 Oct 2016 13:44:48 +0000 Received: from BN1AFFO11FD010.protection.gbl (2a01:111:f400:7c10::105) by BN3PR0301CA0042.outlook.office365.com (2a01:111:e400:4000::52) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.659.11 via Frontend Transport; Sat, 15 Oct 2016 13:44: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 BN1AFFO11FD010.mail.protection.outlook.com (10.58.52.70) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.669.7 via Frontend Transport; Sat, 15 Oct 2016 13:44:47 +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 u9FDhhgR021870; Sat, 15 Oct 2016 06:44:44 -0700 From: Shreyansh Jain To: CC: , , , Shreyansh Jain Date: Sat, 15 Oct 2016 19:15:02 +0530 Message-ID: <1476539108-13170-12-git-send-email-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476539108-13170-1-git-send-email-shreyansh.jain@nxp.com> References: <1473410639-10367-1-git-send-email-shreyansh.jain@nxp.com> <1476539108-13170-1-git-send-email-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131210126875242306; (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)(1109001)(1110001)(339900001)(199003)(189002)(586003)(8676002)(33646002)(8936002)(11100500001)(8666005)(626004)(6916009)(6666003)(50466002)(2950100002)(50226002)(5003940100001)(104016004)(5660300001)(85426001)(2906002)(305945005)(92566002)(68736007)(81156014)(7846002)(4326007)(81166006)(86362001)(87936001)(2351001)(189998001)(47776003)(229853001)(97736004)(106466001)(36756003)(77096005)(48376002)(19580405001)(105606002)(50986999)(110136003)(76176999)(19580395003)(356003)(7059030)(403724002); DIR:OUT; SFP:1101; SCL:1; SRVR:BLUPR03MB328; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD010; 1:hI3Eg5Ns9bSbwIlrAvPoQ+IuQXUF/Av4j74h4xC5xB9r9WE0hJWkQCKmgAP5QD9m+YG2cQBRyeT30Cs4IwFSWMFCpFxOlbFGiB5y55JgQU+Ds8xVO8n0PX94IQwhWoKwKlIvZZdW6IBnWagbJAvV3wuixWDbPaAd2j2pj80cPgup+jNa4vAn9Vpf37xrnyTe7964GAJQgbBWmyL/kMLjl0AxY760P5kTX3Ro7mDdGfv5tl9U6y516anJ+JoQAqTESOUsD747qD5/pohx3ZHUEEQ1Lhl0giJ8T78P/h8Tcg10rpJynbmeFadqcUAMWayHzTWRy1T93NXeXvjsInRhulFnGwmrg/v3as1Rwc5HGjcLtOK2McBdDTxKX3y8rZ4AinFLijIFn+IoE3LRSg6+kbofETtP3WDKAGlkxMHte17+WtpacEC/QP9uTv32jg+K8VAncuEiZwtteOHEGSjEKwYt9mP+S4HzrDEWP258i9Zzu8vRFDslTEz3uHPXf794q/znk2QCYw56Moqpz+WAzThHvoOkH9gFNnrMAAWE7kHYcwJMNHVbS1IiXkEC5YZSxJgqha9t8FJ13jqOgEuw9SRtDBXm+aj6sOqnipmwJj3SubXnOB7XyYBE85xgh11CZ88AQFfzcy67g3IHGSqat7TH9uRJPLSzaDnRU1IT9e62bbu9aRNY67ETIJy50dsYIMvxbrJiiKDrKJFLb5WilXw9AEkxaFDUAKT+rZQNqBw= MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: f0a7470b-42f7-49cc-2f42-08d3f5016dcc X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB328; 2:vF5SeUk3XkMkWakHh7yrACPBHENvJXe4gBCKuLIjegxL5Xc7L2SZVOwf+q2CkOD+nTcf8A84aHc3smP//D0RBF5jjSmUjzw8MKNsUiregVJ2rIFDshjLq0B9HqjtuWAdIxvR2Sk6mHlsehX0VGfTfvwFu8b6YRX5Mh1E5a2ohVSofai1thp76AALwfeIHl/LEQkKx1UjubrXnI8CqYJB5g==; 3:GfAzhISbL8GmfEe/7f+qqqHQecXsJO0FcSustNyeMtLiVo+KU/NcyoR19ST8dVjXlCvg+ZwNobFZXqyZJBcAeiSJjUdfs+L8KROZ+9Lye465TuFkgZIKUpVW5rhJEIv3iOI/CSZIp3RCL5McYKpn162TEXbzaBptTfcSv3gvUXeRiGmWl7YG3K2ACeCttP/3lrwVBB1zvOElkJmWH1/t9s7cPtACwIXUrXgIoND0MrJKUJnI4eH93Bz44ow2fU/X; 25:ijLNkIq227lj0iSrC5T5zeIEbic7sPPDmIoL8vacccCYA6RKB2h+j26vblf9GWQEK4mdRHBByA6UnVdaCfB8l6cUcmOoiXRYGEXAOi7T/RuY85JAE76vDBWHuPQOeReoQj/dfIn3B5cxBW3hBXWtA/OMmZ4HYtF+q+YrYjy3O7q0EXFaekkn9LLXfpzJUTwDtBG9v5Y3My8spt9TDcy20YwnZrrNXLwHkYboHT+YC5Xp6KeT4BXoTeEdOEOdyVR0/j5A3/q1WyMLPesAOkK8smpqotbmdXimJkM9VaPguyoJ86P5Bta5sDG6xez31HwGr/pLXhkVznxI9KdWcVsyO5KWfgdwWifGFzz2HITYcRGuR7omV6M1eWqA5uNCAaSziWpxeDufapQmrfJ7QSbOo7Ppu4BH4iQMYuhoCcfbwrCp7HGzN3TtZkYkgBHILEy67YpC+qC93go9upLCrmGSIA== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB328; X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB328; 31:nh+s4wWcGfUJZiDPiZmW5eqWz7sRvWP2w/TgHS1BZAPSngv2t5Hn/bfXyMZgJpLTXyqvBCXKXGXp1Z7108m8qRnInECTA1ZHg1yobtfYehld41nMCTdP9yLXeVxcjO8wrg7Xmlduf9g1MRrV2KrVVmML2LZKtC7xQaYU2KY1DQ+ynvm25bOf4r9+IBkOKhLIU+D5nTNKGMPmF7o+GYYa4v8hQrarWmfWL3hwvWdUFlGVm5eXA/GmuQNMpJFuf2pKz7cXXI1nyx+0vsAWFITQBbKnkg+dHtXZ8a6deppWKT0=; 4:KhpYr5FScJ9Q3dufognVQdBXWNLN2td5JbqEOAPg5dZKcRts6CozgvazcNWNg4UweGLHg0EN9lXkyNJaylktv8K5tcP57jHTLLik4Lk9xevUKo+33nQ/RQ1UgYJrISz5aV6+hy51DFVFxftDzDh5FJa7kGgiPa8VBxzqTT06B4yFk/4d6Gew9ccRhvvUMaLvSVYS3VvEfMznYDKwvwoHI+5uCN4SvrNk+Pe6ToJgAgdKF2oFw89lWKvuAnAUcGYzVEisMZTqOhN8F3Qgm9JsPp+Uag0gX6Grfvz8jpUCcZsNsF18jfUbLluv8RQ9mqHjETEY6DuI4vLqMSnALBsfqmBXGqOgv8P7pHA5icJy5MEGP9Im4sU0d2mibLD0QDGU8MB8pWL3m/9RS9Al9kBLu6t5HS3l6rx/knME5RkJzQdDFSzpDC7kC1hVRZFI6NNsApykp/HAoUnSQ8Y0W1Jh2MmVrbCezDaLSKLWi+FFhvcj5BMkIc5w1a70zUzt2Sgi7zSKxhHLTYGjj2Oz+1+rSPMvsuSe+thT1FGDfqTtTKHpvR7zswPG3rnTGUloKOgp 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)(8121501046)(13023025)(13017025)(13024025)(13018025)(13015025)(5005006)(3002001)(10201501046)(6055026); SRVR:BLUPR03MB328; BCL:0; PCL:0; RULEID:(400006); SRVR:BLUPR03MB328; X-Forefront-PRVS: 00963989E5 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BLUPR03MB328; 23:UxVm77hcgEjfMIbBV6ZPiyXfT67ixFLtGnUvOi0Vmr?= =?us-ascii?Q?bV9k+EBJAZ4QypdWGjzQ78bh4efK2epqECaqUUNYZH52XUPBtF4ohbOT+Tnt?= =?us-ascii?Q?9/OWdqOu3FmfPeSndVohcQqXmilNueciWGMuWF8u+mCLMhLhbW0VCNuQhoMd?= =?us-ascii?Q?3bYq/qRvI/GKN3XOY9vE8j0W/lZaBjKcLWuDLC9gVTiulbCuOJ387FWlZQHT?= =?us-ascii?Q?qOlr4a6gf8MgI66RlLIX3tgJdUSwRQ/IaiUKeMlV+5A8hLCR8fJVoKSrU4sC?= =?us-ascii?Q?/F0oNHT0KJ+KKBvmSyRDbkzzRJ6+5oti6UNaHXq6wI+/YDfiWk88ioSKx+HF?= =?us-ascii?Q?pGFOXm+3iBvaxqA+81zViuPTNx/u3vSjcwPV9i+oLCajLl0+FN9d7Zl4IC6V?= =?us-ascii?Q?1x+ppv8pE91KnLFc6T5+VZp2O9EXz1uo3KtTeXiYRXnWRpObomhEwqJsbZJE?= =?us-ascii?Q?mImAQDuGlGSglfM0aaAM07ydny45avQqiB7OAN3pwCPasAA00Ib6px7edRQf?= =?us-ascii?Q?nPjFD536KwNLcyGIJS3O5vgn2EP9INixRNuXA9K9CV+evlm9GtgOrskzOFv1?= =?us-ascii?Q?1xpb8H3bL4UoYbUYy3YpamNHNBj40zFPwkm9dK4CkT0A9kx/9WeZP+vh71GP?= =?us-ascii?Q?qsUes4t5KAhSWDlNtszY+AJoaWOet73X6lYUGhUI63YLZ9XAmJS8sI2zL2OW?= =?us-ascii?Q?yce4LVJbroj/gUT/rW9uOcz3It55jzHnyz+rg/reoUsvZ8ibOxLuCkHjbOwx?= =?us-ascii?Q?422AcE6AdVhHmD+V9PLUK4NkQGSBrvYFg30SC8bIlVkFno7eAAt5EjaftZC7?= =?us-ascii?Q?cYHg+6aEIehViXQ/gLC0BMwqfg/9e9TLOxlJgnnhGfiKNOP+3MwdjcQ05LC+?= =?us-ascii?Q?GxR3Jm9MlpSwXQ/2Af8I0qjfHUrSYSoGWtGpVYU/qZzlyO6HT/Ci25DvhX3B?= =?us-ascii?Q?jzRHtEpu7t3tdmkFJGLlaJQQue1Vi6ezxDZAtJccXCZ/PgdEWngds6wDsjNv?= =?us-ascii?Q?rRr1zHDJCNdre82GAqzb9s8Oi/8q7oW0CRhF4avcL0IhnrCGJ4E5KMbLLiOm?= =?us-ascii?Q?g3VEhBszOtyV02FAlY9b0HRwA/2L5nkbSsjnp/9PEyH+snvZwprZVhi7AS8E?= =?us-ascii?Q?hyBSgNBNJPbpUuaSb3vovzsm76wrDZPGgTISGcCXao1MbD8iw3wQT2s6Of4B?= =?us-ascii?Q?r7GXaDHI+q1MIJakmEUvR9wCkKcUrmkvu+I7uH/wYnUpUxcux+31LlwA=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB328; 6:JKT44V+visvggMh2+jB/sint0ZPM8pnRq4ns4NrRtyMdTk7Nw26wkihaiJqSSP2ZwsgUdLhyzc4p4ERDW6LitKcZLzO1wsphKOnVXSck5EfoB7w3FglacsWK39p4Y6PmV9u8ZEAj1VtmtHrrtS6Rncn17nAUdsKhSSt4ejeaI+DhFrXj0KMYvQxHp2uvG8VaWti00qA9mEeCAdxUvjhII+BZJTEgUpEwYapfyWzzJVhtCxNVVzkTmBYLbT2MmL1CT+ckhnq+7ldbT+rUjZ411b9OG5aQVksBozHhxYlI0qpkEBtQ1x0ZphCHWNWdvCy+; 5:DHcqgu4IG8judTsQTfUfWmIZeIEPS+GolFgVPNVshBxTpXBoslb/LZ/tRIg7SQYfyIcvVr+H43lax9TDheScQgFkBftXc4jtaV49+5S5vV0yllCbdT5Vj9VPTjouGqJuPUfVXRhsSIZOIp9UUohoDQ39lcFBvmKF7Y8IO007936MC588jtyuLcLaecAR8U1E; 24:zbUs2gmxetmC8o3TaE5sdbGKuqhM8rI2PPe+LWP6U7bHhEBQJKf6lZKXWbGkv/FbVLTNI/AhhyqN4zQ+rYk28Fz6OoI7L31MyGZx6pWSH1Q= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BLUPR03MB328; 7:tLE2ti3mFMYBPuPtJTiamRjf65fT+iX+hXFJsb+Qpf3n82YBNCEOossVusOkr+yd2Ykpb89Ch1yaOSgbpsoc2eMMnbLSqHVZzILPv8nkjXEHMyCWgxEFFTSMk7Z25udizwpGxzgp+xVgjL6ukXrmVmUNZxVjjMLSk+mh80nlTlKbDU0l3tXTlmOZVUmsk6hTeXuNarehoWKj4gM/avHKBo5avA60wcnNP18zt7ij8z/q6ZFEnzy2CBaa2HZjkqks+kbe5j+3HKDrZwpBr8LRHJ5xAMO6m2qNRZ7YN0PErdvkiaeX05Ncz/wcD5fxliGMWzk5cASoCHX5EdpArMw1nSwl6xRIFSRGjxhCnbnIwAw= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Oct 2016 13:44:47.2590 (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: BLUPR03MB328 Subject: [dpdk-dev] [PATCH v4 11/17] 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- lib/librte_eal/common/include/rte_soc.h | 10 +- lib/librte_eal/linuxapp/eal/eal_soc.c | 315 ++++++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h index 1f5f81b..1865be5 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,6 +203,11 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr) } /** + * Scan for new SoC devices. + */ +int rte_eal_soc_scan(void); + +/** * 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, diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c index 3929a76..d8286bb 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(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)