direct.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * direct.c - Low-level direct PCI config space access
  3. */
  4. #include <linux/pci.h>
  5. #include <linux/init.h>
  6. #include <linux/dmi.h>
  7. #include "pci.h"
  8. /*
  9. * Functions for accessing PCI configuration space with type 1 accesses
  10. */
  11. #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
  12. (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
  13. int pci_conf1_read(unsigned int seg, unsigned int bus,
  14. unsigned int devfn, int reg, int len, u32 *value)
  15. {
  16. unsigned long flags;
  17. if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) {
  18. *value = -1;
  19. return -EINVAL;
  20. }
  21. spin_lock_irqsave(&pci_config_lock, flags);
  22. outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  23. switch (len) {
  24. case 1:
  25. *value = inb(0xCFC + (reg & 3));
  26. break;
  27. case 2:
  28. *value = inw(0xCFC + (reg & 2));
  29. break;
  30. case 4:
  31. *value = inl(0xCFC);
  32. break;
  33. }
  34. spin_unlock_irqrestore(&pci_config_lock, flags);
  35. return 0;
  36. }
  37. int pci_conf1_write(unsigned int seg, unsigned int bus,
  38. unsigned int devfn, int reg, int len, u32 value)
  39. {
  40. unsigned long flags;
  41. if ((bus > 255) || (devfn > 255) || (reg > 255))
  42. return -EINVAL;
  43. spin_lock_irqsave(&pci_config_lock, flags);
  44. outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  45. switch (len) {
  46. case 1:
  47. outb((u8)value, 0xCFC + (reg & 3));
  48. break;
  49. case 2:
  50. outw((u16)value, 0xCFC + (reg & 2));
  51. break;
  52. case 4:
  53. outl((u32)value, 0xCFC);
  54. break;
  55. }
  56. spin_unlock_irqrestore(&pci_config_lock, flags);
  57. return 0;
  58. }
  59. #undef PCI_CONF1_ADDRESS
  60. struct pci_raw_ops pci_direct_conf1 = {
  61. .read = pci_conf1_read,
  62. .write = pci_conf1_write,
  63. };
  64. /*
  65. * Functions for accessing PCI configuration space with type 2 accesses
  66. */
  67. #define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg)
  68. static int pci_conf2_read(unsigned int seg, unsigned int bus,
  69. unsigned int devfn, int reg, int len, u32 *value)
  70. {
  71. unsigned long flags;
  72. int dev, fn;
  73. if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
  74. return -EINVAL;
  75. dev = PCI_SLOT(devfn);
  76. fn = PCI_FUNC(devfn);
  77. if (dev & 0x10)
  78. return PCIBIOS_DEVICE_NOT_FOUND;
  79. spin_lock_irqsave(&pci_config_lock, flags);
  80. outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  81. outb((u8)bus, 0xCFA);
  82. switch (len) {
  83. case 1:
  84. *value = inb(PCI_CONF2_ADDRESS(dev, reg));
  85. break;
  86. case 2:
  87. *value = inw(PCI_CONF2_ADDRESS(dev, reg));
  88. break;
  89. case 4:
  90. *value = inl(PCI_CONF2_ADDRESS(dev, reg));
  91. break;
  92. }
  93. outb(0, 0xCF8);
  94. spin_unlock_irqrestore(&pci_config_lock, flags);
  95. return 0;
  96. }
  97. static int pci_conf2_write(unsigned int seg, unsigned int bus,
  98. unsigned int devfn, int reg, int len, u32 value)
  99. {
  100. unsigned long flags;
  101. int dev, fn;
  102. if ((bus > 255) || (devfn > 255) || (reg > 255))
  103. return -EINVAL;
  104. dev = PCI_SLOT(devfn);
  105. fn = PCI_FUNC(devfn);
  106. if (dev & 0x10)
  107. return PCIBIOS_DEVICE_NOT_FOUND;
  108. spin_lock_irqsave(&pci_config_lock, flags);
  109. outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  110. outb((u8)bus, 0xCFA);
  111. switch (len) {
  112. case 1:
  113. outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
  114. break;
  115. case 2:
  116. outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
  117. break;
  118. case 4:
  119. outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
  120. break;
  121. }
  122. outb(0, 0xCF8);
  123. spin_unlock_irqrestore(&pci_config_lock, flags);
  124. return 0;
  125. }
  126. #undef PCI_CONF2_ADDRESS
  127. static struct pci_raw_ops pci_direct_conf2 = {
  128. .read = pci_conf2_read,
  129. .write = pci_conf2_write,
  130. };
  131. /*
  132. * Before we decide to use direct hardware access mechanisms, we try to do some
  133. * trivial checks to ensure it at least _seems_ to be working -- we just test
  134. * whether bus 00 contains a host bridge (this is similar to checking
  135. * techniques used in XFree86, but ours should be more reliable since we
  136. * attempt to make use of direct access hints provided by the PCI BIOS).
  137. *
  138. * This should be close to trivial, but it isn't, because there are buggy
  139. * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
  140. */
  141. static int __init pci_sanity_check(struct pci_raw_ops *o)
  142. {
  143. u32 x = 0;
  144. int devfn;
  145. if (pci_probe & PCI_NO_CHECKS)
  146. return 1;
  147. /* Assume Type 1 works for newer systems.
  148. This handles machines that don't have anything on PCI Bus 0. */
  149. if (dmi_get_year(DMI_BIOS_DATE) >= 2001)
  150. return 1;
  151. for (devfn = 0; devfn < 0x100; devfn++) {
  152. if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
  153. continue;
  154. if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
  155. return 1;
  156. if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
  157. continue;
  158. if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
  159. return 1;
  160. }
  161. DBG(KERN_WARNING "PCI: Sanity check failed\n");
  162. return 0;
  163. }
  164. static int __init pci_check_type1(void)
  165. {
  166. unsigned long flags;
  167. unsigned int tmp;
  168. int works = 0;
  169. local_irq_save(flags);
  170. outb(0x01, 0xCFB);
  171. tmp = inl(0xCF8);
  172. outl(0x80000000, 0xCF8);
  173. if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
  174. works = 1;
  175. }
  176. outl(tmp, 0xCF8);
  177. local_irq_restore(flags);
  178. return works;
  179. }
  180. static int __init pci_check_type2(void)
  181. {
  182. unsigned long flags;
  183. int works = 0;
  184. local_irq_save(flags);
  185. outb(0x00, 0xCFB);
  186. outb(0x00, 0xCF8);
  187. outb(0x00, 0xCFA);
  188. if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
  189. pci_sanity_check(&pci_direct_conf2)) {
  190. works = 1;
  191. }
  192. local_irq_restore(flags);
  193. return works;
  194. }
  195. void __init pci_direct_init(void)
  196. {
  197. struct resource *region, *region2;
  198. if ((pci_probe & PCI_PROBE_CONF1) == 0)
  199. goto type2;
  200. region = request_region(0xCF8, 8, "PCI conf1");
  201. if (!region)
  202. goto type2;
  203. if (pci_check_type1()) {
  204. printk(KERN_INFO "PCI: Using configuration type 1\n");
  205. raw_pci_ops = &pci_direct_conf1;
  206. return;
  207. }
  208. release_resource(region);
  209. type2:
  210. if ((pci_probe & PCI_PROBE_CONF2) == 0)
  211. return;
  212. region = request_region(0xCF8, 4, "PCI conf2");
  213. if (!region)
  214. return;
  215. region2 = request_region(0xC000, 0x1000, "PCI conf2");
  216. if (!region2)
  217. goto fail2;
  218. if (pci_check_type2()) {
  219. printk(KERN_INFO "PCI: Using configuration type 2\n");
  220. raw_pci_ops = &pci_direct_conf2;
  221. return;
  222. }
  223. release_resource(region2);
  224. fail2:
  225. release_resource(region);
  226. }