bus.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * drivers/pci/bus.c
  3. *
  4. * From setup-res.c, by:
  5. * Dave Rusling (david.rusling@reo.mts.dec.com)
  6. * David Mosberger (davidm@cs.arizona.edu)
  7. * David Miller (davem@redhat.com)
  8. * Ivan Kokshaysky (ink@jurassic.park.msu.ru)
  9. */
  10. #include <linux/module.h>
  11. #include <linux/kernel.h>
  12. #include <linux/pci.h>
  13. #include <linux/errno.h>
  14. #include <linux/ioport.h>
  15. #include <linux/proc_fs.h>
  16. #include <linux/init.h>
  17. #include <linux/slab.h>
  18. #include "pci.h"
  19. void pci_bus_add_resource(struct pci_bus *bus, struct resource *res,
  20. unsigned int flags)
  21. {
  22. struct pci_bus_resource *bus_res;
  23. bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
  24. if (!bus_res) {
  25. dev_err(&bus->dev, "can't add %pR resource\n", res);
  26. return;
  27. }
  28. bus_res->res = res;
  29. bus_res->flags = flags;
  30. list_add_tail(&bus_res->list, &bus->resources);
  31. }
  32. struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n)
  33. {
  34. struct pci_bus_resource *bus_res;
  35. if (n < PCI_BRIDGE_RESOURCE_NUM)
  36. return bus->resource[n];
  37. n -= PCI_BRIDGE_RESOURCE_NUM;
  38. list_for_each_entry(bus_res, &bus->resources, list) {
  39. if (n-- == 0)
  40. return bus_res->res;
  41. }
  42. return NULL;
  43. }
  44. EXPORT_SYMBOL_GPL(pci_bus_resource_n);
  45. void pci_bus_remove_resources(struct pci_bus *bus)
  46. {
  47. struct pci_bus_resource *bus_res, *tmp;
  48. int i;
  49. for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
  50. bus->resource[i] = NULL;
  51. list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
  52. list_del(&bus_res->list);
  53. kfree(bus_res);
  54. }
  55. }
  56. /**
  57. * pci_bus_alloc_resource - allocate a resource from a parent bus
  58. * @bus: PCI bus
  59. * @res: resource to allocate
  60. * @size: size of resource to allocate
  61. * @align: alignment of resource to allocate
  62. * @min: minimum /proc/iomem address to allocate
  63. * @type_mask: IORESOURCE_* type flags
  64. * @alignf: resource alignment function
  65. * @alignf_data: data argument for resource alignment function
  66. *
  67. * Given the PCI bus a device resides on, the size, minimum address,
  68. * alignment and type, try to find an acceptable resource allocation
  69. * for a specific device resource.
  70. */
  71. int
  72. pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
  73. resource_size_t size, resource_size_t align,
  74. resource_size_t min, unsigned int type_mask,
  75. resource_size_t (*alignf)(void *,
  76. const struct resource *,
  77. resource_size_t,
  78. resource_size_t),
  79. void *alignf_data)
  80. {
  81. int i, ret = -ENOMEM;
  82. struct resource *r;
  83. resource_size_t max = -1;
  84. type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
  85. /* don't allocate too high if the pref mem doesn't support 64bit*/
  86. if (!(res->flags & IORESOURCE_MEM_64))
  87. max = PCIBIOS_MAX_MEM_32;
  88. pci_bus_for_each_resource(bus, r, i) {
  89. if (!r)
  90. continue;
  91. /* type_mask must match */
  92. if ((res->flags ^ r->flags) & type_mask)
  93. continue;
  94. /* We cannot allocate a non-prefetching resource
  95. from a pre-fetching area */
  96. if ((r->flags & IORESOURCE_PREFETCH) &&
  97. !(res->flags & IORESOURCE_PREFETCH))
  98. continue;
  99. /* Ok, try it out.. */
  100. ret = allocate_resource(r, res, size,
  101. r->start ? : min,
  102. max, align,
  103. alignf, alignf_data);
  104. if (ret == 0)
  105. break;
  106. }
  107. return ret;
  108. }
  109. /**
  110. * pci_bus_add_device - add a single device
  111. * @dev: device to add
  112. *
  113. * This adds a single pci device to the global
  114. * device list and adds sysfs and procfs entries
  115. */
  116. int pci_bus_add_device(struct pci_dev *dev)
  117. {
  118. int retval;
  119. retval = device_add(&dev->dev);
  120. if (retval)
  121. return retval;
  122. dev->is_added = 1;
  123. pci_proc_attach_device(dev);
  124. pci_create_sysfs_dev_files(dev);
  125. return 0;
  126. }
  127. /**
  128. * pci_bus_add_child - add a child bus
  129. * @bus: bus to add
  130. *
  131. * This adds sysfs entries for a single bus
  132. */
  133. int pci_bus_add_child(struct pci_bus *bus)
  134. {
  135. int retval;
  136. if (bus->bridge)
  137. bus->dev.parent = bus->bridge;
  138. retval = device_register(&bus->dev);
  139. if (retval)
  140. return retval;
  141. bus->is_added = 1;
  142. /* Create legacy_io and legacy_mem files for this bus */
  143. pci_create_legacy_files(bus);
  144. return retval;
  145. }
  146. /**
  147. * pci_bus_add_devices - insert newly discovered PCI devices
  148. * @bus: bus to check for new devices
  149. *
  150. * Add newly discovered PCI devices (which are on the bus->devices
  151. * list) to the global PCI device list, add the sysfs and procfs
  152. * entries. Where a bridge is found, add the discovered bus to
  153. * the parents list of child buses, and recurse (breadth-first
  154. * to be compatible with 2.4)
  155. *
  156. * Call hotplug for each new devices.
  157. */
  158. void pci_bus_add_devices(const struct pci_bus *bus)
  159. {
  160. struct pci_dev *dev;
  161. struct pci_bus *child;
  162. int retval;
  163. list_for_each_entry(dev, &bus->devices, bus_list) {
  164. /* Skip already-added devices */
  165. if (dev->is_added)
  166. continue;
  167. retval = pci_bus_add_device(dev);
  168. if (retval)
  169. dev_err(&dev->dev, "Error adding device, continuing\n");
  170. }
  171. list_for_each_entry(dev, &bus->devices, bus_list) {
  172. BUG_ON(!dev->is_added);
  173. child = dev->subordinate;
  174. /*
  175. * If there is an unattached subordinate bus, attach
  176. * it and then scan for unattached PCI devices.
  177. */
  178. if (!child)
  179. continue;
  180. if (list_empty(&child->node)) {
  181. down_write(&pci_bus_sem);
  182. list_add_tail(&child->node, &dev->bus->children);
  183. up_write(&pci_bus_sem);
  184. }
  185. pci_bus_add_devices(child);
  186. /*
  187. * register the bus with sysfs as the parent is now
  188. * properly registered.
  189. */
  190. if (child->is_added)
  191. continue;
  192. retval = pci_bus_add_child(child);
  193. if (retval)
  194. dev_err(&dev->dev, "Error adding bus, continuing\n");
  195. }
  196. }
  197. void pci_enable_bridges(struct pci_bus *bus)
  198. {
  199. struct pci_dev *dev;
  200. int retval;
  201. list_for_each_entry(dev, &bus->devices, bus_list) {
  202. if (dev->subordinate) {
  203. if (!pci_is_enabled(dev)) {
  204. retval = pci_enable_device(dev);
  205. if (retval)
  206. dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", retval);
  207. pci_set_master(dev);
  208. }
  209. pci_enable_bridges(dev->subordinate);
  210. }
  211. }
  212. }
  213. /** pci_walk_bus - walk devices on/under bus, calling callback.
  214. * @top bus whose devices should be walked
  215. * @cb callback to be called for each device found
  216. * @userdata arbitrary pointer to be passed to callback.
  217. *
  218. * Walk the given bus, including any bridged devices
  219. * on buses under this bus. Call the provided callback
  220. * on each device found.
  221. *
  222. * We check the return of @cb each time. If it returns anything
  223. * other than 0, we break out.
  224. *
  225. */
  226. void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
  227. void *userdata)
  228. {
  229. struct pci_dev *dev;
  230. struct pci_bus *bus;
  231. struct list_head *next;
  232. int retval;
  233. bus = top;
  234. down_read(&pci_bus_sem);
  235. next = top->devices.next;
  236. for (;;) {
  237. if (next == &bus->devices) {
  238. /* end of this bus, go up or finish */
  239. if (bus == top)
  240. break;
  241. next = bus->self->bus_list.next;
  242. bus = bus->self->bus;
  243. continue;
  244. }
  245. dev = list_entry(next, struct pci_dev, bus_list);
  246. if (dev->subordinate) {
  247. /* this is a pci-pci bridge, do its devices next */
  248. next = dev->subordinate->devices.next;
  249. bus = dev->subordinate;
  250. } else
  251. next = dev->bus_list.next;
  252. /* Run device routines with the device locked */
  253. device_lock(&dev->dev);
  254. retval = cb(dev, userdata);
  255. device_unlock(&dev->dev);
  256. if (retval)
  257. break;
  258. }
  259. up_read(&pci_bus_sem);
  260. }
  261. EXPORT_SYMBOL_GPL(pci_walk_bus);
  262. EXPORT_SYMBOL(pci_bus_alloc_resource);
  263. EXPORT_SYMBOL_GPL(pci_bus_add_device);
  264. EXPORT_SYMBOL(pci_bus_add_devices);
  265. EXPORT_SYMBOL(pci_enable_bridges);