From patchwork Fri Dec 2 16:32:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Emil Velikov X-Patchwork-Id: 9458877 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A789760515 for ; Fri, 2 Dec 2016 16:33:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 966F728568 for ; Fri, 2 Dec 2016 16:33:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B3D228575; Fri, 2 Dec 2016 16:33:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 0E0772856D for ; Fri, 2 Dec 2016 16:33:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F280C6E94D; Fri, 2 Dec 2016 16:33:08 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 41E436E976 for ; Fri, 2 Dec 2016 16:33:07 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id u144so3531205wmu.0 for ; Fri, 02 Dec 2016 08:33:07 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=k/jdtwBOAEfz3R+K3WB7cUNrwYGFt+hegoKK6AbZMBw=; b=UuRWH9n0xlSI1XjOIuShBJWZH+kJJ4yU/Vx3p6X1FVPuR3o5OxEi3t4Cqjfvns67nd Tjix2P+a0ye12R3Nmc27ExfCY5QPspw8v9/3Bh3ce6t1sohpcGDlPuSkEPsEqxfv7KFM /gfByakBu42Ep2GzzRDbGN3Vf1FVaiV1k1sJjBXOnzbXFn5vAuYkHjTXR2WLN/4qZ1tL spUi1UnFzAhgQkhIdjx4D6BSWRMiJkEe5mNVg5cuIGThvnAEiL5fUCurxQfsbxPBrNUW //deeavCKRYRsYLVb9IuY/kTmXWPkFHbwp410wwoQfUK7NphPYCWqX/CLPzn43JSkceo bh1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=k/jdtwBOAEfz3R+K3WB7cUNrwYGFt+hegoKK6AbZMBw=; b=XuL8Nj7N2wngteEhE8T0L45/ocfiAA2GXmTSnsMACSTVFd+UpTO/lgl7I5ylVjgI4D ezyJUrGRGLgOEPCNwVnNNVXndAt0UfmJrRN5oibZw7U3lfdjcqgLek3qtxTmLYGj8CTA 2RQdqAxPfeY1ln0nv4LI1IltyF+9/wmccdUIsbOu0BkQyLP3sLee6+iCe8JLdlYeeNJk +rg5qmUjX49NKJLl2AvGloRW3cG9MytsWazwzFuZFajdixDzSWgQmd3R6vTvRtSpRpDD LyC50mnbUzSiaZBD8bb1eDfrKYEZhjdoUNGE7A4gUMdGEjvb/7nawT9yfOutqEbD5UiT utDw== X-Gm-Message-State: AKaTC014eZiOnhgpGO0mh10kQGvN8Avkyh9NjPDhtgPR2hxJ7fFTb+koxXg6wKN3yLGjyA== X-Received: by 10.28.90.65 with SMTP id o62mr3619894wmb.80.1480696385325; Fri, 02 Dec 2016 08:33:05 -0800 (PST) Received: from arch-x1c3.cbg.collabora.co.uk ([2a00:1098:5:0:9665:9cff:feee:aa4d]) by smtp.gmail.com with ESMTPSA id b7sm6331517wjm.39.2016.12.02.08.33.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 02 Dec 2016 08:33:04 -0800 (PST) From: Emil Velikov To: dri-devel@lists.freedesktop.org Subject: [PATCH libdrm 4/5] xf86drm: introduce drmGetDevice[s]2 Date: Fri, 2 Dec 2016 16:32:37 +0000 Message-Id: <20161202163238.15849-4-emil.l.velikov@gmail.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161202163238.15849-1-emil.l.velikov@gmail.com> References: <20161202163238.15849-1-emil.l.velikov@gmail.com> MIME-Version: 1.0 Cc: Mauro Santos , =?UTF-8?q?Michel=20D=C3=A4nzer?= , 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Emil Velikov Relative to the original version, here one can provide a flags bitmask. Currently only DRM_DEVICE_IGNORE_PCI_REVISION is supported. Implementation detail: If it's set, we will only parse the separate sysfs files and we won't touch the config one. The latter awakes the device (causing delays) which is the core reason why this API was introduced. v2: - Initialize revision to 0xff if it's unread. - Change DRM_DEVICE_IGNORE_PCI_REVISION to DRM_DEVICE_GET_PCI_REVISION - Add explicit note that drmGetDevice[s]2 does not retrieve the revision by default. Cc: Michel Dänzer Cc: Nicolai Hähnle Cc: Mauro Santos Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98502 Signed-off-by: Emil Velikov Reviewed-by: Michel Dänzer --- xf86drm.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- xf86drm.h | 4 ++++ 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/xf86drm.c b/xf86drm.c index 701cf29..52e9b9f 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -2948,7 +2948,8 @@ static int drmGetMaxNodeName(void) #ifdef __linux__ static int parse_separate_sysfs_files(int maj, int min, - drmPciDeviceInfoPtr device) + drmPciDeviceInfoPtr device, + bool ignore_revision) { #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) static const char *attrs[] = { @@ -2963,7 +2964,7 @@ static int parse_separate_sysfs_files(int maj, int min, FILE *fp; int ret; - for (unsigned i = 0; i < ARRAY_SIZE(attrs); i++) { + for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) { snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min, attrs[i]); fp = fopen(path, "r"); @@ -2977,7 +2978,7 @@ static int parse_separate_sysfs_files(int maj, int min, } - device->revision_id = data[0] & 0xff; + device->revision_id = ignore_revision ? 0xff : data[0] & 0xff; device->vendor_id = data[1] & 0xffff; device->device_id = data[2] & 0xffff; device->subvendor_id = data[3] & 0xffff; @@ -3018,7 +3019,10 @@ static int drmParsePciDeviceInfo(int maj, int min, uint32_t flags) { #ifdef __linux__ - if (parse_separate_sysfs_files(maj, min, device)) + if (flags & DRM_DEVICE_GET_PCI_REVISION == 0) + return parse_separate_sysfs_files(maj, min, device, true); + + if (parse_separate_sysfs_files(maj, min, device, false)) return parse_config_sysfs_file(maj, min, device); return 0; @@ -3125,16 +3129,27 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count) } } +/* Check that the given flags are valid returning 0 on success */ +static int +drm_device_validate_flags(uint32_t flags) +{ + return (flags & ~DRM_DEVICE_GET_PCI_REVISION); +} + /** * Get information about the opened drm device * * \param fd file descriptor of the drm device + * \param flags feature/behaviour bitmask * \param device the address of a drmDevicePtr where the information * will be allocated in stored * * \return zero on success, negative error code otherwise. + * + * \note Unlike drmGetDevice it does not retrieve the pci device revision field + * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set. */ -int drmGetDevice(int fd, drmDevicePtr *device) +int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) { drmDevicePtr *local_devices; drmDevicePtr d; @@ -3147,7 +3162,9 @@ int drmGetDevice(int fd, drmDevicePtr *device) int ret, i, node_count; int max_count = 16; dev_t find_rdev; - uint32_t flags = 0; + + if (drm_device_validate_flags(flags)) + return -EINVAL; if (fd == -1 || device == NULL) return -EINVAL; @@ -3246,8 +3263,23 @@ free_locals: } /** + * 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) +{ + return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device); +} + +/** * Get drm devices on the system * + * \param flags feature/behaviour bitmask * \param devices the array of devices with drmDevicePtr elements * can be NULL to get the device number first * \param max_devices the maximum number of devices for the array @@ -3256,8 +3288,11 @@ free_locals: * if devices is NULL - total number of devices available on the system, * alternatively the number of devices stored in devices[], which is * capped by the max_devices. + * + * \note Unlike drmGetDevices it does not retrieve the pci device revision field + * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set. */ -int drmGetDevices(drmDevicePtr devices[], int max_devices) +int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) { drmDevicePtr *local_devices; drmDevicePtr device; @@ -3269,7 +3304,9 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices) int maj, min; int ret, i, node_count, device_count; int max_count = 16; - uint32_t flags = 0; + + if (drm_device_validate_flags(flags)) + return -EINVAL; local_devices = calloc(max_count, sizeof(drmDevicePtr)); if (local_devices == NULL) @@ -3357,6 +3394,23 @@ free_locals: return ret; } +/** + * Get drm devices on the system + * + * \param devices the array of devices with drmDevicePtr elements + * can be NULL to get the device number first + * \param max_devices the maximum number of devices for the array + * + * \return on error - negative error code, + * if devices is NULL - total number of devices available on the system, + * alternatively the number of devices stored in devices[], which is + * capped by the max_devices. + */ +int drmGetDevices(drmDevicePtr devices[], int max_devices) +{ + return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices); +} + char *drmGetDeviceNameFromFd2(int fd) { #ifdef __linux__ diff --git a/xf86drm.h b/xf86drm.h index 4da6bd3..b340fc4 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -801,6 +801,10 @@ extern void drmFreeDevice(drmDevicePtr *device); extern int drmGetDevices(drmDevicePtr devices[], int max_devices); extern void drmFreeDevices(drmDevicePtr devices[], int count); +#define DRM_DEVICE_GET_PCI_REVISION (1 << 0) +extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device); +extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices); + #if defined(__cplusplus) } #endif