xf86drm: add drm{Get,Free}Device
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 <emil.l.velikov@gmail.com> Acked-by: Alex Deucher <alexander.deucher@amd.com>main
parent
fae59d7234
commit
ccedf66b65
115
xf86drm.c
115
xf86drm.c
|
@ -2982,7 +2982,7 @@ static int drmParsePciDeviceInfo(const char *d_name,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drmFreeDevice(drmDevicePtr *device)
|
void drmFreeDevice(drmDevicePtr *device)
|
||||||
{
|
{
|
||||||
if (device == NULL)
|
if (device == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -3071,6 +3071,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
|
* Get drm devices on the system
|
||||||
*
|
*
|
||||||
|
|
|
@ -790,6 +790,9 @@ typedef struct _drmDevice {
|
||||||
} deviceinfo;
|
} deviceinfo;
|
||||||
} drmDevice, *drmDevicePtr;
|
} drmDevice, *drmDevicePtr;
|
||||||
|
|
||||||
|
extern int drmGetDevice(int fd, drmDevicePtr *device);
|
||||||
|
extern void drmFreeDevice(drmDevicePtr *device);
|
||||||
|
|
||||||
extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
|
extern int drmGetDevices(drmDevicePtr devices[], int max_devices);
|
||||||
extern void drmFreeDevices(drmDevicePtr devices[], int count);
|
extern void drmFreeDevices(drmDevicePtr devices[], int count);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue