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