setup-res.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:6k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/pci/setup-res.c
  3.  *
  4.  * Extruded from code written by
  5.  *      Dave Rusling (david.rusling@reo.mts.dec.com)
  6.  *      David Mosberger (davidm@cs.arizona.edu)
  7.  * David Miller (davem@redhat.com)
  8.  *
  9.  * Support routines for initializing a PCI subsystem.
  10.  */
  11. /* fixed for multiple pci buses, 1999 Andrea Arcangeli <andrea@suse.de> */
  12. /*
  13.  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
  14.  *      Resource sorting
  15.  */
  16. #include <linux/init.h>
  17. #include <linux/kernel.h>
  18. #include <linux/pci.h>
  19. #include <linux/errno.h>
  20. #include <linux/ioport.h>
  21. #include <linux/cache.h>
  22. #include <linux/slab.h>
  23. #define DEBUG_CONFIG 0
  24. #if DEBUG_CONFIG
  25. # define DBGC(args)     printk args
  26. #else
  27. # define DBGC(args)
  28. #endif
  29. int __init
  30. pci_claim_resource(struct pci_dev *dev, int resource)
  31. {
  32.         struct resource *res = &dev->resource[resource];
  33. struct resource *root = pci_find_parent_resource(dev, res);
  34. int err;
  35. err = -EINVAL;
  36. if (root != NULL) {
  37. err = request_resource(root, res);
  38. if (err) {
  39. printk(KERN_ERR "PCI: Address space collision on "
  40.        "region %d of device %s [%lx:%lx]n",
  41.        resource, dev->name, res->start, res->end);
  42. }
  43. } else {
  44. printk(KERN_ERR "PCI: No parent found for region %d "
  45.        "of device %sn", resource, dev->name);
  46. }
  47. return err;
  48. }
  49. /*
  50.  * Given the PCI bus a device resides on, try to
  51.  * find an acceptable resource allocation for a
  52.  * specific device resource..
  53.  */
  54. static int pci_assign_bus_resource(const struct pci_bus *bus,
  55. struct pci_dev *dev,
  56. struct resource *res,
  57. unsigned long size,
  58. unsigned long min,
  59. unsigned int type_mask,
  60. int resno)
  61. {
  62. unsigned long align;
  63. int i;
  64. type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
  65. for (i = 0 ; i < 4; i++) {
  66. struct resource *r = bus->resource[i];
  67. if (!r)
  68. continue;
  69. /* type_mask must match */
  70. if ((res->flags ^ r->flags) & type_mask)
  71. continue;
  72. /* We cannot allocate a non-prefetching resource
  73.    from a pre-fetching area */
  74. if ((r->flags & IORESOURCE_PREFETCH) &&
  75.     !(res->flags & IORESOURCE_PREFETCH))
  76. continue;
  77. /* The bridge resources are special, as their
  78.    size != alignment. Sizing routines return
  79.    required alignment in the "start" field. */
  80. align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;
  81. /* Ok, try it out.. */
  82. if (allocate_resource(r, res, size, min, -1, align,
  83.       pcibios_align_resource, dev) < 0)
  84. continue;
  85. /* Update PCI config space.  */
  86. pcibios_update_resource(dev, r, res, resno);
  87. return 0;
  88. }
  89. return -EBUSY;
  90. }
  91. int 
  92. pci_assign_resource(struct pci_dev *dev, int i)
  93. {
  94. const struct pci_bus *bus = dev->bus;
  95. struct resource *res = dev->resource + i;
  96. unsigned long size, min;
  97. size = res->end - res->start + 1;
  98. min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
  99. /* First, try exact prefetching match.. */
  100. if (pci_assign_bus_resource(bus, dev, res, size, min, IORESOURCE_PREFETCH, i) < 0) {
  101. /*
  102.  * That failed.
  103.  *
  104.  * But a prefetching area can handle a non-prefetching
  105.  * window (it will just not perform as well).
  106.  */
  107. if (!(res->flags & IORESOURCE_PREFETCH) || pci_assign_bus_resource(bus, dev, res, size, min, 0, i) < 0) {
  108. printk(KERN_ERR "PCI: Failed to allocate resource %d(%lx-%lx) for %sn",
  109.        i, res->start, res->end, dev->slot_name);
  110. return -EBUSY;
  111. }
  112. }
  113. DBGC((KERN_ERR "  got res[%lx:%lx] for resource %d of %sn", res->start,
  114. res->end, i, dev->name));
  115. return 0;
  116. }
  117. /* Sort resources by alignment */
  118. void __init
  119. pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
  120. {
  121. int i;
  122. for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  123. struct resource *r;
  124. struct resource_list *list, *tmp;
  125. unsigned long r_align;
  126. r = &dev->resource[i];
  127. r_align = r->end - r->start;
  128. if (!(r->flags) || r->parent)
  129. continue;
  130. if (!r_align) {
  131. printk(KERN_WARNING "PCI: Ignore bogus resource %d "
  132.     "[%lx:%lx] of %sn",
  133.     i, r->start, r->end, dev->name);
  134. continue;
  135. }
  136. r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
  137. for (list = head; ; list = list->next) {
  138. unsigned long align = 0;
  139. struct resource_list *ln = list->next;
  140. int idx;
  141. if (ln) {
  142. idx = ln->res - &ln->dev->resource[0];
  143. align = (idx < PCI_BRIDGE_RESOURCES) ?
  144. ln->res->end - ln->res->start + 1 :
  145. ln->res->start;
  146. }
  147. if (r_align > align) {
  148. tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
  149. if (!tmp)
  150. panic("pdev_sort_resources(): "
  151.       "kmalloc() failed!n");
  152. tmp->next = ln;
  153. tmp->res = r;
  154. tmp->dev = dev;
  155. list->next = tmp;
  156. break;
  157. }
  158. }
  159. }
  160. }
  161. void __init
  162. pdev_enable_device(struct pci_dev *dev)
  163. {
  164. u32 reg;
  165. u16 cmd;
  166. int i;
  167. DBGC((KERN_ERR "PCI enable device: (%s)n", dev->name));
  168. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  169. for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  170. struct resource *res = &dev->resource[i];
  171. if (res->flags & IORESOURCE_IO)
  172. cmd |= PCI_COMMAND_IO;
  173. else if (res->flags & IORESOURCE_MEM)
  174. cmd |= PCI_COMMAND_MEMORY;
  175. }
  176. /* Special case, disable the ROM.  Several devices act funny
  177.    (ie. do not respond to memory space writes) when it is left
  178.    enabled.  A good example are QlogicISP adapters.  */
  179. if (dev->rom_base_reg) {
  180. pci_read_config_dword(dev, dev->rom_base_reg, &reg);
  181. reg &= ~PCI_ROM_ADDRESS_ENABLE;
  182. pci_write_config_dword(dev, dev->rom_base_reg, reg);
  183. dev->resource[PCI_ROM_RESOURCE].flags &= ~PCI_ROM_ADDRESS_ENABLE;
  184. }
  185. /* All of these (may) have I/O scattered all around and may not
  186.    use I/O base address registers at all.  So we just have to
  187.    always enable IO to these devices.  */
  188. if ((dev->class >> 8) == PCI_CLASS_NOT_DEFINED
  189.     || (dev->class >> 8) == PCI_CLASS_NOT_DEFINED_VGA
  190.     || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE
  191.     || (dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
  192. cmd |= PCI_COMMAND_IO;
  193. }
  194. /* ??? Always turn on bus mastering.  If the device doesn't support
  195.    it, the bit will go into the bucket. */
  196. cmd |= PCI_COMMAND_MASTER;
  197. /* Set the cache line and default latency (32).  */
  198. pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
  199. (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
  200. /* Enable the appropriate bits in the PCI command register.  */
  201. pci_write_config_word(dev, PCI_COMMAND, cmd);
  202. DBGC((KERN_ERR "  cmd reg 0x%xn", cmd));
  203. }