aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-08-23 20:32:36 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-08-23 20:32:36 -0400
commita28afda8cc6a45b2c5a4f98cf8fcddd877597701 (patch)
tree2ad4d76e22ddb294fcf31d06b79e7464c70c653a
parente1c171b86baaccab983ded5dfa1663c0981d2520 (diff)
parentdefb9446fe417f72855bc8bf97aa5d8af076bdf8 (diff)
Merge branch 'pci/bjorn-find-next-ext-cap' into next
* pci/bjorn-find-next-ext-cap: PCI: Add Vendor-Specific Extended Capability header info PCI: Add pci_find_next_ext_capability() Conflicts: drivers/pci/pci.c
-rw-r--r--drivers/pci/pci.c40
-rw-r--r--include/linux/pci.h1
-rw-r--r--include/linux/pci_regs.h6
3 files changed, 37 insertions, 10 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fac08f508d09..5ba60dd71faa 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -254,20 +254,17 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
254} 254}
255 255
256/** 256/**
257 * pci_find_ext_capability - Find an extended capability 257 * pci_find_next_ext_capability - Find an extended capability
258 * @dev: PCI device to query 258 * @dev: PCI device to query
259 * @start: address at which to start looking (0 to start at beginning of list)
259 * @cap: capability code 260 * @cap: capability code
260 * 261 *
261 * Returns the address of the requested extended capability structure 262 * Returns the address of the next matching extended capability structure
262 * within the device's PCI configuration space or 0 if the device does 263 * within the device's PCI configuration space or 0 if the device does
263 * not support it. Possible values for @cap: 264 * not support it. Some capabilities can occur several times, e.g., the
264 * 265 * vendor-specific capability, and this provides a way to find them all.
265 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
266 * %PCI_EXT_CAP_ID_VC Virtual Channel
267 * %PCI_EXT_CAP_ID_DSN Device Serial Number
268 * %PCI_EXT_CAP_ID_PWR Power Budgeting
269 */ 266 */
270int pci_find_ext_capability(struct pci_dev *dev, int cap) 267int pci_find_next_ext_capability(struct pci_dev *dev, int start, int cap)
271{ 268{
272 u32 header; 269 u32 header;
273 int ttl; 270 int ttl;
@@ -279,6 +276,9 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
279 if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) 276 if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
280 return 0; 277 return 0;
281 278
279 if (start)
280 pos = start;
281
282 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) 282 if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
283 return 0; 283 return 0;
284 284
@@ -290,7 +290,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
290 return 0; 290 return 0;
291 291
292 while (ttl-- > 0) { 292 while (ttl-- > 0) {
293 if (PCI_EXT_CAP_ID(header) == cap) 293 if (PCI_EXT_CAP_ID(header) == cap && pos != start)
294 return pos; 294 return pos;
295 295
296 pos = PCI_EXT_CAP_NEXT(header); 296 pos = PCI_EXT_CAP_NEXT(header);
@@ -303,6 +303,26 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
303 303
304 return 0; 304 return 0;
305} 305}
306EXPORT_SYMBOL_GPL(pci_find_next_ext_capability);
307
308/**
309 * pci_find_ext_capability - Find an extended capability
310 * @dev: PCI device to query
311 * @cap: capability code
312 *
313 * Returns the address of the requested extended capability structure
314 * within the device's PCI configuration space or 0 if the device does
315 * not support it. Possible values for @cap:
316 *
317 * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting
318 * %PCI_EXT_CAP_ID_VC Virtual Channel
319 * %PCI_EXT_CAP_ID_DSN Device Serial Number
320 * %PCI_EXT_CAP_ID_PWR Power Budgeting
321 */
322int pci_find_ext_capability(struct pci_dev *dev, int cap)
323{
324 return pci_find_next_ext_capability(dev, 0, cap);
325}
306EXPORT_SYMBOL_GPL(pci_find_ext_capability); 326EXPORT_SYMBOL_GPL(pci_find_ext_capability);
307 327
308static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) 328static 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 b8667e0548e0..57a08da824e0 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);
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 3958f70f3202..20ae747ddf34 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -678,6 +678,12 @@
678#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ 678#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
679#define PCI_EXT_CAP_PWR_SIZEOF 16 679#define PCI_EXT_CAP_PWR_SIZEOF 16
680 680
681/* Vendor-Specific (VSEC, PCI_EXT_CAP_ID_VNDR) */
682#define PCI_VNDR_HEADER 4 /* Vendor-Specific Header */
683#define PCI_VNDR_HEADER_ID(x) ((x) & 0xffff)
684#define PCI_VNDR_HEADER_REV(x) (((x) >> 16) & 0xf)
685#define PCI_VNDR_HEADER_LEN(x) (((x) >> 20) & 0xfff)
686
681/* 687/*
682 * Hypertransport sub capability types 688 * Hypertransport sub capability types
683 * 689 *