Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PCI searching functions
0004  *
0005  * Copyright (C) 1993 -- 1997 Drew Eckhardt, Frederic Potter,
0006  *                  David Mosberger-Tang
0007  * Copyright (C) 1997 -- 2000 Martin Mares <mj@ucw.cz>
0008  * Copyright (C) 2003 -- 2004 Greg Kroah-Hartman <greg@kroah.com>
0009  */
0010 
0011 #include <linux/pci.h>
0012 #include <linux/slab.h>
0013 #include <linux/module.h>
0014 #include <linux/interrupt.h>
0015 #include "pci.h"
0016 
0017 DECLARE_RWSEM(pci_bus_sem);
0018 
0019 /*
0020  * pci_for_each_dma_alias - Iterate over DMA aliases for a device
0021  * @pdev: starting downstream device
0022  * @fn: function to call for each alias
0023  * @data: opaque data to pass to @fn
0024  *
0025  * Starting @pdev, walk up the bus calling @fn for each possible alias
0026  * of @pdev at the root bus.
0027  */
0028 int pci_for_each_dma_alias(struct pci_dev *pdev,
0029                int (*fn)(struct pci_dev *pdev,
0030                      u16 alias, void *data), void *data)
0031 {
0032     struct pci_bus *bus;
0033     int ret;
0034 
0035     /*
0036      * The device may have an explicit alias requester ID for DMA where the
0037      * requester is on another PCI bus.
0038      */
0039     pdev = pci_real_dma_dev(pdev);
0040 
0041     ret = fn(pdev, pci_dev_id(pdev), data);
0042     if (ret)
0043         return ret;
0044 
0045     /*
0046      * If the device is broken and uses an alias requester ID for
0047      * DMA, iterate over that too.
0048      */
0049     if (unlikely(pdev->dma_alias_mask)) {
0050         unsigned int devfn;
0051 
0052         for_each_set_bit(devfn, pdev->dma_alias_mask, MAX_NR_DEVFNS) {
0053             ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn),
0054                  data);
0055             if (ret)
0056                 return ret;
0057         }
0058     }
0059 
0060     for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
0061         struct pci_dev *tmp;
0062 
0063         /* Skip virtual buses */
0064         if (!bus->self)
0065             continue;
0066 
0067         tmp = bus->self;
0068 
0069         /* stop at bridge where translation unit is associated */
0070         if (tmp->dev_flags & PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT)
0071             return ret;
0072 
0073         /*
0074          * PCIe-to-PCI/X bridges alias transactions from downstream
0075          * devices using the subordinate bus number (PCI Express to
0076          * PCI/PCI-X Bridge Spec, rev 1.0, sec 2.3).  For all cases
0077          * where the upstream bus is PCI/X we alias to the bridge
0078          * (there are various conditions in the previous reference
0079          * where the bridge may take ownership of transactions, even
0080          * when the secondary interface is PCI-X).
0081          */
0082         if (pci_is_pcie(tmp)) {
0083             switch (pci_pcie_type(tmp)) {
0084             case PCI_EXP_TYPE_ROOT_PORT:
0085             case PCI_EXP_TYPE_UPSTREAM:
0086             case PCI_EXP_TYPE_DOWNSTREAM:
0087                 continue;
0088             case PCI_EXP_TYPE_PCI_BRIDGE:
0089                 ret = fn(tmp,
0090                      PCI_DEVID(tmp->subordinate->number,
0091                            PCI_DEVFN(0, 0)), data);
0092                 if (ret)
0093                     return ret;
0094                 continue;
0095             case PCI_EXP_TYPE_PCIE_BRIDGE:
0096                 ret = fn(tmp, pci_dev_id(tmp), data);
0097                 if (ret)
0098                     return ret;
0099                 continue;
0100             }
0101         } else {
0102             if (tmp->dev_flags & PCI_DEV_FLAG_PCIE_BRIDGE_ALIAS)
0103                 ret = fn(tmp,
0104                      PCI_DEVID(tmp->subordinate->number,
0105                            PCI_DEVFN(0, 0)), data);
0106             else
0107                 ret = fn(tmp, pci_dev_id(tmp), data);
0108             if (ret)
0109                 return ret;
0110         }
0111     }
0112 
0113     return ret;
0114 }
0115 
0116 static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
0117 {
0118     struct pci_bus *child;
0119     struct pci_bus *tmp;
0120 
0121     if (bus->number == busnr)
0122         return bus;
0123 
0124     list_for_each_entry(tmp, &bus->children, node) {
0125         child = pci_do_find_bus(tmp, busnr);
0126         if (child)
0127             return child;
0128     }
0129     return NULL;
0130 }
0131 
0132 /**
0133  * pci_find_bus - locate PCI bus from a given domain and bus number
0134  * @domain: number of PCI domain to search
0135  * @busnr: number of desired PCI bus
0136  *
0137  * Given a PCI bus number and domain number, the desired PCI bus is located
0138  * in the global list of PCI buses.  If the bus is found, a pointer to its
0139  * data structure is returned.  If no bus is found, %NULL is returned.
0140  */
0141 struct pci_bus *pci_find_bus(int domain, int busnr)
0142 {
0143     struct pci_bus *bus = NULL;
0144     struct pci_bus *tmp_bus;
0145 
0146     while ((bus = pci_find_next_bus(bus)) != NULL)  {
0147         if (pci_domain_nr(bus) != domain)
0148             continue;
0149         tmp_bus = pci_do_find_bus(bus, busnr);
0150         if (tmp_bus)
0151             return tmp_bus;
0152     }
0153     return NULL;
0154 }
0155 EXPORT_SYMBOL(pci_find_bus);
0156 
0157 /**
0158  * pci_find_next_bus - begin or continue searching for a PCI bus
0159  * @from: Previous PCI bus found, or %NULL for new search.
0160  *
0161  * Iterates through the list of known PCI buses.  A new search is
0162  * initiated by passing %NULL as the @from argument.  Otherwise if
0163  * @from is not %NULL, searches continue from next device on the
0164  * global list.
0165  */
0166 struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
0167 {
0168     struct list_head *n;
0169     struct pci_bus *b = NULL;
0170 
0171     down_read(&pci_bus_sem);
0172     n = from ? from->node.next : pci_root_buses.next;
0173     if (n != &pci_root_buses)
0174         b = list_entry(n, struct pci_bus, node);
0175     up_read(&pci_bus_sem);
0176     return b;
0177 }
0178 EXPORT_SYMBOL(pci_find_next_bus);
0179 
0180 /**
0181  * pci_get_slot - locate PCI device for a given PCI slot
0182  * @bus: PCI bus on which desired PCI device resides
0183  * @devfn: encodes number of PCI slot in which the desired PCI
0184  * device resides and the logical device number within that slot
0185  * in case of multi-function devices.
0186  *
0187  * Given a PCI bus and slot/function number, the desired PCI device
0188  * is located in the list of PCI devices.
0189  * If the device is found, its reference count is increased and this
0190  * function returns a pointer to its data structure.  The caller must
0191  * decrement the reference count by calling pci_dev_put().
0192  * If no device is found, %NULL is returned.
0193  */
0194 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
0195 {
0196     struct pci_dev *dev;
0197 
0198     down_read(&pci_bus_sem);
0199 
0200     list_for_each_entry(dev, &bus->devices, bus_list) {
0201         if (dev->devfn == devfn)
0202             goto out;
0203     }
0204 
0205     dev = NULL;
0206  out:
0207     pci_dev_get(dev);
0208     up_read(&pci_bus_sem);
0209     return dev;
0210 }
0211 EXPORT_SYMBOL(pci_get_slot);
0212 
0213 /**
0214  * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot
0215  * @domain: PCI domain/segment on which the PCI device resides.
0216  * @bus: PCI bus on which desired PCI device resides
0217  * @devfn: encodes number of PCI slot in which the desired PCI device
0218  * resides and the logical device number within that slot in case of
0219  * multi-function devices.
0220  *
0221  * Given a PCI domain, bus, and slot/function number, the desired PCI
0222  * device is located in the list of PCI devices. If the device is
0223  * found, its reference count is increased and this function returns a
0224  * pointer to its data structure.  The caller must decrement the
0225  * reference count by calling pci_dev_put().  If no device is found,
0226  * %NULL is returned.
0227  */
0228 struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
0229                         unsigned int devfn)
0230 {
0231     struct pci_dev *dev = NULL;
0232 
0233     for_each_pci_dev(dev) {
0234         if (pci_domain_nr(dev->bus) == domain &&
0235             (dev->bus->number == bus && dev->devfn == devfn))
0236             return dev;
0237     }
0238     return NULL;
0239 }
0240 EXPORT_SYMBOL(pci_get_domain_bus_and_slot);
0241 
0242 static int match_pci_dev_by_id(struct device *dev, const void *data)
0243 {
0244     struct pci_dev *pdev = to_pci_dev(dev);
0245     const struct pci_device_id *id = data;
0246 
0247     if (pci_match_one_device(id, pdev))
0248         return 1;
0249     return 0;
0250 }
0251 
0252 /*
0253  * pci_get_dev_by_id - begin or continue searching for a PCI device by id
0254  * @id: pointer to struct pci_device_id to match for the device
0255  * @from: Previous PCI device found in search, or %NULL for new search.
0256  *
0257  * Iterates through the list of known PCI devices.  If a PCI device is found
0258  * with a matching id a pointer to its device structure is returned, and the
0259  * reference count to the device is incremented.  Otherwise, %NULL is returned.
0260  * A new search is initiated by passing %NULL as the @from argument.  Otherwise
0261  * if @from is not %NULL, searches continue from next device on the global
0262  * list.  The reference count for @from is always decremented if it is not
0263  * %NULL.
0264  *
0265  * This is an internal function for use by the other search functions in
0266  * this file.
0267  */
0268 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
0269                      struct pci_dev *from)
0270 {
0271     struct device *dev;
0272     struct device *dev_start = NULL;
0273     struct pci_dev *pdev = NULL;
0274 
0275     if (from)
0276         dev_start = &from->dev;
0277     dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
0278                   match_pci_dev_by_id);
0279     if (dev)
0280         pdev = to_pci_dev(dev);
0281     pci_dev_put(from);
0282     return pdev;
0283 }
0284 
0285 /**
0286  * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
0287  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
0288  * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
0289  * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
0290  * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
0291  * @from: Previous PCI device found in search, or %NULL for new search.
0292  *
0293  * Iterates through the list of known PCI devices.  If a PCI device is found
0294  * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
0295  * device structure is returned, and the reference count to the device is
0296  * incremented.  Otherwise, %NULL is returned.  A new search is initiated by
0297  * passing %NULL as the @from argument.  Otherwise if @from is not %NULL,
0298  * searches continue from next device on the global list.
0299  * The reference count for @from is always decremented if it is not %NULL.
0300  */
0301 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
0302                    unsigned int ss_vendor, unsigned int ss_device,
0303                    struct pci_dev *from)
0304 {
0305     struct pci_device_id id = {
0306         .vendor = vendor,
0307         .device = device,
0308         .subvendor = ss_vendor,
0309         .subdevice = ss_device,
0310     };
0311 
0312     return pci_get_dev_by_id(&id, from);
0313 }
0314 EXPORT_SYMBOL(pci_get_subsys);
0315 
0316 /**
0317  * pci_get_device - begin or continue searching for a PCI device by vendor/device id
0318  * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
0319  * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
0320  * @from: Previous PCI device found in search, or %NULL for new search.
0321  *
0322  * Iterates through the list of known PCI devices.  If a PCI device is
0323  * found with a matching @vendor and @device, the reference count to the
0324  * device is incremented and a pointer to its device structure is returned.
0325  * Otherwise, %NULL is returned.  A new search is initiated by passing %NULL
0326  * as the @from argument.  Otherwise if @from is not %NULL, searches continue
0327  * from next device on the global list.  The reference count for @from is
0328  * always decremented if it is not %NULL.
0329  */
0330 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
0331                    struct pci_dev *from)
0332 {
0333     return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
0334 }
0335 EXPORT_SYMBOL(pci_get_device);
0336 
0337 /**
0338  * pci_get_class - begin or continue searching for a PCI device by class
0339  * @class: search for a PCI device with this class designation
0340  * @from: Previous PCI device found in search, or %NULL for new search.
0341  *
0342  * Iterates through the list of known PCI devices.  If a PCI device is
0343  * found with a matching @class, the reference count to the device is
0344  * incremented and a pointer to its device structure is returned.
0345  * Otherwise, %NULL is returned.
0346  * A new search is initiated by passing %NULL as the @from argument.
0347  * Otherwise if @from is not %NULL, searches continue from next device
0348  * on the global list.  The reference count for @from is always decremented
0349  * if it is not %NULL.
0350  */
0351 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
0352 {
0353     struct pci_device_id id = {
0354         .vendor = PCI_ANY_ID,
0355         .device = PCI_ANY_ID,
0356         .subvendor = PCI_ANY_ID,
0357         .subdevice = PCI_ANY_ID,
0358         .class_mask = PCI_ANY_ID,
0359         .class = class,
0360     };
0361 
0362     return pci_get_dev_by_id(&id, from);
0363 }
0364 EXPORT_SYMBOL(pci_get_class);
0365 
0366 /**
0367  * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
0368  * @ids: A pointer to a null terminated list of struct pci_device_id structures
0369  * that describe the type of PCI device the caller is trying to find.
0370  *
0371  * Obvious fact: You do not have a reference to any device that might be found
0372  * by this function, so if that device is removed from the system right after
0373  * this function is finished, the value will be stale.  Use this function to
0374  * find devices that are usually built into a system, or for a general hint as
0375  * to if another device happens to be present at this specific moment in time.
0376  */
0377 int pci_dev_present(const struct pci_device_id *ids)
0378 {
0379     struct pci_dev *found = NULL;
0380 
0381     while (ids->vendor || ids->subvendor || ids->class_mask) {
0382         found = pci_get_dev_by_id(ids, NULL);
0383         if (found) {
0384             pci_dev_put(found);
0385             return 1;
0386         }
0387         ids++;
0388     }
0389 
0390     return 0;
0391 }
0392 EXPORT_SYMBOL(pci_dev_present);