Files
xserver_xsdl/hw/xfree86/os-support/linux/lnx_platform.c
Bryce Harrington d16284687d xfree86: Revert workaround for drm race condition.
Revert 70739e817b and mostly revert
c31eac647a.

Further investigation shows the encountered race condition is between
lightdm and plymouth-splash, as implemented in the Ubuntu distribution
within the limitations of upstart's job coordination logic, and can (and
should) be fixed within those limiations.  Not in xserver itself.

This leaves some of the diagnostic improvements from the recent patch
series, in case others run into a similar situation.

Signed-off-by: Bryce Harrington <bryce@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2013-04-12 10:03:29 +10:00

185 lines
4.2 KiB
C

#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef XSERVER_PLATFORM_BUS
#include <xf86drm.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
/* Linux platform device support */
#include "xf86_OSproc.h"
#include "xf86.h"
#include "xf86platformBus.h"
#include "xf86Bus.h"
#include "hotplug.h"
static Bool
get_drm_info(struct OdevAttributes *attribs, char *path)
{
drmSetVersion sv;
char *buf;
int fd;
int err = 0;
fd = open(path, O_RDWR, O_CLOEXEC);
if (fd == -1)
return FALSE;
sv.drm_di_major = 1;
sv.drm_di_minor = 4;
sv.drm_dd_major = -1; /* Don't care */
sv.drm_dd_minor = -1; /* Don't care */
err = drmSetInterfaceVersion(fd, &sv);
if (err) {
ErrorF("setversion 1.4 failed: %s\n", strerror(-err));
goto out;
}
xf86_add_platform_device(attribs);
buf = drmGetBusid(fd);
xf86_add_platform_device_attrib(xf86_num_platform_devices - 1,
ODEV_ATTRIB_BUSID, buf);
drmFreeBusid(buf);
out:
close(fd);
return (err == 0);
}
Bool
xf86PlatformDeviceCheckBusID(struct xf86_platform_device *device, const char *busid)
{
struct OdevAttribute *attrib;
const char *syspath = NULL;
BusType bustype;
const char *id;
xorg_list_for_each_entry(attrib, &device->attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
syspath = attrib->attrib_name;
break;
}
}
if (!syspath)
return FALSE;
bustype = StringToBusType(busid, &id);
if (bustype == BUS_PCI) {
struct pci_device *pPci = device->pdev;
if (xf86ComparePciBusString(busid,
((pPci->domain << 8)
| pPci->bus),
pPci->dev, pPci->func)) {
return TRUE;
}
}
else if (bustype == BUS_PLATFORM) {
/* match on the minimum string */
int len = strlen(id);
if (strlen(syspath) < strlen(id))
len = strlen(syspath);
if (strncmp(id, syspath, len))
return FALSE;
return TRUE;
}
return FALSE;
}
void
xf86PlatformDeviceProbe(struct OdevAttributes *attribs)
{
struct OdevAttribute *attrib;
int i;
char *path = NULL;
Bool ret;
xorg_list_for_each_entry(attrib, &attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_PATH) {
path = attrib->attrib_name;
break;
}
}
if (!path)
goto out_free;
for (i = 0; i < xf86_num_platform_devices; i++) {
char *dpath;
dpath = xf86_get_platform_attrib(i, ODEV_ATTRIB_PATH);
if (!strcmp(path, dpath))
break;
}
if (i != xf86_num_platform_devices)
goto out_free;
LogMessage(X_INFO, "xfree86: Adding drm device (%s)\n", path);
ret = get_drm_info(attribs, path);
if (ret == FALSE)
goto out_free;
return;
out_free:
config_odev_free_attribute_list(attribs);
}
void NewGPUDeviceRequest(struct OdevAttributes *attribs)
{
int old_num = xf86_num_platform_devices;
int ret;
xf86PlatformDeviceProbe(attribs);
if (old_num == xf86_num_platform_devices)
return;
ret = xf86platformAddDevice(xf86_num_platform_devices-1);
if (ret == -1)
xf86_remove_platform_device(xf86_num_platform_devices-1);
ErrorF("xf86: found device %d\n", xf86_num_platform_devices);
return;
}
void DeleteGPUDeviceRequest(struct OdevAttributes *attribs)
{
struct OdevAttribute *attrib;
int index;
char *syspath = NULL;
xorg_list_for_each_entry(attrib, &attribs->list, member) {
if (attrib->attrib_id == ODEV_ATTRIB_SYSPATH) {
syspath = attrib->attrib_name;
break;
}
}
for (index = 0; index < xf86_num_platform_devices; index++) {
char *dspath;
dspath = xf86_get_platform_attrib(index, ODEV_ATTRIB_SYSPATH);
if (!strcmp(syspath, dspath))
break;
}
if (index == xf86_num_platform_devices)
goto out;
ErrorF("xf86: remove device %d %s\n", index, syspath);
xf86platformRemoveDevice(index);
out:
config_odev_free_attribute_list(attribs);
}
#endif