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