Commit 29f3eb64634cf96903a3cdb56b1f9a80bebad17d
Committed by
Greg Kroah-Hartman
1 parent
11f242f04c
Exists in
master
and in
7 other branches
pci: Additional search functions
In order to finish converting to pci_get_* interfaces we need to add a couple of bits of missing functionaility pci_get_bus_and_slot() provides the equivalent to pci_find_slot() (pci_get_slot is already taken as a name for something similar but not the same) pci_get_device_reverse() is the equivalent of pci_find_device_reverse but refcounting Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 2 changed files with 72 additions and 3 deletions Side-by-side Diff
drivers/pci/search.c
... | ... | @@ -140,6 +140,31 @@ |
140 | 140 | } |
141 | 141 | |
142 | 142 | /** |
143 | + * pci_get_bus_and_slot - locate PCI device from a given PCI slot | |
144 | + * @bus: number of PCI bus on which desired PCI device resides | |
145 | + * @devfn: encodes number of PCI slot in which the desired PCI | |
146 | + * device resides and the logical device number within that slot | |
147 | + * in case of multi-function devices. | |
148 | + * | |
149 | + * Given a PCI bus and slot/function number, the desired PCI device | |
150 | + * is located in system global list of PCI devices. If the device | |
151 | + * is found, a pointer to its data structure is returned. If no | |
152 | + * device is found, %NULL is returned. The returned device has its | |
153 | + * reference count bumped by one. | |
154 | + */ | |
155 | + | |
156 | +struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | |
157 | +{ | |
158 | + struct pci_dev *dev = NULL; | |
159 | + | |
160 | + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | |
161 | + if (dev->bus->number == bus && dev->devfn == devfn) | |
162 | + return dev; | |
163 | + } | |
164 | + return NULL; | |
165 | +} | |
166 | + | |
167 | +/** | |
143 | 168 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id |
144 | 169 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids |
145 | 170 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
146 | 171 | |
... | ... | @@ -274,7 +299,46 @@ |
274 | 299 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); |
275 | 300 | } |
276 | 301 | |
302 | +/** | |
303 | + * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id | |
304 | + * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | |
305 | + * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | |
306 | + * @from: Previous PCI device found in search, or %NULL for new search. | |
307 | + * | |
308 | + * Iterates through the list of known PCI devices in the reverse order of | |
309 | + * pci_get_device. | |
310 | + * If a PCI device is found with a matching @vendor and @device, the reference | |
311 | + * count to the device is incremented and a pointer to its device structure | |
312 | + * is returned Otherwise, %NULL is returned. A new search is initiated by | |
313 | + * passing %NULL as the @from argument. Otherwise if @from is not %NULL, | |
314 | + * searches continue from next device on the global list. The reference | |
315 | + * count for @from is always decremented if it is not %NULL. | |
316 | + */ | |
317 | +struct pci_dev * | |
318 | +pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from) | |
319 | +{ | |
320 | + struct list_head *n; | |
321 | + struct pci_dev *dev; | |
277 | 322 | |
323 | + WARN_ON(in_interrupt()); | |
324 | + down_read(&pci_bus_sem); | |
325 | + n = from ? from->global_list.prev : pci_devices.prev; | |
326 | + | |
327 | + while (n && (n != &pci_devices)) { | |
328 | + dev = pci_dev_g(n); | |
329 | + if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && | |
330 | + (device == PCI_ANY_ID || dev->device == device)) | |
331 | + goto exit; | |
332 | + n = n->prev; | |
333 | + } | |
334 | + dev = NULL; | |
335 | +exit: | |
336 | + dev = pci_dev_get(dev); | |
337 | + up_read(&pci_bus_sem); | |
338 | + pci_dev_put(from); | |
339 | + return dev; | |
340 | +} | |
341 | + | |
278 | 342 | /** |
279 | 343 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id |
280 | 344 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids |
281 | 345 | |
282 | 346 | |
283 | 347 | |
... | ... | @@ -382,13 +446,17 @@ |
382 | 446 | } |
383 | 447 | EXPORT_SYMBOL(pci_dev_present); |
384 | 448 | |
385 | -EXPORT_SYMBOL(pci_find_bus); | |
386 | -EXPORT_SYMBOL(pci_find_next_bus); | |
387 | 449 | EXPORT_SYMBOL(pci_find_device); |
388 | 450 | EXPORT_SYMBOL(pci_find_device_reverse); |
389 | 451 | EXPORT_SYMBOL(pci_find_slot); |
452 | +/* For boot time work */ | |
453 | +EXPORT_SYMBOL(pci_find_bus); | |
454 | +EXPORT_SYMBOL(pci_find_next_bus); | |
455 | +/* For everyone */ | |
390 | 456 | EXPORT_SYMBOL(pci_get_device); |
457 | +EXPORT_SYMBOL(pci_get_device_reverse); | |
391 | 458 | EXPORT_SYMBOL(pci_get_subsys); |
392 | 459 | EXPORT_SYMBOL(pci_get_slot); |
460 | +EXPORT_SYMBOL(pci_get_bus_and_slot); | |
393 | 461 | EXPORT_SYMBOL(pci_get_class); |
include/linux/pci.h
... | ... | @@ -452,13 +452,14 @@ |
452 | 452 | int pci_find_capability (struct pci_dev *dev, int cap); |
453 | 453 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); |
454 | 454 | int pci_find_ext_capability (struct pci_dev *dev, int cap); |
455 | -struct pci_bus * pci_find_next_bus(const struct pci_bus *from); | |
455 | +struct pci_bus *pci_find_next_bus(const struct pci_bus *from); | |
456 | 456 | |
457 | 457 | struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); |
458 | 458 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, |
459 | 459 | unsigned int ss_vendor, unsigned int ss_device, |
460 | 460 | struct pci_dev *from); |
461 | 461 | struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); |
462 | +struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); | |
462 | 463 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); |
463 | 464 | int pci_dev_present(const struct pci_device_id *ids); |
464 | 465 |