![]() |
|
|||
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);
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |