[openib-general] Re: Initial ipath review brain dump
Roland Dreier
rolandd at cisco.com
Mon Oct 17 15:41:49 PDT 2005
I came up with the patch below, which lets drivers do something like
the following:
for (pos = pci_find_capability(pdev, <ID>);
pos;
pos = pci_find_next_capability(pdev, pos, <ID>)) {
/* ... */
}
I think this works well for infinipath_core.c. What do you think? If
it looks OK to you, I'll send it on to Greg K-H for (I hope) inclusion
in 2.6.15.
[Assuming Linus releases 2.6.14 within the next few days, then the
2.6.15 window for core changes will close by the end of next week, so
it's a good idea to get any generic stuff merged ASAP]
- R.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 259d247..b852959 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -120,6 +120,33 @@ int pci_find_capability(struct pci_dev *
}
/**
+ * pci_find_next_capability - Find next capability after current position
+ * @dev: PCI device to query
+ * @pos: Position to search from
+ * @cap: capability code
+ */
+int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
+{
+ u8 id;
+ int ttl = 48;
+
+ while (ttl--) {
+ pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
+ pos &= ~3;
+ if (pos < 0x40)
+ break;
+ pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
+ if (id == 0xff)
+ break;
+ if (id == cap)
+ return pos;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(pci_find_next_capability);
+
+/**
* pci_bus_find_capability - query for devices' capabilities
* @bus: the PCI bus to query
* @devfn: PCI device to query
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7349058..8016d14 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -337,6 +337,7 @@ struct pci_dev *pci_find_device (unsigne
struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
+int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability (struct pci_dev *dev, int cap);
struct pci_bus * pci_find_next_bus(const struct pci_bus *from);
@@ -546,6 +547,7 @@ static inline int pci_assign_resource(st
static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
static inline void pci_unregister_driver(struct pci_driver *drv) { }
static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
+static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) {return 0; }
static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; }
static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
More information about the general
mailing list