]> git.hungrycats.org Git - linux/commitdiff
[PATCH] PCI: add pci_get_slot() function
authorMatthew Wilcox <willy@debian.org>
Thu, 29 Jan 2004 06:32:13 +0000 (22:32 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Thu, 29 Jan 2004 06:32:13 +0000 (22:32 -0800)
tg3.c has a bug where it can find the wrong 5704 peer on a machine with
PCI domains.  The problem is that pci_find_slot() can't distinguish
whether it has the correct domain or not.

This patch fixes that problem by introducing pci_get_slot().

drivers/pci/search.c
include/linux/pci.h

index 366f1f16fb2f06e39e94a5add8c6842dbf7cd533..aa900b17f2f78974ab195a4c91dee541ee78fdca 100644 (file)
@@ -103,6 +103,41 @@ pci_find_slot(unsigned int bus, unsigned int devfn)
        return NULL;
 }
 
+/**
+ * pci_get_slot - locate PCI device for a given PCI slot
+ * @bus: PCI bus on which desired PCI device resides
+ * @devfn: encodes number of PCI slot in which the desired PCI 
+ * device resides and the logical device number within that slot 
+ * in case of multi-function devices.
+ *
+ * Given a PCI bus and slot/function number, the desired PCI device 
+ * is located in the list of PCI devices.
+ * If the device is found, its reference count is increased and this
+ * function returns a pointer to its data structure.  The caller must
+ * decrement the reference count by calling pci_dev_put().
+ * If no device is found, %NULL is returned.
+ */
+struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
+{
+       struct list_head *tmp;
+       struct pci_dev *dev;
+
+       WARN_ON(in_interrupt());
+       spin_lock(&pci_bus_lock);
+
+       list_for_each(tmp, &bus->children) {
+               dev = pci_dev_b(tmp);
+               if (dev->devfn == devfn)
+                       goto out;
+       }
+
+       dev = NULL;
+ out:
+       pci_dev_get(dev);
+       spin_unlock(&pci_bus_lock);
+       return dev;
+}
+
 /**
  * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
@@ -319,3 +354,4 @@ EXPORT_SYMBOL(pci_find_slot);
 EXPORT_SYMBOL(pci_find_subsys);
 EXPORT_SYMBOL(pci_get_device);
 EXPORT_SYMBOL(pci_get_subsys);
+EXPORT_SYMBOL(pci_get_slot);
index 33980d0a753cc1e0923b19e67947949933547cda..4178a8b148bb56566e7e1c1ebce2c60341d98bf4 100644 (file)
@@ -614,6 +614,8 @@ struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct
 struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device,
                                unsigned int ss_vendor, unsigned int ss_device,
                                struct pci_dev *from);
+struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
+
 int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
 int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
 int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val);