12c02d7
From 39f73e813f7d404498629f6104a9003d092af28d Mon Sep 17 00:00:00 2001
12c02d7
From: Dave Airlie <airlied@redhat.com>
12c02d7
Date: Tue, 8 May 2012 13:01:12 +0100
12c02d7
Subject: [PATCH] xf86/pci: fix slot claiming counting.
12c02d7
12c02d7
Currently if we claim a slot for a PCI driver, we never let it go properly,
12c02d7
this prevents the fallback probe from reusing the slot, even though it
12c02d7
isn't claimed for that pci slot.
12c02d7
12c02d7
So if you set the modesetting driver to point at a specific kms device,
12c02d7
that isn't a PCI device (i.e. USB dongle), then the modesetting driver
12c02d7
loads, the pci probe tries to bind the config slot to the primary PCI
12c02d7
device, however we then check the kms device bus id to discover it
12c02d7
isn't valid. However we don't remove the claim on the slot. Next the
12c02d7
old probe function is called and there is no slots to claim.
12c02d7
12c02d7
This patch fixes that and converts the pciSlotClaimed boolean into
12c02d7
a counter, and changes the unclaim api to take a device pointer
12c02d7
to remove from the entity.
12c02d7
12c02d7
Reviewed-by: Adam Jackson <ajax@redhat.com>
12c02d7
Signed-off-by: Dave Airlie <airlied@redhat.com>
12c02d7
---
12c02d7
 hw/xfree86/common/xf86.h       |    4 ++--
12c02d7
 hw/xfree86/common/xf86Bus.c    |   20 ++++++++++++++++++++
12c02d7
 hw/xfree86/common/xf86Priv.h   |    1 +
12c02d7
 hw/xfree86/common/xf86pciBus.c |   10 ++++++----
12c02d7
 4 files changed, 29 insertions(+), 6 deletions(-)
12c02d7
12c02d7
diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
12c02d7
index fc4c34e..e6d41d6 100644
12c02d7
--- a/hw/xfree86/common/xf86.h
12c02d7
+++ b/hw/xfree86/common/xf86.h
12c02d7
@@ -97,12 +97,12 @@ extern _X_EXPORT Bool VTSwitchEnabled;  /* kbd driver */
12c02d7
 /* PCI related */
12c02d7
 #ifdef XSERVER_LIBPCIACCESS
12c02d7
 #include <pciaccess.h>
12c02d7
-extern _X_EXPORT Bool pciSlotClaimed;
12c02d7
+extern _X_EXPORT int pciSlotClaimed;
12c02d7
 
12c02d7
 extern _X_EXPORT Bool xf86CheckPciSlot(const struct pci_device *);
12c02d7
 extern _X_EXPORT int xf86ClaimPciSlot(struct pci_device *, DriverPtr drvp,
12c02d7
                                       int chipset, GDevPtr dev, Bool active);
12c02d7
-extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *);
12c02d7
+extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *, GDevPtr dev);
12c02d7
 extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus,
12c02d7
                                             int *device, int *func);
12c02d7
 extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus,
12c02d7
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
12c02d7
index b176e8c..b876434 100644
12c02d7
--- a/hw/xfree86/common/xf86Bus.c
12c02d7
+++ b/hw/xfree86/common/xf86Bus.c
12c02d7
@@ -420,6 +420,26 @@ xf86AddDevToEntity(int entityIndex, GDevPtr dev)
12c02d7
     dev->claimed = TRUE;
12c02d7
 }
12c02d7
 
12c02d7
+
12c02d7
+void
12c02d7
+xf86RemoveDevFromEntity(int entityIndex, GDevPtr dev)
12c02d7
+{
12c02d7
+    EntityPtr pEnt;
12c02d7
+    int i, j;
12c02d7
+    if (entityIndex >= xf86NumEntities)
12c02d7
+        return;
12c02d7
+
12c02d7
+    pEnt = xf86Entities[entityIndex];
12c02d7
+    for (i = 0; i < pEnt->numInstances; i++) {
12c02d7
+        if (pEnt->devices[i] == dev) {
12c02d7
+            for (j = i; j < pEnt->numInstances - 1; j++)
12c02d7
+                pEnt->devices[j] = pEnt->devices[j + 1];
12c02d7
+            break;
12c02d7
+        }
12c02d7
+    }
12c02d7
+    pEnt->numInstances--;
12c02d7
+    dev->claimed = FALSE;
12c02d7
+}
12c02d7
 /*
12c02d7
  * xf86GetEntityInfo() -- This function hands information from the
12c02d7
  * EntityRec struct to the drivers. The EntityRec structure itself
12c02d7
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
12c02d7
index 8d9cb55..6c5efea 100644
12c02d7
--- a/hw/xfree86/common/xf86Priv.h
12c02d7
+++ b/hw/xfree86/common/xf86Priv.h
12c02d7
@@ -116,6 +116,7 @@ extern _X_EXPORT void xf86AccessLeave(void);
12c02d7
 extern _X_EXPORT void xf86PostProbe(void);
12c02d7
 extern _X_EXPORT void xf86ClearEntityListForScreen(int scrnIndex);
12c02d7
 extern _X_EXPORT void xf86AddDevToEntity(int entityIndex, GDevPtr dev);
12c02d7
+extern _X_EXPORT void xf86RemoveDevFromEntity(int entityIndex, GDevPtr dev);
12c02d7
 
12c02d7
 /* xf86Config.c */
12c02d7
 
12c02d7
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
12c02d7
index e52f1da..d758260 100644
12c02d7
--- a/hw/xfree86/common/xf86pciBus.c
12c02d7
+++ b/hw/xfree86/common/xf86pciBus.c
12c02d7
@@ -52,7 +52,7 @@
12c02d7
 #define PCI_VENDOR_GENERIC		0x00FF
12c02d7
 
12c02d7
 /* Bus-specific globals */
12c02d7
-Bool pciSlotClaimed = FALSE;
12c02d7
+int pciSlotClaimed = 0;
12c02d7
 
12c02d7
 #define PCIINFOCLASSES(c) \
12c02d7
     ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
12c02d7
@@ -223,7 +223,7 @@ xf86ClaimPciSlot(struct pci_device *d, DriverPtr drvp,
12c02d7
         p->inUse = FALSE;
12c02d7
         if (dev)
12c02d7
             xf86AddDevToEntity(num, dev);
12c02d7
-        pciSlotClaimed = TRUE;
12c02d7
+        pciSlotClaimed++;
12c02d7
 
12c02d7
         return num;
12c02d7
     }
12c02d7
@@ -235,7 +235,7 @@ xf86ClaimPciSlot(struct pci_device *d, DriverPtr drvp,
12c02d7
  * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
12c02d7
  */
12c02d7
 void
12c02d7
-xf86UnclaimPciSlot(struct pci_device *d)
12c02d7
+xf86UnclaimPciSlot(struct pci_device *d, GDevPtr dev)
12c02d7
 {
12c02d7
     int i;
12c02d7
 
12c02d7
@@ -244,6 +244,8 @@ xf86UnclaimPciSlot(struct pci_device *d)
12c02d7
 
12c02d7
         if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
12c02d7
             /* Probably the slot should be deallocated? */
12c02d7
+            xf86RemoveDevFromEntity(i, dev);
12c02d7
+            pciSlotClaimed--;
12c02d7
             p->bus.type = BUS_NONE;
12c02d7
             return;
12c02d7
         }
12c02d7
@@ -537,7 +539,7 @@ xf86PciProbeDev(DriverPtr drvp)
12c02d7
                         foundScreen = TRUE;
12c02d7
                     }
12c02d7
                     else
12c02d7
-                        xf86UnclaimPciSlot(pPci);
12c02d7
+                        xf86UnclaimPciSlot(pPci, devList[i]);
12c02d7
                 }
12c02d7
 
12c02d7
                 break;
12c02d7
-- 
12c02d7
1.7.7.6
12c02d7