diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-10-16 19:20:21 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-10-18 14:36:12 -0400 |
commit | 29f3eb64634cf96903a3cdb56b1f9a80bebad17d (patch) | |
tree | d72f67470fcca932d42e9f38e6b9a03a49df30b3 | |
parent | 11f242f04c6d886494cc83097cb6def044eabebb (diff) |
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>
-rw-r--r-- | drivers/pci/search.c | 72 | ||||
-rw-r--r-- | include/linux/pci.h | 3 |
2 files changed, 72 insertions, 3 deletions
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index d529462d1b53..2f13eba5d5ae 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -140,6 +140,31 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
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 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id | 168 | * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id |
144 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids | 169 | * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids |
145 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids | 170 | * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids |
@@ -274,6 +299,45 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) | |||
274 | return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); | 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; | ||
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 | } | ||
277 | 341 | ||
278 | /** | 342 | /** |
279 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id | 343 | * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id |
@@ -382,12 +446,16 @@ exit: | |||
382 | } | 446 | } |
383 | EXPORT_SYMBOL(pci_dev_present); | 447 | EXPORT_SYMBOL(pci_dev_present); |
384 | 448 | ||
385 | EXPORT_SYMBOL(pci_find_bus); | ||
386 | EXPORT_SYMBOL(pci_find_next_bus); | ||
387 | EXPORT_SYMBOL(pci_find_device); | 449 | EXPORT_SYMBOL(pci_find_device); |
388 | EXPORT_SYMBOL(pci_find_device_reverse); | 450 | EXPORT_SYMBOL(pci_find_device_reverse); |
389 | EXPORT_SYMBOL(pci_find_slot); | 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 | EXPORT_SYMBOL(pci_get_device); | 456 | EXPORT_SYMBOL(pci_get_device); |
457 | EXPORT_SYMBOL(pci_get_device_reverse); | ||
391 | EXPORT_SYMBOL(pci_get_subsys); | 458 | EXPORT_SYMBOL(pci_get_subsys); |
392 | EXPORT_SYMBOL(pci_get_slot); | 459 | EXPORT_SYMBOL(pci_get_slot); |
460 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
393 | EXPORT_SYMBOL(pci_get_class); | 461 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 5c604f5fad67..09bf88fc80c5 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -452,13 +452,14 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); | |||
452 | int pci_find_capability (struct pci_dev *dev, int cap); | 452 | int pci_find_capability (struct pci_dev *dev, int cap); |
453 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); | 453 | int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); |
454 | int pci_find_ext_capability (struct pci_dev *dev, int cap); | 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 | struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); | 457 | struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); |
458 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, | 458 | struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, |
459 | unsigned int ss_vendor, unsigned int ss_device, | 459 | unsigned int ss_vendor, unsigned int ss_device, |
460 | struct pci_dev *from); | 460 | struct pci_dev *from); |
461 | struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); | 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 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); | 463 | struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); |
463 | int pci_dev_present(const struct pci_device_id *ids); | 464 | int pci_dev_present(const struct pci_device_id *ids); |
464 | 465 | ||