aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c40
-rw-r--r--include/linux/pci.h1
2 files changed, 31 insertions, 10 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index f3ea977a5b1b..d34415ba0f64 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -286,20 +286,17 @@ static int pci_pcie_cap2(struct pci_dev *dev)
286} 286}
287 287
288/** 288/**
289 * pci_find_ext_capability - Find an extended capability 289 * pci_find_next_ext_capability - Find an extended capability
290 * @dev: PCI device to query 290 * @dev: PCI device to query
291 * @start: address at which to start looking (0 to start at beginning of list)
291 * @cap: capability code 292 * @cap: capability code
292 * 293 *
293 * Returns the address of the requested extended capability structure 294 * Returns the address of the next matching extended capability structure
294 * within the device's PCI configuration space or 0 if the device does 295 * within the device's PCI configuration space or 0 if the device does
295 * not support it. Possible values for @cap: 296 * not support it. Some capabilities can occur several times, e.g., the
296 * 297 * vendor-specific capability, and this provides a way to find them all.
297 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
298 * %PCI_EXT_CAP_ID_VC Virtual Channel
299 * %PCI_EXT_CAP_ID_DSN Device Serial Number
300 * %PCI_EXT_CAP_ID_PWR Power Budgeting
301 */ 298 */
302int pci_find_ext_capability(struct pci_dev *dev, int cap) 299int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap)
303{ 300{
304 u32 header; 301 u32 header;
305 int ttl; 302 int ttl;
@@ -311,6 +308,9 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
311 if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) 308 if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
312 return 0; 309 return 0;
313 310
311 if (start)
312 pos = start;
313
314 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) 314 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
315 return 0; 315 return 0;
316 316
@@ -322,7 +322,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
322 return 0; 322 return 0;
323 323
324 while (ttl-- > 0) { 324 while (ttl-- > 0) {
325 if (PCI_EXT_CAP_ID(header) == cap) 325 if (PCI_EXT_CAP_ID(header) == cap && pos != start)
326 return pos; 326 return pos;
327 327
328 pos = PCI_EXT_CAP_NEXT(header); 328 pos = PCI_EXT_CAP_NEXT(header);
@@ -335,6 +335,26 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
335 335
336 return 0; 336 return 0;
337} 337}
338EXPORT_SYMBOL_GPL(pci_find_next_ext_capability);
339
340/**
341 * pci_find_ext_capability - Find an extended capability
342 * @dev: PCI device to query
343 * @cap: capability code
344 *
345 * Returns the address of the requested extended capability structure
346 * within the device's PCI configuration space or 0 if the device does
347 * not support it. Possible values for @cap:
348 *
349 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
350 * %PCI_EXT_CAP_ID_VC Virtual Channel
351 * %PCI_EXT_CAP_ID_DSN Device Serial Number
352 * %PCI_EXT_CAP_ID_PWR Power Budgeting
353 */
354int pci_find_ext_capability(struct pci_dev *dev, int cap)
355{
356 return pci_find_next_ext_capability(dev, 0, cap);
357}
338EXPORT_SYMBOL_GPL(pci_find_ext_capability); 358EXPORT_SYMBOL_GPL(pci_find_ext_capability);
339 359
340static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) 360static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5faa8310eec9..65c503cdec3b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -755,6 +755,7 @@ enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev);
755int pci_find_capability(struct pci_dev *dev, int cap); 755int pci_find_capability(struct pci_dev *dev, int cap);
756int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); 756int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
757int pci_find_ext_capability(struct pci_dev *dev, int cap); 757int pci_find_ext_capability(struct pci_dev *dev, int cap);
758int pci_find_next_ext_capability(struct pci_dev *dev, int pos, int cap);
758int pci_find_ht_capability(struct pci_dev *dev, int ht_cap); 759int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
759int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap); 760int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
760struct pci_bus *pci_find_next_bus(const struct pci_bus *from); 761struct pci_bus *pci_find_next_bus(const struct pci_bus *from);