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/init.h> 11 #include <linux/pci.h> 12 #include <linux/module.h> 13 #include <linux/interrupt.h> 14 #include "pci.h" 15 16 DECLARE_RWSEM(pci_bus_sem); 17 18 static struct pci_bus * 19 pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) 20 { 21 struct pci_bus* child; 22 struct list_head *tmp; 23 24 if(bus->number == busnr) 25 return bus; 26 27 list_for_each(tmp, &bus->children) { 28 child = pci_do_find_bus(pci_bus_b(tmp), busnr); 29 if(child) 30 return child; 31 } 32 return NULL; 33 } 34 35 /** 36 * pci_find_bus - locate PCI bus from a given domain and bus number 37 * @domain: number of PCI domain to search 38 * @busnr: number of desired PCI bus 39 * 40 * Given a PCI bus number and domain number, the desired PCI bus is located 41 * in the global list of PCI buses. If the bus is found, a pointer to its 42 * data structure is returned. If no bus is found, %NULL is returned. 43 */ 44 struct pci_bus * pci_find_bus(int domain, int busnr) 45 { 46 struct pci_bus *bus = NULL; 47 struct pci_bus *tmp_bus; 48 49 while ((bus = pci_find_next_bus(bus)) != NULL) { 50 if (pci_domain_nr(bus) != domain) 51 continue; 52 tmp_bus = pci_do_find_bus(bus, busnr); 53 if (tmp_bus) 54 return tmp_bus; 55 } 56 return NULL; 57 } 58 59 /** 60 * pci_find_next_bus - begin or continue searching for a PCI bus 61 * @from: Previous PCI bus found, or %NULL for new search. 62 * 63 * Iterates through the list of known PCI busses. A new search is 64 * initiated by passing %NULL as the @from argument. Otherwise if 65 * @from is not %NULL, searches continue from next device on the 66 * global list. 67 */ 68 struct pci_bus * 69 pci_find_next_bus(const struct pci_bus *from) 70 { 71 struct list_head *n; 72 struct pci_bus *b = NULL; 73 74 WARN_ON(in_interrupt()); 75 down_read(&pci_bus_sem); 76 n = from ? from->node.next : pci_root_buses.next; 77 if (n != &pci_root_buses) 78 b = pci_bus_b(n); 79 up_read(&pci_bus_sem); 80 return b; 81 } 82 83 /** 84 * pci_find_slot - locate PCI device from a given PCI slot 85 * @bus: number of PCI bus on which desired PCI device resides 86 * @devfn: encodes number of PCI slot in which the desired PCI 87 * device resides and the logical device number within that slot 88 * in case of multi-function devices. 89 * 90 * Given a PCI bus and slot/function number, the desired PCI device 91 * is located in system global list of PCI devices. If the device 92 * is found, a pointer to its data structure is returned. If no 93 * device is found, %NULL is returned. 94 */ 95 struct pci_dev * 96 pci_find_slot(unsigned int bus, unsigned int devfn) 97 { 98 struct pci_dev *dev = NULL; 99 100 while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 101 if (dev->bus->number == bus && dev->devfn == devfn) 102 return dev; 103 } 104 return NULL; 105 } 106 107 /** 108 * pci_get_slot - locate PCI device for a given PCI slot 109 * @bus: PCI bus on which desired PCI device resides 110 * @devfn: encodes number of PCI slot in which the desired PCI 111 * device resides and the logical device number within that slot 112 * in case of multi-function devices. 113 * 114 * Given a PCI bus and slot/function number, the desired PCI device 115 * is located in the list of PCI devices. 116 * If the device is found, its reference count is increased and this 117 * function returns a pointer to its data structure. The caller must 118 * decrement the reference count by calling pci_dev_put(). 119 * If no device is found, %NULL is returned. 120 */ 121 struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) 122 { 123 struct list_head *tmp; 124 struct pci_dev *dev; 125 126 WARN_ON(in_interrupt()); 127 down_read(&pci_bus_sem); 128 129 list_for_each(tmp, &bus->devices) { 130 dev = pci_dev_b(tmp); 131 if (dev->devfn == devfn) 132 goto out; 133 } 134 135 dev = NULL; 136 out: 137 pci_dev_get(dev); 138 up_read(&pci_bus_sem); 139 return dev; 140 } 141 142 /** 143 * pci_get_bus_and_slot - locate PCI device from a given PCI slot 144 * @bus: number of PCI bus on which desired PCI device resides 145 * @devfn: encodes number of PCI slot in which the desired PCI 146 * device resides and the logical device number within that slot 147 * in case of multi-function devices. 148 * 149 * Given a PCI bus and slot/function number, the desired PCI device 150 * is located in system global list of PCI devices. If the device 151 * is found, a pointer to its data structure is returned. If no 152 * device is found, %NULL is returned. The returned device has its 153 * reference count bumped by one. 154 */ 155 156 struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) 157 { 158 struct pci_dev *dev = NULL; 159 160 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 161 if (dev->bus->number == bus && dev->devfn == devfn) 162 return dev; 163 } 164 return NULL; 165 } 166 167 /** 168 * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id 169 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 170 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 171 * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids 172 * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids 173 * @from: Previous PCI device found in search, or %NULL for new search. 174 * 175 * Iterates through the list of known PCI devices. If a PCI device is 176 * found with a matching @vendor, @device, @ss_vendor and @ss_device, a 177 * pointer to its device structure is returned. Otherwise, %NULL is returned. 178 * A new search is initiated by passing %NULL as the @from argument. 179 * Otherwise if @from is not %NULL, searches continue from next device 180 * on the global list. 181 * 182 * NOTE: Do not use this function any more; use pci_get_subsys() instead, as 183 * the PCI device returned by this function can disappear at any moment in 184 * time. 185 */ 186 static struct pci_dev * pci_find_subsys(unsigned int vendor, 187 unsigned int device, 188 unsigned int ss_vendor, 189 unsigned int ss_device, 190 const struct pci_dev *from) 191 { 192 struct list_head *n; 193 struct pci_dev *dev; 194 195 WARN_ON(in_interrupt()); 196 197 /* 198 * pci_find_subsys() can be called on the ide_setup() path, super-early 199 * in boot. But the down_read() will enable local interrupts, which 200 * can cause some machines to crash. So here we detect and flag that 201 * situation and bail out early. 202 */ 203 if (unlikely(list_empty(&pci_devices))) 204 return NULL; 205 down_read(&pci_bus_sem); 206 n = from ? from->global_list.next : pci_devices.next; 207 208 while (n && (n != &pci_devices)) { 209 dev = pci_dev_g(n); 210 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && 211 (device == PCI_ANY_ID || dev->device == device) && 212 (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) && 213 (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device)) 214 goto exit; 215 n = n->next; 216 } 217 dev = NULL; 218 exit: 219 up_read(&pci_bus_sem); 220 return dev; 221 } 222 223 /** 224 * pci_find_device - begin or continue searching for a PCI device by vendor/device id 225 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 226 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 227 * @from: Previous PCI device found in search, or %NULL for new search. 228 * 229 * Iterates through the list of known PCI devices. If a PCI device is found 230 * with a matching @vendor and @device, a pointer to its device structure is 231 * returned. Otherwise, %NULL is returned. 232 * A new search is initiated by passing %NULL as the @from argument. 233 * Otherwise if @from is not %NULL, searches continue from next device 234 * on the global list. 235 * 236 * NOTE: Do not use this function any more; use pci_get_device() instead, as 237 * the PCI device returned by this function can disappear at any moment in 238 * time. 239 */ 240 struct pci_dev * 241 pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) 242 { 243 return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); 244 } 245 246 /** 247 * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id 248 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 249 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 250 * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids 251 * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids 252 * @from: Previous PCI device found in search, or %NULL for new search. 253 * 254 * Iterates through the list of known PCI devices. If a PCI device is found 255 * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its 256 * device structure is returned, and the reference count to the device is 257 * incremented. Otherwise, %NULL is returned. A new search is initiated by 258 * passing %NULL as the @from argument. Otherwise if @from is not %NULL, 259 * searches continue from next device on the global list. 260 * The reference count for @from is always decremented if it is not %NULL. 261 */ 262 struct pci_dev * 263 pci_get_subsys(unsigned int vendor, unsigned int device, 264 unsigned int ss_vendor, unsigned int ss_device, 265 struct pci_dev *from) 266 { 267 struct list_head *n; 268 struct pci_dev *dev; 269 270 WARN_ON(in_interrupt()); 271 272 /* 273 * pci_get_subsys() can potentially be called by drivers super-early 274 * in boot. But the down_read() will enable local interrupts, which 275 * can cause some machines to crash. So here we detect and flag that 276 * situation and bail out early. 277 */ 278 if (unlikely(list_empty(&pci_devices))) 279 return NULL; 280 down_read(&pci_bus_sem); 281 n = from ? from->global_list.next : pci_devices.next; 282 283 while (n && (n != &pci_devices)) { 284 dev = pci_dev_g(n); 285 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && 286 (device == PCI_ANY_ID || dev->device == device) && 287 (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) && 288 (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device)) 289 goto exit; 290 n = n->next; 291 } 292 dev = NULL; 293 exit: 294 dev = pci_dev_get(dev); 295 up_read(&pci_bus_sem); 296 pci_dev_put(from); 297 return dev; 298 } 299 300 /** 301 * pci_get_device - begin or continue searching for a PCI device by vendor/device id 302 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 303 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 304 * @from: Previous PCI device found in search, or %NULL for new search. 305 * 306 * Iterates through the list of known PCI devices. If a PCI device is 307 * found with a matching @vendor and @device, the reference count to the 308 * device is incremented and a pointer to its device structure is returned. 309 * Otherwise, %NULL is returned. A new search is initiated by passing %NULL 310 * as the @from argument. Otherwise if @from is not %NULL, searches continue 311 * from next device on the global list. The reference count for @from is 312 * always decremented if it is not %NULL. 313 */ 314 struct pci_dev * 315 pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) 316 { 317 return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); 318 } 319 320 /** 321 * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id 322 * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids 323 * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids 324 * @from: Previous PCI device found in search, or %NULL for new search. 325 * 326 * Iterates through the list of known PCI devices in the reverse order of 327 * pci_get_device. 328 * If a PCI device is found with a matching @vendor and @device, the reference 329 * count to the device is incremented and a pointer to its device structure 330 * is returned Otherwise, %NULL is returned. A new search is initiated by 331 * passing %NULL as the @from argument. Otherwise if @from is not %NULL, 332 * searches continue from next device on the global list. The reference 333 * count for @from is always decremented if it is not %NULL. 334 */ 335 struct pci_dev * 336 pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from) 337 { 338 struct list_head *n; 339 struct pci_dev *dev; 340 341 WARN_ON(in_interrupt()); 342 down_read(&pci_bus_sem); 343 n = from ? from->global_list.prev : pci_devices.prev; 344 345 while (n && (n != &pci_devices)) { 346 dev = pci_dev_g(n); 347 if ((vendor == PCI_ANY_ID || dev->vendor == vendor) && 348 (device == PCI_ANY_ID || dev->device == device)) 349 goto exit; 350 n = n->prev; 351 } 352 dev = NULL; 353 exit: 354 dev = pci_dev_get(dev); 355 up_read(&pci_bus_sem); 356 pci_dev_put(from); 357 return dev; 358 } 359 360 /** 361 * pci_get_class - begin or continue searching for a PCI device by class 362 * @class: search for a PCI device with this class designation 363 * @from: Previous PCI device found in search, or %NULL for new search. 364 * 365 * Iterates through the list of known PCI devices. If a PCI device is 366 * found with a matching @class, the reference count to the device is 367 * incremented and a pointer to its device structure is returned. 368 * Otherwise, %NULL is returned. 369 * A new search is initiated by passing %NULL as the @from argument. 370 * Otherwise if @from is not %NULL, searches continue from next device 371 * on the global list. The reference count for @from is always decremented 372 * if it is not %NULL. 373 */ 374 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) 375 { 376 struct list_head *n; 377 struct pci_dev *dev; 378 379 WARN_ON(in_interrupt()); 380 down_read(&pci_bus_sem); 381 n = from ? from->global_list.next : pci_devices.next; 382 383 while (n && (n != &pci_devices)) { 384 dev = pci_dev_g(n); 385 if (dev->class == class) 386 goto exit; 387 n = n->next; 388 } 389 dev = NULL; 390 exit: 391 dev = pci_dev_get(dev); 392 up_read(&pci_bus_sem); 393 pci_dev_put(from); 394 return dev; 395 } 396 397 const struct pci_device_id *pci_find_present(const struct pci_device_id *ids) 398 { 399 struct pci_dev *dev; 400 const struct pci_device_id *found = NULL; 401 402 WARN_ON(in_interrupt()); 403 down_read(&pci_bus_sem); 404 while (ids->vendor || ids->subvendor || ids->class_mask) { 405 list_for_each_entry(dev, &pci_devices, global_list) { 406 if ((found = pci_match_one_device(ids, dev)) != NULL) 407 break; 408 } 409 ids++; 410 } 411 up_read(&pci_bus_sem); 412 return found; 413 } 414 415 /** 416 * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. 417 * @ids: A pointer to a null terminated list of struct pci_device_id structures 418 * that describe the type of PCI device the caller is trying to find. 419 * 420 * Obvious fact: You do not have a reference to any device that might be found 421 * by this function, so if that device is removed from the system right after 422 * this function is finished, the value will be stale. Use this function to 423 * find devices that are usually built into a system, or for a general hint as 424 * to if another device happens to be present at this specific moment in time. 425 */ 426 int pci_dev_present(const struct pci_device_id *ids) 427 { 428 return pci_find_present(ids) == NULL ? 0 : 1; 429 } 430 431 EXPORT_SYMBOL(pci_dev_present); 432 EXPORT_SYMBOL(pci_find_present); 433 434 EXPORT_SYMBOL(pci_find_device); 435 EXPORT_SYMBOL(pci_find_slot); 436 /* For boot time work */ 437 EXPORT_SYMBOL(pci_find_bus); 438 EXPORT_SYMBOL(pci_find_next_bus); 439 /* For everyone */ 440 EXPORT_SYMBOL(pci_get_device); 441 EXPORT_SYMBOL(pci_get_device_reverse); 442 EXPORT_SYMBOL(pci_get_subsys); 443 EXPORT_SYMBOL(pci_get_slot); 444 EXPORT_SYMBOL(pci_get_bus_and_slot); 445 EXPORT_SYMBOL(pci_get_class); 446