xf86drm: split out drmProcessPciDevice and drmFoldDuplicatedDevices

Will be reused in the next commit.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
main
Emil Velikov 2015-09-09 17:54:34 +01:00
parent 8415a00a3f
commit fae59d7234
1 changed files with 74 additions and 49 deletions

123
xf86drm.c
View File

@ -36,6 +36,7 @@
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
@ -3001,6 +3002,75 @@ void drmFreeDevices(drmDevicePtr devices[], int count)
drmFreeDevice(&devices[i]); drmFreeDevice(&devices[i]);
} }
static int drmProcessPciDevice(drmDevicePtr *device, const char *d_name,
const char *node, int node_type,
int maj, int min, bool fetch_deviceinfo)
{
const int max_node_str = drmGetMaxNodeName();
int ret, i;
void *addr;
addr = *device = calloc(1, sizeof(drmDevice) +
(DRM_NODE_MAX *
(sizeof(void *) + max_node_str)) +
sizeof(drmPciBusInfo) +
sizeof(drmPciDeviceInfo));
if (!*device)
return -ENOMEM;
(*device)->bustype = DRM_BUS_PCI;
(*device)->available_nodes = 1 << node_type;
addr += sizeof(drmDevice);
(*device)->nodes = addr;
addr += DRM_NODE_MAX * sizeof(void *);
for (i = 0; i < DRM_NODE_MAX; i++) {
(*device)->nodes[i] = addr;
addr += max_node_str;
}
memcpy((*device)->nodes[node_type], node, max_node_str);
(*device)->businfo.pci = addr;
ret = drmParsePciBusInfo(maj, min, (*device)->businfo.pci);
if (ret)
goto free_device;
// Fetch the device info if the user has requested it
if (fetch_deviceinfo) {
addr += sizeof(drmPciBusInfo);
(*device)->deviceinfo.pci = addr;
ret = drmParsePciDeviceInfo(d_name, (*device)->deviceinfo.pci);
if (ret)
goto free_device;
}
return 0;
free_device:
free(*device);
*device = NULL;
return ret;
}
static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
{
int node_type, i, j;
for (i = 0; i < count; i++) {
for (j = i + 1; j < count; j++) {
if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) {
local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
node_type = log2(local_devices[j]->available_nodes);
memcpy(local_devices[i]->nodes[node_type],
local_devices[j]->nodes[node_type], drmGetMaxNodeName());
drmFreeDevice(&local_devices[j]);
}
}
}
}
/** /**
* Get drm devices on the system * Get drm devices on the system
* *
@ -3021,12 +3091,10 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
struct dirent *dent; struct dirent *dent;
struct stat sbuf; struct stat sbuf;
char node[PATH_MAX + 1]; char node[PATH_MAX + 1];
const int max_node_str = drmGetMaxNodeName();
int node_type, subsystem_type; int node_type, subsystem_type;
int maj, min; int maj, min;
int ret, i, j, node_count, device_count; int ret, i, node_count, device_count;
int max_count = 16; int max_count = 16;
void *addr;
local_devices = calloc(max_count, sizeof(drmDevicePtr)); local_devices = calloc(max_count, sizeof(drmDevicePtr));
if (local_devices == NULL) if (local_devices == NULL)
@ -3061,44 +3129,11 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
switch (subsystem_type) { switch (subsystem_type) {
case DRM_BUS_PCI: case DRM_BUS_PCI:
addr = device = calloc(1, sizeof(drmDevice) + ret = drmProcessPciDevice(&device, dent->d_name, node, node_type,
(DRM_NODE_MAX * maj, min, devices != NULL);
(sizeof(void *) + max_node_str)) +
sizeof(drmPciBusInfo) +
sizeof(drmPciDeviceInfo));
if (!device)
goto free_devices;
device->bustype = subsystem_type;
device->available_nodes = 1 << node_type;
addr += sizeof(drmDevice);
device->nodes = addr;
addr += DRM_NODE_MAX * sizeof(void *);
for (j = 0; j < DRM_NODE_MAX; j++) {
device->nodes[j] = addr;
addr += max_node_str;
}
memcpy(device->nodes[node_type], node, max_node_str);
device->businfo.pci = addr;
ret = drmParsePciBusInfo(maj, min, device->businfo.pci);
if (ret) if (ret)
goto free_devices; goto free_devices;
// Fetch the device info if the user has requested it
if (devices != NULL) {
addr += sizeof(drmPciBusInfo);
device->deviceinfo.pci = addr;
ret = drmParsePciDeviceInfo(dent->d_name,
device->deviceinfo.pci);
if (ret)
goto free_devices;
}
break; break;
default: default:
fprintf(stderr, "The subsystem type is not supported yet\n"); fprintf(stderr, "The subsystem type is not supported yet\n");
@ -3121,17 +3156,7 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
node_count = i; node_count = i;
/* Fold nodes into a single device if they share the same bus info */ /* Fold nodes into a single device if they share the same bus info */
for (i = 0; i < node_count; i++) { drmFoldDuplicatedDevices(local_devices, node_count);
for (j = i + 1; j < node_count; j++) {
if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) {
local_devices[i]->available_nodes |= local_devices[j]->available_nodes;
node_type = log2(local_devices[j]->available_nodes);
memcpy(local_devices[i]->nodes[node_type],
local_devices[j]->nodes[node_type], max_node_str);
drmFreeDevice(&local_devices[j]);
}
}
}
device_count = 0; device_count = 0;
for (i = 0; i < node_count && local_devices[i]; i++) { for (i = 0; i < node_count && local_devices[i]; i++) {