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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * pci.c - Low-Level PCI Access in IA-64
  3.  *
  4.  * Derived from bios32.c of i386 tree.
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/types.h>
  8. #include <linux/kernel.h>
  9. #include <linux/pci.h>
  10. #include <linux/init.h>
  11. #include <linux/ioport.h>
  12. #include <linux/slab.h>
  13. #include <linux/smp_lock.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/acpi.h>
  16. #include <asm/machvec.h>
  17. #include <asm/page.h>
  18. #include <asm/segment.h>
  19. #include <asm/system.h>
  20. #include <asm/io.h>
  21. #include <asm/sal.h>
  22. #ifdef CONFIG_SMP
  23. # include <asm/smp.h>
  24. #endif
  25. #include <asm/irq.h>
  26. #undef DEBUG
  27. #define DEBUG
  28. #ifdef DEBUG
  29. #define DBG(x...) printk(x)
  30. #else
  31. #define DBG(x...)
  32. #endif
  33. #ifdef CONFIG_IA64_MCA
  34. extern void ia64_mca_check_errors( void );
  35. #endif
  36. struct pci_fixup pcibios_fixups[1];
  37. struct pci_ops *pci_root_ops;
  38. int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
  39. int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
  40. /*
  41.  * Low-level SAL-based PCI configuration access functions. Note that SAL
  42.  * calls are already serialized (via sal_lock), so we don't need another
  43.  * synchronization mechanism here.
  44.  */
  45. #define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) 
  46. ((u64)(seg << 24) | (u64)(bus << 16) | 
  47.  (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
  48. static int
  49. pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
  50. {
  51. int result = 0;
  52. u64 data = 0;
  53. if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
  54. return -EINVAL;
  55. result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
  56. *value = (u32) data;
  57. return result;
  58. }
  59. static int
  60. pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
  61. {
  62. if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
  63. return -EINVAL;
  64. return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
  65. }
  66. static int
  67. pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
  68. {
  69. int result = 0;
  70. u32 data = 0;
  71. if (!value)
  72. return -EINVAL;
  73. result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  74.       PCI_FUNC(dev->devfn), where, 1, &data);
  75. *value = (u8) data;
  76. return result;
  77. }
  78. static int
  79. pci_sal_read_config_word (struct pci_dev *dev, int where, u16 *value)
  80. {
  81. int result = 0;
  82. u32 data = 0;
  83. if (!value)
  84. return -EINVAL;
  85. result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  86.       PCI_FUNC(dev->devfn), where, 2, &data);
  87. *value = (u16) data;
  88. return result;
  89. }
  90. static int
  91. pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
  92. {
  93. if (!value)
  94. return -EINVAL;
  95. return pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  96.     PCI_FUNC(dev->devfn), where, 4, value);
  97. }
  98. static int
  99. pci_sal_write_config_byte (struct pci_dev *dev, int where, u8 value)
  100. {
  101. return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  102.      PCI_FUNC(dev->devfn), where, 1, value);
  103. }
  104. static int
  105. pci_sal_write_config_word (struct pci_dev *dev, int where, u16 value)
  106. {
  107. return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  108.      PCI_FUNC(dev->devfn), where, 2, value);
  109. }
  110. static int
  111. pci_sal_write_config_dword (struct pci_dev *dev, int where, u32 value)
  112. {
  113. return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
  114.      PCI_FUNC(dev->devfn), where, 4, value);
  115. }
  116. struct pci_ops pci_sal_ops = {
  117. pci_sal_read_config_byte,
  118. pci_sal_read_config_word,
  119. pci_sal_read_config_dword,
  120. pci_sal_write_config_byte,
  121. pci_sal_write_config_word,
  122. pci_sal_write_config_dword
  123. };
  124. /*
  125.  * Initialization. Uses the SAL interface
  126.  */
  127. static struct pci_controller *
  128. alloc_pci_controller(int seg)
  129. {
  130. struct pci_controller *controller;
  131. controller = kmalloc(sizeof(*controller), GFP_KERNEL);
  132. if (!controller)
  133. return NULL;
  134. memset(controller, 0, sizeof(*controller));
  135. controller->segment = seg;
  136. return controller;
  137. }
  138. static struct pci_bus *
  139. scan_root_bus(int bus, struct pci_ops *ops, void *sysdata)
  140. {
  141. struct pci_bus *b;
  142. /*
  143.  * We know this is a new root bus we haven't seen before, so
  144.  * scan it, even if we've seen the same bus number in a different
  145.  * segment.
  146.  */
  147. b = kmalloc(sizeof(*b), GFP_KERNEL);
  148. if (!b)
  149. return NULL;
  150. memset(b, 0, sizeof(*b));
  151. INIT_LIST_HEAD(&b->children);
  152. INIT_LIST_HEAD(&b->devices);
  153. list_add_tail(&b->node, &pci_root_buses);
  154. b->number = b->secondary = bus;
  155. b->resource[0] = &ioport_resource;
  156. b->resource[1] = &iomem_resource;
  157. b->sysdata = sysdata;
  158. b->ops = ops;
  159. b->subordinate = pci_do_scan_bus(b);
  160. return b;
  161. }
  162. struct pci_bus *
  163. pcibios_scan_root(void *handle, int seg, int bus)
  164. {
  165. struct pci_controller *controller;
  166. u64 base, size, offset;
  167. printk("PCI: Probing PCI hardware on bus (%02x:%02x)n", seg, bus);
  168. controller = alloc_pci_controller(seg);
  169. if (!controller)
  170. return NULL;
  171. controller->acpi_handle = handle;
  172. acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
  173. controller->mem_offset = offset;
  174. return scan_root_bus(bus, pci_root_ops, controller);
  175. }
  176. void __init
  177. pcibios_config_init (void)
  178. {
  179. if (pci_root_ops)
  180. return;
  181. printk("PCI: Using SAL to access configuration spacen");
  182. pci_root_ops = &pci_sal_ops;
  183. pci_config_read = pci_sal_read;
  184. pci_config_write = pci_sal_write;
  185. return;
  186. }
  187. void __init
  188. pcibios_init (void)
  189. {
  190. # define PCI_BUSES_TO_SCAN 255
  191. int i = 0;
  192. struct pci_controller *controller;
  193. #ifdef CONFIG_IA64_MCA
  194. ia64_mca_check_errors();    /* For post-failure MCA error logging */
  195. #endif
  196. pcibios_config_init();
  197. platform_pci_fixup(0); /* phase 0 fixups (before buses scanned) */
  198. printk("PCI: Probing PCI hardwaren");
  199. controller = alloc_pci_controller(0);
  200. if (controller)
  201. for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
  202. pci_scan_bus(i, pci_root_ops, controller);
  203. platform_pci_fixup(1); /* phase 1 fixups (after buses scanned) */
  204. return;
  205. }
  206. static void __init
  207. pcibios_fixup_resource(struct resource *res, u64 offset)
  208. {
  209. res->start += offset;
  210. res->end += offset;
  211. }
  212. void __init
  213. pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
  214. {
  215. int i;
  216. for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  217. if (!dev->resource[i].start)
  218. continue;
  219. if (dev->resource[i].flags & IORESOURCE_MEM)
  220. pcibios_fixup_resource(&dev->resource[i],
  221. PCI_CONTROLLER(dev)->mem_offset);
  222. }
  223. }
  224. /*
  225.  *  Called after each bus is probed, but before its children
  226.  *  are examined.
  227.  */
  228. void __init
  229. pcibios_fixup_bus (struct pci_bus *b)
  230. {
  231. struct list_head *ln;
  232. for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
  233. pcibios_fixup_device_resources(pci_dev_b(ln), b);
  234. }
  235. void __init
  236. pcibios_update_resource (struct pci_dev *dev, struct resource *root,
  237.  struct resource *res, int resource)
  238. {
  239. unsigned long where, size;
  240. u32 reg;
  241. where = PCI_BASE_ADDRESS_0 + (resource * 4);
  242. size = res->end - res->start;
  243. pci_read_config_dword(dev, where, &reg);
  244. reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
  245. pci_write_config_dword(dev, where, reg);
  246. /* ??? FIXME -- record old value for shutdown.  */
  247. }
  248. void __init
  249. pcibios_update_irq (struct pci_dev *dev, int irq)
  250. {
  251. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  252. /* ??? FIXME -- record old value for shutdown.  */
  253. }
  254. void __init
  255. pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
  256. {
  257. ranges->io_start -= bus->resource[0]->start;
  258. ranges->io_end -= bus->resource[0]->start;
  259. ranges->mem_start -= bus->resource[1]->start;
  260. ranges->mem_end -= bus->resource[1]->start;
  261. }
  262. int
  263. pcibios_enable_device (struct pci_dev *dev)
  264. {
  265. u16 cmd, old_cmd;
  266. int idx;
  267. struct resource *r;
  268. if (!dev)
  269. return -EINVAL;
  270.   platform_pci_enable_device(dev);
  271. pci_read_config_word(dev, PCI_COMMAND, &cmd);
  272. old_cmd = cmd;
  273. for (idx=0; idx<6; idx++) {
  274. r = &dev->resource[idx];
  275. if (!r->start && r->end) {
  276. printk(KERN_ERR
  277.        "PCI: Device %s not available because of resource collisionsn",
  278.        dev->slot_name);
  279. return -EINVAL;
  280. }
  281. if (r->flags & IORESOURCE_IO)
  282. cmd |= PCI_COMMAND_IO;
  283. if (r->flags & IORESOURCE_MEM)
  284. cmd |= PCI_COMMAND_MEMORY;
  285. }
  286. if (dev->resource[PCI_ROM_RESOURCE].start)
  287. cmd |= PCI_COMMAND_MEMORY;
  288. if (cmd != old_cmd) {
  289. printk("PCI: Enabling device %s (%04x -> %04x)n", dev->slot_name, old_cmd, cmd);
  290. pci_write_config_word(dev, PCI_COMMAND, cmd);
  291. }
  292. printk(KERN_INFO "PCI: Found IRQ %d for device %sn", dev->irq, dev->slot_name);
  293. return 0;
  294. }
  295. void
  296. pcibios_align_resource (void *data, struct resource *res,
  297.         unsigned long size, unsigned long align)
  298. {
  299. }
  300. /*
  301.  * PCI BIOS setup, always defaults to SAL interface
  302.  */
  303. char * __init
  304. pcibios_setup (char *str)
  305. {
  306. return NULL;
  307. }
  308. int
  309. pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
  310.      enum pci_mmap_state mmap_state, int write_combine)
  311. {
  312. /*
  313.  * I/O space cannot be accessed via normal processor loads and stores on this
  314.  * platform.
  315.  */
  316. if (mmap_state == pci_mmap_io)
  317. /*
  318.  * XXX we could relax this for I/O spaces for which ACPI indicates that
  319.  * the space is 1-to-1 mapped.  But at the moment, we don't support
  320.  * multiple PCI address spaces and the legacy I/O space is not 1-to-1
  321.  * mapped, so this is moot.
  322.  */
  323. return -EINVAL;
  324. /*
  325.  * Leave vm_pgoff as-is, the PCI space address is the physical address on this
  326.  * platform.
  327.  */
  328. vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
  329. if (write_combine)
  330. vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  331. else
  332. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  333. if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
  334.      vma->vm_end - vma->vm_start,
  335.      vma->vm_page_prot))
  336. return -EAGAIN;
  337. return 0;
  338. }