search.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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 bus & 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. * Note: the bus/slot search is limited to PCI domain (segment) 0.
  133. *
  134. * Given a PCI bus and slot/function number, the desired PCI device
  135. * is located in system global list of PCI devices. If the device
  136. * is found, a pointer to its data structure is returned. If no
  137. * device is found, %NULL is returned. The returned device has its
  138. * reference count bumped by one.
  139. */
  140. struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn)
  141. {
  142. struct pci_dev *dev = NULL;
  143. while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
  144. if (pci_domain_nr(dev->bus) == 0 &&
  145. (dev->bus->number == bus && dev->devfn == devfn))
  146. return dev;
  147. }
  148. return NULL;
  149. }
  150. /**
  151. * pci_find_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
  152. * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  153. * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
  154. * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
  155. * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
  156. * @from: Previous PCI device found in search, or %NULL for new search.
  157. *
  158. * Iterates through the list of known PCI devices. If a PCI device is
  159. * found with a matching @vendor, @device, @ss_vendor and @ss_device, a
  160. * pointer to its device structure is returned. Otherwise, %NULL is returned.
  161. * A new search is initiated by passing %NULL as the @from argument.
  162. * Otherwise if @from is not %NULL, searches continue from next device
  163. * on the global list.
  164. *
  165. * NOTE: Do not use this function any more; use pci_get_subsys() instead, as
  166. * the PCI device returned by this function can disappear at any moment in
  167. * time.
  168. */
  169. static struct pci_dev * pci_find_subsys(unsigned int vendor,
  170. unsigned int device,
  171. unsigned int ss_vendor,
  172. unsigned int ss_device,
  173. const struct pci_dev *from)
  174. {
  175. struct list_head *n;
  176. struct pci_dev *dev;
  177. WARN_ON(in_interrupt());
  178. /*
  179. * pci_find_subsys() can be called on the ide_setup() path, super-early
  180. * in boot. But the down_read() will enable local interrupts, which
  181. * can cause some machines to crash. So here we detect and flag that
  182. * situation and bail out early.
  183. */
  184. if (unlikely(no_pci_devices()))
  185. return NULL;
  186. down_read(&pci_bus_sem);
  187. n = from ? from->global_list.next : pci_devices.next;
  188. while (n && (n != &pci_devices)) {
  189. dev = pci_dev_g(n);
  190. if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
  191. (device == PCI_ANY_ID || dev->device == device) &&
  192. (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
  193. (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
  194. goto exit;
  195. n = n->next;
  196. }
  197. dev = NULL;
  198. exit:
  199. up_read(&pci_bus_sem);
  200. return dev;
  201. }
  202. /**
  203. * pci_find_device - begin or continue searching for a PCI device by vendor/device id
  204. * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  205. * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
  206. * @from: Previous PCI device found in search, or %NULL for new search.
  207. *
  208. * Iterates through the list of known PCI devices. If a PCI device is found
  209. * with a matching @vendor and @device, a pointer to its device structure is
  210. * returned. Otherwise, %NULL is returned.
  211. * A new search is initiated by passing %NULL as the @from argument.
  212. * Otherwise if @from is not %NULL, searches continue from next device
  213. * on the global list.
  214. *
  215. * NOTE: Do not use this function any more; use pci_get_device() instead, as
  216. * the PCI device returned by this function can disappear at any moment in
  217. * time.
  218. */
  219. struct pci_dev *
  220. pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
  221. {
  222. return pci_find_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
  223. }
  224. /**
  225. * pci_get_subsys - begin or continue searching for a PCI device by vendor/subvendor/device/subdevice id
  226. * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  227. * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
  228. * @ss_vendor: PCI subsystem vendor id to match, or %PCI_ANY_ID to match all vendor ids
  229. * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids
  230. * @from: Previous PCI device found in search, or %NULL for new search.
  231. *
  232. * Iterates through the list of known PCI devices. If a PCI device is found
  233. * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its
  234. * device structure is returned, and the reference count to the device is
  235. * incremented. Otherwise, %NULL is returned. A new search is initiated by
  236. * passing %NULL as the @from argument. Otherwise if @from is not %NULL,
  237. * searches continue from next device on the global list.
  238. * The reference count for @from is always decremented if it is not %NULL.
  239. */
  240. struct pci_dev *
  241. 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 list_head *n;
  246. struct pci_dev *dev;
  247. WARN_ON(in_interrupt());
  248. /*
  249. * pci_get_subsys() can potentially be called by drivers super-early
  250. * in boot. But the down_read() will enable local interrupts, which
  251. * can cause some machines to crash. So here we detect and flag that
  252. * situation and bail out early.
  253. */
  254. if (unlikely(no_pci_devices()))
  255. return NULL;
  256. down_read(&pci_bus_sem);
  257. n = from ? from->global_list.next : pci_devices.next;
  258. while (n && (n != &pci_devices)) {
  259. dev = pci_dev_g(n);
  260. if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
  261. (device == PCI_ANY_ID || dev->device == device) &&
  262. (ss_vendor == PCI_ANY_ID || dev->subsystem_vendor == ss_vendor) &&
  263. (ss_device == PCI_ANY_ID || dev->subsystem_device == ss_device))
  264. goto exit;
  265. n = n->next;
  266. }
  267. dev = NULL;
  268. exit:
  269. dev = pci_dev_get(dev);
  270. up_read(&pci_bus_sem);
  271. pci_dev_put(from);
  272. return dev;
  273. }
  274. /**
  275. * pci_get_device - begin or continue searching for a PCI device by vendor/device id
  276. * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  277. * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
  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 @vendor and @device, the reference count to the
  282. * device is incremented and a pointer to its device structure is returned.
  283. * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
  284. * as the @from argument. Otherwise if @from is not %NULL, searches continue
  285. * from next device on the global list. The reference count for @from is
  286. * always decremented if it is not %NULL.
  287. */
  288. struct pci_dev *
  289. pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
  290. {
  291. return pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
  292. }
  293. /**
  294. * pci_get_device_reverse - begin or continue searching for a PCI device by vendor/device id
  295. * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
  296. * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
  297. * @from: Previous PCI device found in search, or %NULL for new search.
  298. *
  299. * Iterates through the list of known PCI devices in the reverse order of
  300. * pci_get_device.
  301. * If a PCI device is found with a matching @vendor and @device, the reference
  302. * count to the device is incremented and a pointer to its device structure
  303. * is returned Otherwise, %NULL is returned. A new search is initiated by
  304. * passing %NULL as the @from argument. Otherwise if @from is not %NULL,
  305. * searches continue from next device on the global list. The reference
  306. * count for @from is always decremented if it is not %NULL.
  307. */
  308. struct pci_dev *
  309. pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev *from)
  310. {
  311. struct list_head *n;
  312. struct pci_dev *dev;
  313. WARN_ON(in_interrupt());
  314. down_read(&pci_bus_sem);
  315. n = from ? from->global_list.prev : pci_devices.prev;
  316. while (n && (n != &pci_devices)) {
  317. dev = pci_dev_g(n);
  318. if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
  319. (device == PCI_ANY_ID || dev->device == device))
  320. goto exit;
  321. n = n->prev;
  322. }
  323. dev = NULL;
  324. exit:
  325. dev = pci_dev_get(dev);
  326. up_read(&pci_bus_sem);
  327. pci_dev_put(from);
  328. return dev;
  329. }
  330. /**
  331. * pci_get_class - begin or continue searching for a PCI device by class
  332. * @class: search for a PCI device with this class designation
  333. * @from: Previous PCI device found in search, or %NULL for new search.
  334. *
  335. * Iterates through the list of known PCI devices. If a PCI device is
  336. * found with a matching @class, the reference count to the device is
  337. * incremented and a pointer to its device structure is returned.
  338. * Otherwise, %NULL is returned.
  339. * A new search is initiated by passing %NULL as the @from argument.
  340. * Otherwise if @from is not %NULL, searches continue from next device
  341. * on the global list. The reference count for @from is always decremented
  342. * if it is not %NULL.
  343. */
  344. struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
  345. {
  346. struct list_head *n;
  347. struct pci_dev *dev;
  348. WARN_ON(in_interrupt());
  349. down_read(&pci_bus_sem);
  350. n = from ? from->global_list.next : pci_devices.next;
  351. while (n && (n != &pci_devices)) {
  352. dev = pci_dev_g(n);
  353. if (dev->class == class)
  354. goto exit;
  355. n = n->next;
  356. }
  357. dev = NULL;
  358. exit:
  359. dev = pci_dev_get(dev);
  360. up_read(&pci_bus_sem);
  361. pci_dev_put(from);
  362. return dev;
  363. }
  364. const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
  365. {
  366. struct pci_dev *dev;
  367. const struct pci_device_id *found = NULL;
  368. WARN_ON(in_interrupt());
  369. down_read(&pci_bus_sem);
  370. while (ids->vendor || ids->subvendor || ids->class_mask) {
  371. list_for_each_entry(dev, &pci_devices, global_list) {
  372. if ((found = pci_match_one_device(ids, dev)) != NULL)
  373. goto exit;
  374. }
  375. ids++;
  376. }
  377. exit:
  378. up_read(&pci_bus_sem);
  379. return found;
  380. }
  381. /**
  382. * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
  383. * @ids: A pointer to a null terminated list of struct pci_device_id structures
  384. * that describe the type of PCI device the caller is trying to find.
  385. *
  386. * Obvious fact: You do not have a reference to any device that might be found
  387. * by this function, so if that device is removed from the system right after
  388. * this function is finished, the value will be stale. Use this function to
  389. * find devices that are usually built into a system, or for a general hint as
  390. * to if another device happens to be present at this specific moment in time.
  391. */
  392. int pci_dev_present(const struct pci_device_id *ids)
  393. {
  394. return pci_find_present(ids) == NULL ? 0 : 1;
  395. }
  396. EXPORT_SYMBOL(pci_dev_present);
  397. EXPORT_SYMBOL(pci_find_present);
  398. EXPORT_SYMBOL(pci_find_device);
  399. EXPORT_SYMBOL(pci_find_slot);
  400. /* For boot time work */
  401. EXPORT_SYMBOL(pci_find_bus);
  402. EXPORT_SYMBOL(pci_find_next_bus);
  403. /* For everyone */
  404. EXPORT_SYMBOL(pci_get_device);
  405. EXPORT_SYMBOL(pci_get_device_reverse);
  406. EXPORT_SYMBOL(pci_get_subsys);
  407. EXPORT_SYMBOL(pci_get_slot);
  408. EXPORT_SYMBOL(pci_get_bus_and_slot);
  409. EXPORT_SYMBOL(pci_get_class);