From patchwork Wed Sep 9 17:21:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emil Velikov X-Patchwork-Id: 7147701 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 14AFEBEEC1 for ; Wed, 9 Sep 2015 17:17:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 08BB320567 for ; Wed, 9 Sep 2015 17:17:39 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id E4B7E20A09 for ; Wed, 9 Sep 2015 17:17:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 224926EC89; Wed, 9 Sep 2015 10:17:37 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wi0-f179.google.com (mail-wi0-f179.google.com [209.85.212.179]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2CA626EC8A for ; Wed, 9 Sep 2015 10:17:35 -0700 (PDT) Received: by wicge5 with SMTP id ge5so163585993wic.0 for ; Wed, 09 Sep 2015 10:17:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HMnERKsuM1rt/spKt9RoYlAx6j2cMqxrgDUrlWx7/48=; b=PivlNOQ8kr8FVXWDvGgFNYHM7A6yq/EDnUa3180Xt0NKeqkay8F+w5EZuQjtQX55+Z GY6N7DuCaSuqU0+1yMlObrtOfX4BNpdO08z2Mb6kneP98k+Mz1bcXf3rTeOTSvVpTgqF PCNkLx9dCq+MiticR2aiOU/BQP8GeM0DlfM4CVHzOHflGoS13uXpH3s5Z0ySQ3leqm+d jCaa/hfHeK2goYCpVJBZcPjUj29kSB58QzWKfvcUGnS7HX640YelQioTQtCae0Nadc/x i5X+ivqNG4iWCDm+w4RfNa+ZZ13PYs9HDoiwGxqW2sSwUSZo08A9KTUPchbluroCeUIq gXuQ== X-Received: by 10.194.91.193 with SMTP id cg1mr52579489wjb.88.1441819053972; Wed, 09 Sep 2015 10:17:33 -0700 (PDT) Received: from arch-x220.localdomain (cpc12-croy20-2-0-cust52.croy.cable.virginm.net. [82.44.54.53]) by smtp.gmail.com with ESMTPSA id j7sm11257042wjz.11.2015.09.09.10.17.32 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Sep 2015 10:17:33 -0700 (PDT) From: Emil Velikov To: dri-devel@lists.freedesktop.org Subject: [PATCH libdrm 11/12] xf86drm: add drm{Get,Free}Device Date: Wed, 9 Sep 2015 18:21:32 +0100 Message-Id: <1441819293-25567-12-git-send-email-emil.l.velikov@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1441819293-25567-1-git-send-email-emil.l.velikov@gmail.com> References: <1441819293-25567-1-git-send-email-emil.l.velikov@gmail.com> Cc: emil.l.velikov@gmail.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Similar interface to the *Devices() ones but they obtain/free the information of the opened device (as given by its fd). Note there is a fair bit of duplication between the two Get functions, and anyone interested is more than welcome to consolidate it. Signed-off-by: Emil Velikov --- xf86drm.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- xf86drm.h | 3 ++ 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/xf86drm.c b/xf86drm.c index aa0fbe4..789bfc2 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2982,7 +2982,7 @@ static int drmParsePciDeviceInfo(const char *d_name, #endif } -static void drmFreeDevice(drmDevicePtr *device) +void drmFreeDevice(drmDevicePtr *device) { if (device == NULL) return; @@ -3072,6 +3072,119 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count) } /** + * Get information about the opened drm device + * + * \param fd file descriptor of the drm device + * \param device the address of a drmDevicePtr where the information + * will be allocated in stored + * + * \return zero on success, negative error code otherwise. + */ +int drmGetDevice(int fd, drmDevicePtr *device) +{ + drmDevicePtr *local_devices; + drmDevicePtr d; + DIR *sysdir; + struct dirent *dent; + struct stat sbuf; + char node[PATH_MAX + 1]; + int node_type, subsystem_type; + int maj, min; + int ret, i, node_count; + int max_count = 16; + + if (fd == -1 || device == NULL) + return -EINVAL; + + if (fstat(fd, &sbuf)) + return -errno; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) + return -EINVAL; + + subsystem_type = drmParseSubsystemType(maj, min); + + local_devices = calloc(max_count, sizeof(drmDevicePtr)); + if (local_devices == NULL) + return -ENOMEM; + + sysdir = opendir(DRM_DIR_NAME); + if (!sysdir) { + ret = -errno; + goto close_sysdir; + } + + i = 0; + while ((dent = readdir(sysdir))) { + node_type = drmGetNodeType(dent->d_name); + if (node_type < 0) + continue; + + snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); + if (stat(node, &sbuf)) + continue; + + maj = major(sbuf.st_rdev); + min = minor(sbuf.st_rdev); + + if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) + continue; + + if (drmParseSubsystemType(maj, min) != subsystem_type) + continue; + + switch (subsystem_type) { + case DRM_BUS_PCI: + ret = drmProcessPciDevice(&d, dent->d_name, node, node_type, + maj, min, true); + if (ret) + goto free_devices; + + break; + default: + fprintf(stderr, "The subsystem type is not supported yet\n"); + break; + } + + if (i >= max_count) { + drmDevicePtr *temp; + + max_count += 16; + temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); + if (!temp) + goto free_devices; + local_devices = temp; + } + + local_devices[i] = d; + i++; + } + node_count = i; + + /* Fold nodes into a single device if they share the same bus info */ + drmFoldDuplicatedDevices(local_devices, node_count); + + *device = local_devices[0]; + for (i = 1; i < node_count && local_devices[i]; i++) + drmFreeDevice(&local_devices[i]); + + free(local_devices); + closedir(sysdir); + return 0; + +free_devices: + drmFreeDevices(local_devices, i); + free(local_devices); + +close_sysdir: + closedir(sysdir); + return ret; +} + +/** * Get drm devices on the system * * \param devices the array of devices with drmDevicePtr elements diff --git a/xf86drm.h b/xf86drm.h index e82ca84..481d882 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -790,6 +790,9 @@ typedef struct _drmDevice { } deviceinfo; } drmDevice, *drmDevicePtr; +extern int drmGetDevice(int fd, drmDevicePtr *device); +extern void drmFreeDevice(drmDevicePtr *device); + extern int drmGetDevices(drmDevicePtr devices[], int max_devices); extern void drmFreeDevices(drmDevicePtr devices[], int count);