summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-04-25 11:11:36 +0100
committerDave Airlie <airlied@redhat.com>2012-04-25 11:11:36 +0100
commitd381abf2655bd6752469567570e0afa572f0f0a7 (patch)
tree5ff95b3b15708a7582711a07036bf9623b61641b
parent5b2b3c217c9d78ede91616a90254d71b4f75463b (diff)
improve udev probing to use pci info
-rw-r--r--hw/xfree86/common/xf86Bus.c2
-rw-r--r--hw/xfree86/common/xf86DrvHelper.c4
-rw-r--r--hw/xfree86/common/xf86Init.c3
-rw-r--r--hw/xfree86/common/xf86pciBus.c11
-rw-r--r--hw/xfree86/common/xf86str.h2
-rw-r--r--hw/xfree86/common/xf86udev.c41
6 files changed, 53 insertions, 10 deletions
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 950a4df26..1038d81c2 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -79,7 +79,7 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only, Bool drv_v2)
if (drv_v2) {
foundScreen = xf86udevProbeDev(drv);
- }
+ } else
#ifdef XSERVER_LIBPCIACCESS
if (foundScreen == FALSE && drv->PciProbe != NULL) {
if (xf86DoConfigure && xf86DoConfigurePass1) {
diff --git a/hw/xfree86/common/xf86DrvHelper.c b/hw/xfree86/common/xf86DrvHelper.c
index 50711bb77..e0318c506 100644
--- a/hw/xfree86/common/xf86DrvHelper.c
+++ b/hw/xfree86/common/xf86DrvHelper.c
@@ -43,7 +43,7 @@ impedHelperScreenInit(ScreenPtr pScreen,
int width = 0, height = 0;
int i;
Bool allow_slave = FALSE;
- ScrnInfoPtr master;
+ ScrnInfoPtr master = NULL;
if (!impedSetupScreen(pScreen))
return FALSE;
@@ -69,6 +69,8 @@ retry:
break;
}
+ if (!master)
+ return FALSE;
if (!impedFinishScreenInit(pScreen, NULL, width, height,
75, 75,
master->displayWidth, master->bitsPerPixel))
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 24ec91a80..d27669491 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -853,7 +853,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
xf86GPUScreens[i]->vtSema = TRUE;
} else {
- FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
+ ErrorF("AddScreen/ScreenInit failed for driver %d\n", i);
+ xf86NumGPUScreens--;
}
}
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 4c04404e4..597a1b53a 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -365,7 +365,16 @@ xf86GetPciInfoForEntity(int entityIndex)
return NULL;
p = xf86Entities[entityIndex];
- return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
+ switch (p->bus.type) {
+ case BUS_PCI:
+ return p->bus.id.pci;
+ case BUS_UDEV:
+ if (p->bus.id.udev->pdev)
+ return p->bus.id.udev->pdev;
+ default:
+ break;
+ }
+ return NULL;
}
/*
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index ff3a578a3..7e8abe07d 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -328,7 +328,7 @@ typedef struct _DriverRec {
Bool (*PciProbe) (struct _DriverRec * drv, int entity_num,
struct pci_device * dev, intptr_t match_data);
Bool (*UdevProbe) (struct _DriverRec *drv, int entity_num,
- struct xf86_udev_device *dev);
+ struct xf86_udev_device *dev, intptr_t dev_match_data);
} DriverRec, *DriverPtr;
/*
diff --git a/hw/xfree86/common/xf86udev.c b/hw/xfree86/common/xf86udev.c
index b1282ddb5..a1ee1d5bf 100644
--- a/hw/xfree86/common/xf86udev.c
+++ b/hw/xfree86/common/xf86udev.c
@@ -258,25 +258,56 @@ int xf86UnclaimUdevSlot(struct xf86_udev_device *d)
return 0;
}
+#define END_OF_MATCHES(m) \
+ (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
+
int xf86udevProbeDev(DriverPtr drvp)
{
Bool foundScreen = FALSE;
GDevPtr *devList;
const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList);
- int i, j;
+ int i, j, k;
int entity;
+ const struct pci_id_match *const devices = drvp->supported_devices;
+ struct pci_device *pPci;
for (i = 0; i < numDevs; i++) {
for (j = 0; j < num_udev_devices; j++) {
- if (xf86_check_udev_slot(&xf86_udev_devices[j])) {
+ /* overload PCI match loading if we can use it */
+ if (xf86_udev_devices[j].pdev && devices) {
+ int device_id = xf86_udev_devices[j].pdev->device_id;
+ pPci = xf86_udev_devices[j].pdev;
+ for (k = 0; !END_OF_MATCHES(devices[k]); k++) {
+ if (PCI_ID_COMPARE(devices[k].vendor_id, pPci->vendor_id)
+ && PCI_ID_COMPARE(devices[k].device_id, device_id)
+ && ((devices[k].device_class_mask & pPci->device_class)
+ == devices[k].device_class)) {
+ entity = xf86ClaimUdevSlot(&xf86_udev_devices[j],
+ drvp, 0, devList[i], devList[i]->active);
+ if (entity != -1) {
+ if (drvp->UdevProbe(drvp, entity, &xf86_udev_devices[j], devices[k].match_data))
+ continue;
+ foundScreen = TRUE;
+ break;
+ }
+ else
+ xf86UnclaimUdevSlot(&xf86_udev_devices[j]);
+ }
+ }
+ } else if (xf86_udev_devices[j].pdev && !devices)
+ continue;
+ else {
+ if (xf86_check_udev_slot(&xf86_udev_devices[j])) {
entity = xf86ClaimUdevSlot(&xf86_udev_devices[j],
drvp, 0, devList[i], devList[i]->active);
- if (drvp->UdevProbe(drvp, entity, &xf86_udev_devices[j]))
+ if (drvp->UdevProbe(drvp, entity, &xf86_udev_devices[j], 0))
continue;
+ foundScreen = TRUE;
+ }
}
}
}
- return 0;
+ return foundScreen;
}
int AddOutputDevice(struct udev_device *udev_device)
@@ -310,7 +341,7 @@ int AddOutputDevice(struct udev_device *udev_device)
old_screens = xf86NumGPUScreens;
entity = xf86ClaimUdevSlot(&xf86_udev_devices[num_udev_devices-1],
drvp, 0, 0, 0);
- drvp->UdevProbe(drvp, entity, &xf86_udev_devices[num_udev_devices-1]);
+ drvp->UdevProbe(drvp, entity, &xf86_udev_devices[num_udev_devices-1], 0);
if (old_screens == xf86NumGPUScreens)
return 0;