From 35f1f308dbad8a9896f9e1455f0c7c8b49a9cf1a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 5 Oct 2004 21:20:05 -0700 Subject: [PATCH] [PATCH] PCI: add pci_get_class() to make a safe pci_find_class() like call. Signed-off-by: Greg Kroah-Hartman --- Documentation/pci.txt | 5 +++-- drivers/pci/search.c | 38 ++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 4 ++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Documentation/pci.txt b/Documentation/pci.txt index af4e5e61ae404..04f1ba9c1a20e 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -146,7 +146,7 @@ Searching by vendor and device ID: Searching by class ID (iterate in a similar way): - pci_find_class(CLASS_ID, dev) + pci_get_class(CLASS_ID, dev) Searching by both vendor/device and subsystem vendor/device ID: @@ -281,5 +281,6 @@ pci_for_each_dev_reverse() Superseded by pci_find_device_reverse() pci_for_each_bus() Superseded by pci_find_next_bus() pci_find_device() Superseded by pci_get_device() pci_find_subsys() Superseded by pci_get_subsys() -pcibios_find_class() Superseded by pci_find_class() +pcibios_find_class() Superseded by pci_get_class() +pci_find_class() Superseded by pci_get_class() pci_(read|write)_*_nodev() Superseded by pci_bus_(read|write)_*() diff --git a/drivers/pci/search.c b/drivers/pci/search.c index b748ff55c6a41..f4a9586e8698e 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -348,6 +348,43 @@ exit: return dev; } +/** + * pci_get_class - begin or continue searching for a PCI device by class + * @class: search for a PCI device with this class designation + * @from: Previous PCI device found in search, or %NULL for new search. + * + * Iterates through the list of known PCI devices. If a PCI device is + * found with a matching @class, the reference count to the device is + * incremented and a pointer to its device structure is returned. + * Otherwise, %NULL is returned. + * A new search is initiated by passing %NULL to the @from argument. + * Otherwise if @from is not %NULL, searches continue from next device + * on the global list. The reference count for @from is always decremented + * if it is not %NULL. + */ +struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) +{ + struct list_head *n; + struct pci_dev *dev; + + WARN_ON(in_interrupt()); + spin_lock(&pci_bus_lock); + n = from ? from->global_list.next : pci_devices.next; + + while (n && (n != &pci_devices)) { + dev = pci_dev_g(n); + if (dev->class == class) + goto exit; + n = n->next; + } + dev = NULL; +exit: + pci_dev_put(from); + dev = pci_dev_get(dev); + spin_unlock(&pci_bus_lock); + return dev; +} + EXPORT_SYMBOL(pci_find_bus); EXPORT_SYMBOL(pci_find_class); EXPORT_SYMBOL(pci_find_device); @@ -356,3 +393,4 @@ EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_get_device); EXPORT_SYMBOL(pci_get_subsys); EXPORT_SYMBOL(pci_get_slot); +EXPORT_SYMBOL(pci_get_class); diff --git a/include/linux/pci.h b/include/linux/pci.h index 1e6704bedca20..ec10ab903fb10 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -730,6 +730,7 @@ struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from); struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); +struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); @@ -892,6 +893,9 @@ static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) { return NULL; } +static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) +{ return NULL; } + static inline void pci_set_master(struct pci_dev *dev) { } static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } static inline void pci_disable_device(struct pci_dev *dev) { } -- 2.53.0