search.c 15 KB

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