diff options
author | Dave Airlie <airlied@redhat.com> | 2012-04-25 11:11:36 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-25 11:11:36 +0100 |
commit | d381abf2655bd6752469567570e0afa572f0f0a7 (patch) | |
tree | 5ff95b3b15708a7582711a07036bf9623b61641b | |
parent | 5b2b3c217c9d78ede91616a90254d71b4f75463b (diff) |
improve udev probing to use pci info
-rw-r--r-- | hw/xfree86/common/xf86Bus.c | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86DrvHelper.c | 4 | ||||
-rw-r--r-- | hw/xfree86/common/xf86Init.c | 3 | ||||
-rw-r--r-- | hw/xfree86/common/xf86pciBus.c | 11 | ||||
-rw-r--r-- | hw/xfree86/common/xf86str.h | 2 | ||||
-rw-r--r-- | hw/xfree86/common/xf86udev.c | 41 |
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; |