root/drivers/pci/search.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pci_for_each_dma_alias
  2. pci_do_find_bus
  3. pci_find_bus
  4. pci_find_next_bus
  5. pci_get_slot
  6. pci_get_domain_bus_and_slot
  7. match_pci_dev_by_id
  8. pci_get_dev_by_id
  9. pci_get_subsys
  10. pci_get_device
  11. pci_get_class
  12. pci_dev_present

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * PCI searching functions
   4  *
   5  * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
   6  *                                      David Mosberger-Tang
   7  * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz>
   8  * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>
   9  */
  10 
  11 #include <linux/pci.h>
  12 #include <linux/slab.h>
  13 #include <linux/module.h>
  14 #include <linux/interrupt.h>
  15 #include "pci.h"
  16 
  17 DECLARE_RWSEM(pci_bus_sem);
  18 
  19 /*
  20  * pci_for_each_dma_alias - Iterate over DMA aliases for a device
  21  * @pdev: starting downstream device
  22  * @fn: function to call for each alias
  23  * @data: opaque data to pass to @fn
  24  *
  25  * Starting @pdev, walk up the bus calling @fn for each possible alias
  26  * of @pdev at the root bus.
  27  */
  28 int pci_for_each_dma_alias(struct pci_dev *pdev,
  29                            int (*fn)(struct pci_dev *pdev,
  30                                      u16 alias, void *data), void *data)
  31 {
  32         struct pci_bus *bus;
  33         int ret;
  34 
  35         ret = fn(pdev, pci_dev_id(pdev), data);
  36         if (ret)
  37                 return ret;
  38 
  39         /*
  40          * If the device is broken and uses an alias requester ID for
  41          * DMA, iterate over that too.
  42          */
  43         if (unlikely(pdev->dma_alias_mask)) {
  44                 unsigned int devfn;
  45 
  46                 for_each_set_bit(devfn, pdev->dma_alias_mask, MAX_NR_DEVFNS) {
  47                         ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn),
  48                                  data);
  49                         if (ret)
  50                                 return ret;
  51                 }
  52         }
  53 
  54         for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
  55                 struct pci_dev *tmp;
  56 
  57                 /* Skip virtual buses */
  58                 if (!bus->self)
  59                         continue;
  60 
  61                 tmp = bus->self;
  62 
  63                 /* stop at bridge where translation unit is associated */
  64                 if (tmp->dev_flags & PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT)
  65                         return ret;
  66 
  67                 /*
  68                  * PCIe-to-PCI/X bridges alias transactions from downstream
  69                  * devices using the subordinate bus number (PCI Express to
  70                  * PCI/PCI-X Bridge Spec, rev 1.0, sec 2.3).  For all cases
  71                  * where the upstream bus is PCI/X we alias to the bridge
  72                  * (there are various conditions in the previous reference
  73                  * where the bridge may take ownership of transactions, even
  74                  * when the secondary interface is PCI-X).
  75                  */
  76                 if (pci_is_pcie(tmp)) {
  77                         switch (pci_pcie_type(tmp)) {
  78                         case PCI_EXP_TYPE_ROOT_PORT:
  79                         case PCI_EXP_TYPE_UPSTREAM:
  80                         case PCI_EXP_TYPE_DOWNSTREAM:
  81                                 continue;
  82                         case PCI_EXP_TYPE_PCI_BRIDGE:
  83                                 ret = fn(tmp,
  84                                          PCI_DEVID(tmp->subordinate->number,
  85                                                    PCI_DEVFN(0, 0)), data);
  86                                 if (ret)
  87                                         return ret;
  88                                 continue;
  89                         case PCI_EXP_TYPE_PCIE_BRIDGE:
  90                                 ret = fn(tmp, pci_dev_id(tmp), data);
  91                                 if (ret)
  92                                         return ret;
  93                                 continue;
  94                         }
  95                 } else {
  96                         if (tmp->dev_flags & PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS)
  97                                 ret = fn(tmp,
  98                                          PCI_DEVID(tmp->subordinate->number,
  99                                                    PCI_DEVFN(0, 0)), data);
 100                         else
 101                                 ret = fn(tmp, pci_dev_id(tmp), data);
 102                         if (ret)
 103                                 return ret;
 104                 }
 105         }
 106 
 107         return ret;
 108 }
 109 
 110 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
 111 {
 112         struct pci_bus *child;
 113         struct pci_bus *tmp;
 114 
 115         if (bus->number == busnr)
 116                 return bus;
 117 
 118         list_for_each_entry(tmp, &bus->children, node) {
 119                 child = pci_do_find_bus(tmp, busnr);
 120                 if (child)
 121                         return child;
 122         }
 123         return NULL;
 124 }
 125 
 126 /**
 127  * pci_find_bus - locate PCI bus from a given domain and bus number
 128  * @domain: number of PCI domain to search
 129  * @busnr: number of desired PCI bus
 130  *
 131  * Given a PCI bus number and domain number, the desired PCI bus is located
 132  * in the global list of PCI buses.  If the bus is found, a pointer to its
 133  * data structure is returned.  If no bus is found, %NULL is returned.
 134  */
 135 struct pci_bus *pci_find_bus(int domain, int busnr)
 136 {
 137         struct pci_bus *bus = NULL;
 138         struct pci_bus *tmp_bus;
 139 
 140         while ((bus = pci_find_next_bus(bus)) != NULL)  {
 141                 if (pci_domain_nr(bus) != domain)
 142                         continue;
 143                 tmp_bus = pci_do_find_bus(bus, busnr);
 144                 if (tmp_bus)
 145                         return tmp_bus;
 146         }
 147         return NULL;
 148 }
 149 EXPORT_SYMBOL(pci_find_bus);
 150 
 151 /**
 152  * pci_find_next_bus - begin or continue searching for a PCI bus
 153  * @from: Previous PCI bus found, or %NULL for new search.
 154  *
 155  * Iterates through the list of known PCI buses.  A new search is
 156  * initiated by passing %NULL as the @from argument.  Otherwise if
 157  * @from is not %NULL, searches continue from next device on the
 158  * global list.
 159  */
 160 struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
 161 {
 162         struct list_head *n;
 163         struct pci_bus *b = NULL;
 164 
 165         WARN_ON(in_interrupt());
 166         down_read(&pci_bus_sem);
 167         n = from ? from->node.next : pci_root_buses.next;
 168         if (n != &pci_root_buses)
 169                 b = list_entry(n, struct pci_bus, node);
 170         up_read(&pci_bus_sem);
 171         return b;
 172 }
 173 EXPORT_SYMBOL(pci_find_next_bus);
 174 
 175 /**
 176  * pci_get_slot - locate PCI device for a given PCI slot
 177  * @bus: PCI bus on which desired PCI device resides
 178  * @devfn: encodes number of PCI slot in which the desired PCI
 179  * device resides and the logical device number within that slot
 180  * in case of multi-function devices.
 181  *
 182  * Given a PCI bus and slot/function number, the desired PCI device
 183  * is located in the list of PCI devices.
 184  * If the device is found, its reference count is increased and this
 185  * function returns a pointer to its data structure.  The caller must
 186  * decrement the reference count by calling pci_dev_put().
 187  * If no device is found, %NULL is returned.
 188  */
 189 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
 190 {
 191         struct pci_dev *dev;
 192 
 193         WARN_ON(in_interrupt());
 194         down_read(&pci_bus_sem);
 195 
 196         list_for_each_entry(dev, &bus->devices, bus_list) {
 197                 if (dev->devfn == devfn)
 198                         goto out;
 199         }
 200 
 201         dev = NULL;
 202  out:
 203         pci_dev_get(dev);
 204         up_read(&pci_bus_sem);
 205         return dev;
 206 }
 207 EXPORT_SYMBOL(pci_get_slot);
 208 
 209 /**
 210  * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot
 211  * @domain: PCI domain/segment on which the PCI device resides.
 212  * @bus: PCI bus on which desired PCI device resides
 213  * @devfn: encodes number of PCI slot in which the desired PCI device
 214  * resides and the logical device number within that slot in case of
 215  * multi-function devices.
 216  *
 217  * Given a PCI domain, bus, and slot/function number, the desired PCI
 218  * device is located in the list of PCI devices. If the device is
 219  * found, its reference count is increased and this function returns a
 220  * pointer to its data structure.  The caller must decrement the
 221  * reference count by calling pci_dev_put().  If no device is found,
 222  * %NULL is returned.
 223  */
 224 struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
 225                                             unsigned int devfn)
 226 {
 227         struct pci_dev *dev = NULL;
 228 
 229         for_each_pci_dev(dev) {
 230                 if (pci_domain_nr(dev->bus) == domain &&
 231                     (dev->bus->number == bus && dev->devfn == devfn))
 232                         return dev;
 233         }
 234         return NULL;
 235 }
 236 EXPORT_SYMBOL(pci_get_domain_bus_and_slot);
 237 
 238 static int match_pci_dev_by_id(struct device *dev, const void *data)
 239 {
 240         struct pci_dev *pdev = to_pci_dev(dev);
 241         const struct pci_device_id *id = data;
 242 
 243         if (pci_match_one_device(id, pdev))
 244                 return 1;
 245         return 0;
 246 }
 247 
 248 /*
 249  * pci_get_dev_by_id - begin or continue searching for a PCI device by id
 250  * @id: pointer to struct pci_device_id to match for the device
 251  * @from: Previous PCI device found in search, or %NULL for new search.
 252  *
 253  * Iterates through the list of known PCI devices.  If a PCI device is found
 254  * with a matching id a pointer to its device structure is returned, and the
 255  * reference count to the device is incremented.  Otherwise, %NULL is returned.
 256  * A new search is initiated by passing %NULL as the @from argument.  Otherwise
 257  * if @from is not %NULL, searches continue from next device on the global
 258  * list.  The reference count for @from is always decremented if it is not
 259  * %NULL.
 260  *
 261  * This is an internal function for use by the other search functions in
 262  * this file.
 263  */
 264 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
 265                                          struct pci_dev *from)
 266 {
 267         struct device *dev;
 268         struct device *dev_start = NULL;
 269         struct pci_dev *pdev = NULL;
 270 
 271         WARN_ON(in_interrupt());
 272         if (from)
 273                 dev_start = &from->dev;
 274         dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
 275                               match_pci_dev_by_id);
 276         if (dev)
 277                 pdev = to_pci_dev(dev);
 278         pci_dev_put(from);
 279         return pdev;
 280 }
 281 
 282 /**
 283  * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
 284  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
 285  * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
 286  * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
 287  * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
 288  * @from: Previous PCI device found in search, or %NULL for new search.
 289  *
 290  * Iterates through the list of known PCI devices.  If a PCI device is found
 291  * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
 292  * device structure is returned, and the reference count to the device is
 293  * incremented.  Otherwise, %NULL is returned.  A new search is initiated by
 294  * passing %NULL as the @from argument.  Otherwise if @from is not %NULL,
 295  * searches continue from next device on the global list.
 296  * The reference count for @from is always decremented if it is not %NULL.
 297  */
 298 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
 299                                unsigned int ss_vendor, unsigned int ss_device,
 300                                struct pci_dev *from)
 301 {
 302         struct pci_device_id id = {
 303                 .vendor = vendor,
 304                 .device = device,
 305                 .subvendor = ss_vendor,
 306                 .subdevice = ss_device,
 307         };
 308 
 309         return pci_get_dev_by_id(&id, from);
 310 }
 311 EXPORT_SYMBOL(pci_get_subsys);
 312 
 313 /**
 314  * pci_get_device - begin or continue searching for a PCI device by vendor/device id
 315  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
 316  * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
 317  * @from: Previous PCI device found in search, or %NULL for new search.
 318  *
 319  * Iterates through the list of known PCI devices.  If a PCI device is
 320  * found with a matching @vendor and @device, the reference count to the
 321  * device is incremented and a pointer to its device structure is returned.
 322  * Otherwise, %NULL is returned.  A new search is initiated by passing %NULL
 323  * as the @from argument.  Otherwise if @from is not %NULL, searches continue
 324  * from next device on the global list.  The reference count for @from is
 325  * always decremented if it is not %NULL.
 326  */
 327 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
 328                                struct pci_dev *from)
 329 {
 330         return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
 331 }
 332 EXPORT_SYMBOL(pci_get_device);
 333 
 334 /**
 335  * pci_get_class - begin or continue searching for a PCI device by class
 336  * @class: search for a PCI device with this class designation
 337  * @from: Previous PCI device found in search, or %NULL for new search.
 338  *
 339  * Iterates through the list of known PCI devices.  If a PCI device is
 340  * found with a matching @class, the reference count to the device is
 341  * incremented and a pointer to its device structure is returned.
 342  * Otherwise, %NULL is returned.
 343  * A new search is initiated by passing %NULL as the @from argument.
 344  * Otherwise if @from is not %NULL, searches continue from next device
 345  * on the global list.  The reference count for @from is always decremented
 346  * if it is not %NULL.
 347  */
 348 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
 349 {
 350         struct pci_device_id id = {
 351                 .vendor = PCI_ANY_ID,
 352                 .device = PCI_ANY_ID,
 353                 .subvendor = PCI_ANY_ID,
 354                 .subdevice = PCI_ANY_ID,
 355                 .class_mask = PCI_ANY_ID,
 356                 .class = class,
 357         };
 358 
 359         return pci_get_dev_by_id(&id, from);
 360 }
 361 EXPORT_SYMBOL(pci_get_class);
 362 
 363 /**
 364  * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
 365  * @ids: A pointer to a null terminated list of struct pci_device_id structures
 366  * that describe the type of PCI device the caller is trying to find.
 367  *
 368  * Obvious fact: You do not have a reference to any device that might be found
 369  * by this function, so if that device is removed from the system right after
 370  * this function is finished, the value will be stale.  Use this function to
 371  * find devices that are usually built into a system, or for a general hint as
 372  * to if another device happens to be present at this specific moment in time.
 373  */
 374 int pci_dev_present(const struct pci_device_id *ids)
 375 {
 376         struct pci_dev *found = NULL;
 377 
 378         WARN_ON(in_interrupt());
 379         while (ids->vendor || ids->subvendor || ids->class_mask) {
 380                 found = pci_get_dev_by_id(ids, NULL);
 381                 if (found) {
 382                         pci_dev_put(found);
 383                         return 1;
 384                 }
 385                 ids++;
 386         }
 387 
 388         return 0;
 389 }
 390 EXPORT_SYMBOL(pci_dev_present);

/* [<][>][^][v][top][bottom][index][help] */