aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xf86drm.c70
-rw-r--r--xf86drm.h4
2 files changed, 66 insertions, 8 deletions
diff --git a/xf86drm.c b/xf86drm.c
index 701cf291..a886768e 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -2948,7 +2948,8 @@ static int drmGetMaxNodeName(void)
2948 2948
2949#ifdef __linux__ 2949#ifdef __linux__
2950static int parse_separate_sysfs_files(int maj, int min, 2950static int parse_separate_sysfs_files(int maj, int min,
2951 drmPciDeviceInfoPtr device) 2951 drmPciDeviceInfoPtr device,
2952 bool ignore_revision)
2952{ 2953{
2953#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 2954#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
2954 static const char *attrs[] = { 2955 static const char *attrs[] = {
@@ -2963,7 +2964,7 @@ static int parse_separate_sysfs_files(int maj, int min,
2963 FILE *fp; 2964 FILE *fp;
2964 int ret; 2965 int ret;
2965 2966
2966 for (unsigned i = 0; i < ARRAY_SIZE(attrs); i++) { 2967 for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {
2967 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min, 2968 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min,
2968 attrs[i]); 2969 attrs[i]);
2969 fp = fopen(path, "r"); 2970 fp = fopen(path, "r");
@@ -2977,7 +2978,7 @@ static int parse_separate_sysfs_files(int maj, int min,
2977 2978
2978 } 2979 }
2979 2980
2980 device->revision_id = data[0] & 0xff; 2981 device->revision_id = ignore_revision ? 0xff : data[0] & 0xff;
2981 device->vendor_id = data[1] & 0xffff; 2982 device->vendor_id = data[1] & 0xffff;
2982 device->device_id = data[2] & 0xffff; 2983 device->device_id = data[2] & 0xffff;
2983 device->subvendor_id = data[3] & 0xffff; 2984 device->subvendor_id = data[3] & 0xffff;
@@ -3018,7 +3019,10 @@ static int drmParsePciDeviceInfo(int maj, int min,
3018 uint32_t flags) 3019 uint32_t flags)
3019{ 3020{
3020#ifdef __linux__ 3021#ifdef __linux__
3021 if (parse_separate_sysfs_files(maj, min, device)) 3022 if (!(flags & DRM_DEVICE_GET_PCI_REVISION))
3023 return parse_separate_sysfs_files(maj, min, device, true);
3024
3025 if (parse_separate_sysfs_files(maj, min, device, false))
3022 return parse_config_sysfs_file(maj, min, device); 3026 return parse_config_sysfs_file(maj, min, device);
3023 3027
3024 return 0; 3028 return 0;
@@ -3125,16 +3129,27 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
3125 } 3129 }
3126} 3130}
3127 3131
3132/* Check that the given flags are valid returning 0 on success */
3133static int
3134drm_device_validate_flags(uint32_t flags)
3135{
3136 return (flags & ~DRM_DEVICE_GET_PCI_REVISION);
3137}
3138
3128/** 3139/**
3129 * Get information about the opened drm device 3140 * Get information about the opened drm device
3130 * 3141 *
3131 * \param fd file descriptor of the drm device 3142 * \param fd file descriptor of the drm device
3143 * \param flags feature/behaviour bitmask
3132 * \param device the address of a drmDevicePtr where the information 3144 * \param device the address of a drmDevicePtr where the information
3133 * will be allocated in stored 3145 * will be allocated in stored
3134 * 3146 *
3135 * \return zero on success, negative error code otherwise. 3147 * \return zero on success, negative error code otherwise.
3148 *
3149 * \note Unlike drmGetDevice it does not retrieve the pci device revision field
3150 * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
3136 */ 3151 */
3137int drmGetDevice(int fd, drmDevicePtr *device) 3152int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
3138{ 3153{
3139 drmDevicePtr *local_devices; 3154 drmDevicePtr *local_devices;
3140 drmDevicePtr d; 3155 drmDevicePtr d;
@@ -3147,7 +3162,9 @@ int drmGetDevice(int fd, drmDevicePtr *device)
3147 int ret, i, node_count; 3162 int ret, i, node_count;
3148 int max_count = 16; 3163 int max_count = 16;
3149 dev_t find_rdev; 3164 dev_t find_rdev;
3150 uint32_t flags = 0; 3165
3166 if (drm_device_validate_flags(flags))
3167 return -EINVAL;
3151 3168
3152 if (fd == -1 || device == NULL) 3169 if (fd == -1 || device == NULL)
3153 return -EINVAL; 3170 return -EINVAL;
@@ -3246,8 +3263,23 @@ free_locals:
3246} 3263}
3247 3264
3248/** 3265/**
3266 * Get information about the opened drm device
3267 *
3268 * \param fd file descriptor of the drm device
3269 * \param device the address of a drmDevicePtr where the information
3270 * will be allocated in stored
3271 *
3272 * \return zero on success, negative error code otherwise.
3273 */
3274int drmGetDevice(int fd, drmDevicePtr *device)
3275{
3276 return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device);
3277}
3278
3279/**
3249 * Get drm devices on the system 3280 * Get drm devices on the system
3250 * 3281 *
3282 * \param flags feature/behaviour bitmask
3251 * \param devices the array of devices with drmDevicePtr elements 3283 * \param devices the array of devices with drmDevicePtr elements
3252 * can be NULL to get the device number first 3284 * can be NULL to get the device number first
3253 * \param max_devices the maximum number of devices for the array 3285 * \param max_devices the maximum number of devices for the array
@@ -3256,8 +3288,11 @@ free_locals:
3256 * if devices is NULL - total number of devices available on the system, 3288 * if devices is NULL - total number of devices available on the system,
3257 * alternatively the number of devices stored in devices[], which is 3289 * alternatively the number of devices stored in devices[], which is
3258 * capped by the max_devices. 3290 * capped by the max_devices.
3291 *
3292 * \note Unlike drmGetDevices it does not retrieve the pci device revision field
3293 * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
3259 */ 3294 */
3260int drmGetDevices(drmDevicePtr devices[], int max_devices) 3295int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
3261{ 3296{
3262 drmDevicePtr *local_devices; 3297 drmDevicePtr *local_devices;
3263 drmDevicePtr device; 3298 drmDevicePtr device;
@@ -3269,7 +3304,9 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
3269 int maj, min; 3304 int maj, min;
3270 int ret, i, node_count, device_count; 3305 int ret, i, node_count, device_count;
3271 int max_count = 16; 3306 int max_count = 16;
3272 uint32_t flags = 0; 3307
3308 if (drm_device_validate_flags(flags))
3309 return -EINVAL;
3273 3310
3274 local_devices = calloc(max_count, sizeof(drmDevicePtr)); 3311 local_devices = calloc(max_count, sizeof(drmDevicePtr));
3275 if (local_devices == NULL) 3312 if (local_devices == NULL)
@@ -3357,6 +3394,23 @@ free_locals:
3357 return ret; 3394 return ret;
3358} 3395}
3359 3396
3397/**
3398 * Get drm devices on the system
3399 *
3400 * \param devices the array of devices with drmDevicePtr elements
3401 * can be NULL to get the device number first
3402 * \param max_devices the maximum number of devices for the array
3403 *
3404 * \return on error - negative error code,
3405 * if devices is NULL - total number of devices available on the system,
3406 * alternatively the number of devices stored in devices[], which is
3407 * capped by the max_devices.
3408 */
3409int drmGetDevices(drmDevicePtr devices[], int max_devices)
3410{
3411 return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices);
3412}
3413
3360char *drmGetDeviceNameFromFd2(int fd) 3414char *drmGetDeviceNameFromFd2(int fd)
3361{ 3415{
3362#ifdef __linux__ 3416#ifdef __linux__
diff --git a/xf86drm.h b/xf86drm.h
index 4da6bd3c..b340fc46 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -801,6 +801,10 @@ extern void drmFreeDevice(drmDevicePtr *device);
801extern int drmGetDevices(drmDevicePtr devices[], int max_devices); 801extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
802extern void drmFreeDevices(drmDevicePtr devices[], int count); 802extern void drmFreeDevices(drmDevicePtr devices[], int count);
803 803
804#define DRM_DEVICE_GET_PCI_REVISION (1 << 0)
805extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device);
806extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices);
807
804#if defined(__cplusplus) 808#if defined(__cplusplus)
805} 809}
806#endif 810#endif