OSDN Git Service

vgaarb: update stub interface
[android-x86/external-libpciaccess.git] / src / common_bridge.c
index 305228a..7f26bdc 100644 (file)
@@ -55,8 +55,17 @@ read_bridge_info( struct pci_device_private * priv )
 {
     uint8_t  buf[0x40];
     pciaddr_t bytes;
+    int err;
 
 
+    /* Make sure the device has been probed.  If not, header_type won't be
+     * set and the rest of this function will fail.
+     */
+    err = pci_device_probe(& priv->base);
+    if (err) {
+       return err;
+    }
+
     switch ( priv->header_type & 0x7f ) {
     case 0x00:
        break;
@@ -188,6 +197,13 @@ read_bridge_info( struct pci_device_private * priv )
 }
 
 
+/**
+ * Get the PCI bridge information for a device
+ *
+ * \returns
+ * If \c dev is a PCI-to-PCI bridge, a pointer to a \c pci_bridge_info
+ * structure.  Otherwise, \c NULL is returned.
+ */
 const struct pci_bridge_info *
 pci_device_get_bridge_info( struct pci_device * dev )
 {
@@ -201,6 +217,13 @@ pci_device_get_bridge_info( struct pci_device * dev )
 }
 
 
+/**
+ * Get the PCMCIA bridge information for a device
+ *
+ * \returns
+ * If \c dev is a PCI-to-PCMCIA bridge, a pointer to a
+ * \c pci_pcmcia_bridge_info structure.  Otherwise, \c NULL is returned.
+ */
 const struct pci_pcmcia_bridge_info *
 pci_device_get_pcmcia_bridge_info( struct pci_device * dev )
 {
@@ -214,6 +237,26 @@ pci_device_get_pcmcia_bridge_info( struct pci_device * dev )
 }
 
 
+/**
+ * Determine the primary, secondary, and subordinate buses for a bridge
+ * 
+ * Determines the IDs of the primary, secondary, and subordinate buses for
+ * a specified bridge.  Not all bridges directly store this information
+ * (e.g., PCI-to-ISA bridges).  For those bridges, no error is returned, but
+ * -1 is stored in the bus IDs that don't make sense.
+ *
+ * For example, for a PCI-to-ISA bridge, \c primary_bus will be set to the ID
+ * of the bus containing the device and both \c secondary_bus and
+ * \c subordinate_bus will be set to -1.
+ *
+ * \return
+ * On success, zero is returned.  If \c dev is not a bridge, \c ENODEV is
+ * returned.
+ * 
+ * \bug
+ * Host bridges are handled the same way as PCI-to-ISA bridges.  This is
+ * almost certainly not correct.
+ */
 int
 pci_device_get_bridge_buses(struct pci_device * dev, int *primary_bus,
                            int *secondary_bus, int *subordinate_bus)
@@ -227,8 +270,8 @@ pci_device_get_bridge_buses(struct pci_device * dev, int *primary_bus,
        return ENODEV;
     }
 
-    if (priv->bridge.pci == NULL) {
-       read_bridge_info(priv);
+    if (!priv->bridge.pci) {
+       return ENODEV;
     }
 
     switch ((dev->device_class >> 8) & 0x0ff) {
@@ -249,15 +292,31 @@ pci_device_get_bridge_buses(struct pci_device * dev, int *primary_bus,
        break;
 
     case 0x04:
+    if (priv->bridge.pci == NULL)
+        read_bridge_info(priv);
+    if (priv->header_type == 0x01) {
        *primary_bus = priv->bridge.pci->primary_bus;
        *secondary_bus = priv->bridge.pci->secondary_bus;
        *subordinate_bus = priv->bridge.pci->subordinate_bus;
+    } else {
+       *primary_bus = dev->bus;
+       *secondary_bus = -1;
+       *subordinate_bus = -1;
+    }
        break;
 
     case 0x07:
+    if (priv->bridge.pcmcia == NULL)
+        read_bridge_info(priv);
+    if (priv->header_type == 0x02) {
        *primary_bus = priv->bridge.pcmcia->primary_bus;
        *secondary_bus = priv->bridge.pcmcia->card_bus;
        *subordinate_bus = priv->bridge.pcmcia->subordinate_bus;
+    } else {
+       *primary_bus = dev->bus;
+       *secondary_bus = -1;
+       *subordinate_bus = -1;
+    }
        break;
     }