summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-05-09 09:32:05 +0100
committerDave Airlie <airlied@redhat.com>2012-05-09 09:32:05 +0100
commit0ecfdf19a9745ad4a0c8680b6dae542f50d3a212 (patch)
tree925cba062fbbdad8517c40cb3f1eefb981254778
parentd12d9ac5cae7a4287e7ba1f137209574bc0c5b17 (diff)
modesetting: make sure the pci device corresponds to the drm device
If we get asked to pci open a device with a kms path override, make sure they match, otherwise this driver can steal the primary device binding for a usb adaptor. The driver should fallback to the old probe entry point in this case. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/driver.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/driver.c b/src/driver.c
index 2c9878c..e977150 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -198,6 +198,39 @@ static Bool probe_hw(char *dev)
return FALSE;
}
+static char *
+ms_DRICreatePCIBusID(const struct pci_device *dev)
+{
+ char *busID;
+
+ if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
+ dev->domain, dev->bus, dev->dev, dev->func) == -1)
+ return NULL;
+
+ return busID;
+}
+
+
+static Bool probe_hw_pci(char *dev, struct pci_device *pdev)
+{
+ int fd = open_hw(dev);
+ char *id, *devid;
+
+ if (fd == -1)
+ return FALSE;
+
+ id = drmGetBusid(fd);
+ devid = ms_DRICreatePCIBusID(pdev);
+ close(fd);
+
+ if (!id || !devid)
+ return FALSE;
+
+ if (!strcmp(id, devid))
+ return TRUE;
+
+ return FALSE;
+}
static const OptionInfoRec *
AvailableOptions(int chipid, int busid)
{
@@ -219,7 +252,7 @@ ms_pci_probe(DriverPtr driver,
scrn->entityInstanceList[0]);
devpath = xf86FindOptionValue(devSection->options, "kmsdev");
- if (probe_hw(devpath)) {
+ if (probe_hw_pci(devpath, dev)) {
scrn->driverVersion = 1;
scrn->driverName = "modesetting";
scrn->name = "modeset";