direct.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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 ((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 ((bus > 255) || (devfn > 255) || (reg > 255)) {
  74. *value = -1;
  75. return -EINVAL;
  76. }
  77. dev = PCI_SLOT(devfn);
  78. fn = PCI_FUNC(devfn);
  79. if (dev & 0x10)
  80. return PCIBIOS_DEVICE_NOT_FOUND;
  81. spin_lock_irqsave(&pci_config_lock, flags);
  82. outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  83. outb((u8)bus, 0xCFA);
  84. switch (len) {
  85. case 1:
  86. *value = inb(PCI_CONF2_ADDRESS(dev, reg));
  87. break;
  88. case 2:
  89. *value = inw(PCI_CONF2_ADDRESS(dev, reg));
  90. break;
  91. case 4:
  92. *value = inl(PCI_CONF2_ADDRESS(dev, reg));
  93. break;
  94. }
  95. outb(0, 0xCF8);
  96. spin_unlock_irqrestore(&pci_config_lock, flags);
  97. return 0;
  98. }
  99. static int pci_conf2_write(unsigned int seg, unsigned int bus,
  100. unsigned int devfn, int reg, int len, u32 value)
  101. {
  102. unsigned long flags;
  103. int dev, fn;
  104. if ((bus > 255) || (devfn > 255) || (reg > 255))
  105. return -EINVAL;
  106. dev = PCI_SLOT(devfn);
  107. fn = PCI_FUNC(devfn);
  108. if (dev & 0x10)
  109. return PCIBIOS_DEVICE_NOT_FOUND;
  110. spin_lock_irqsave(&pci_config_lock, flags);
  111. outb((u8)(0xF0 | (fn << 1)), 0xCF8);
  112. outb((u8)bus, 0xCFA);
  113. switch (len) {
  114. case 1:
  115. outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
  116. break;
  117. case 2:
  118. outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
  119. break;
  120. case 4:
  121. outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
  122. break;
  123. }
  124. outb(0, 0xCF8);
  125. spin_unlock_irqrestore(&pci_config_lock, flags);
  126. return 0;
  127. }
  128. #undef PCI_CONF2_ADDRESS
  129. static struct pci_raw_ops pci_direct_conf2 = {
  130. .read = pci_conf2_read,
  131. .write = pci_conf2_write,
  132. };
  133. /*
  134. * Before we decide to use direct hardware access mechanisms, we try to do some
  135. * trivial checks to ensure it at least _seems_ to be working -- we just test
  136. * whether bus 00 contains a host bridge (this is similar to checking
  137. * techniques used in XFree86, but ours should be more reliable since we
  138. * attempt to make use of direct access hints provided by the PCI BIOS).
  139. *
  140. * This should be close to trivial, but it isn't, because there are buggy
  141. * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
  142. */
  143. static int __init pci_sanity_check(struct pci_raw_ops *o)
  144. {
  145. u32 x = 0;
  146. int devfn;
  147. if (pci_probe & PCI_NO_CHECKS)
  148. return 1;
  149. /* Assume Type 1 works for newer systems.
  150. This handles machines that don't have anything on PCI Bus 0. */
  151. if (dmi_get_year(DMI_BIOS_DATE) >= 2001)
  152. return 1;
  153. for (devfn = 0; devfn < 0x100; devfn++) {
  154. if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
  155. continue;
  156. if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
  157. return 1;
  158. if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
  159. continue;
  160. if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
  161. return 1;
  162. }
  163. DBG(KERN_WARNING "PCI: Sanity check failed\n");
  164. return 0;
  165. }
  166. static int __init pci_check_type1(void)
  167. {
  168. unsigned long flags;
  169. unsigned int tmp;
  170. int works = 0;
  171. local_irq_save(flags);
  172. outb(0x01, 0xCFB);
  173. tmp = inl(0xCF8);
  174. outl(0x80000000, 0xCF8);
  175. if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
  176. works = 1;
  177. }
  178. outl(tmp, 0xCF8);
  179. local_irq_restore(flags);
  180. return works;
  181. }
  182. static int __init pci_check_type2(void)
  183. {
  184. unsigned long flags;
  185. int works = 0;
  186. local_irq_save(flags);
  187. outb(0x00, 0xCFB);
  188. outb(0x00, 0xCF8);
  189. outb(0x00, 0xCFA);
  190. if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
  191. pci_sanity_check(&pci_direct_conf2)) {
  192. works = 1;
  193. }
  194. local_irq_restore(flags);
  195. return works;
  196. }
  197. void __init pci_direct_init(void)
  198. {
  199. struct resource *region, *region2;
  200. if ((pci_probe & PCI_PROBE_CONF1) == 0)
  201. goto type2;
  202. region = request_region(0xCF8, 8, "PCI conf1");
  203. if (!region)
  204. goto type2;
  205. if (pci_check_type1()) {
  206. printk(KERN_INFO "PCI: Using configuration type 1\n");
  207. raw_pci_ops = &pci_direct_conf1;
  208. return;
  209. }
  210. release_resource(region);
  211. type2:
  212. if ((pci_probe & PCI_PROBE_CONF2) == 0)
  213. return;
  214. region = request_region(0xCF8, 4, "PCI conf2");
  215. if (!region)
  216. return;
  217. region2 = request_region(0xC000, 0x1000, "PCI conf2");
  218. if (!region2)
  219. goto fail2;
  220. if (pci_check_type2()) {
  221. printk(KERN_INFO "PCI: Using configuration type 2\n");
  222. raw_pci_ops = &pci_direct_conf2;
  223. return;
  224. }
  225. release_resource(region2);
  226. fail2:
  227. release_resource(region);
  228. }