common.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include <linux/pci.h>
  2. #include <linux/interrupt.h>
  3. #include <linux/timer.h>
  4. #include <linux/kernel.h>
  5. /*
  6. * These functions are used early on before PCI scanning is done
  7. * and all of the pci_dev and pci_bus structures have been created.
  8. */
  9. static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
  10. int top_bus, int busnr, int devfn)
  11. {
  12. static struct pci_dev dev;
  13. static struct pci_bus bus;
  14. dev.bus = &bus;
  15. dev.sysdata = hose;
  16. dev.devfn = devfn;
  17. bus.number = busnr;
  18. bus.sysdata = hose;
  19. bus.ops = hose->pci_ops;
  20. if(busnr != top_bus)
  21. /* Fake a parent bus structure. */
  22. bus.parent = &bus;
  23. else
  24. bus.parent = NULL;
  25. return &dev;
  26. }
  27. #define EARLY_PCI_OP(rw, size, type) \
  28. int __init early_##rw##_config_##size(struct pci_channel *hose, \
  29. int top_bus, int bus, int devfn, int offset, type value) \
  30. { \
  31. return pci_##rw##_config_##size( \
  32. fake_pci_dev(hose, top_bus, bus, devfn), \
  33. offset, value); \
  34. }
  35. EARLY_PCI_OP(read, byte, u8 *)
  36. EARLY_PCI_OP(read, word, u16 *)
  37. EARLY_PCI_OP(read, dword, u32 *)
  38. EARLY_PCI_OP(write, byte, u8)
  39. EARLY_PCI_OP(write, word, u16)
  40. EARLY_PCI_OP(write, dword, u32)
  41. int __init pci_is_66mhz_capable(struct pci_channel *hose,
  42. int top_bus, int current_bus)
  43. {
  44. u32 pci_devfn;
  45. unsigned short vid;
  46. int cap66 = -1;
  47. u16 stat;
  48. printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
  49. for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
  50. if (PCI_FUNC(pci_devfn))
  51. continue;
  52. if (early_read_config_word(hose, top_bus, current_bus,
  53. pci_devfn, PCI_VENDOR_ID, &vid) !=
  54. PCIBIOS_SUCCESSFUL)
  55. continue;
  56. if (vid == 0xffff)
  57. continue;
  58. /* check 66MHz capability */
  59. if (cap66 < 0)
  60. cap66 = 1;
  61. if (cap66) {
  62. early_read_config_word(hose, top_bus, current_bus,
  63. pci_devfn, PCI_STATUS, &stat);
  64. if (!(stat & PCI_STATUS_66MHZ)) {
  65. printk(KERN_DEBUG
  66. "PCI: %02x:%02x not 66MHz capable.\n",
  67. current_bus, pci_devfn);
  68. cap66 = 0;
  69. break;
  70. }
  71. }
  72. }
  73. return cap66 > 0;
  74. }
  75. static void pcibios_enable_err(unsigned long __data)
  76. {
  77. struct pci_channel *hose = (struct pci_channel *)__data;
  78. del_timer(&hose->err_timer);
  79. printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
  80. enable_irq(hose->err_irq);
  81. }
  82. static void pcibios_enable_serr(unsigned long __data)
  83. {
  84. struct pci_channel *hose = (struct pci_channel *)__data;
  85. del_timer(&hose->serr_timer);
  86. printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
  87. enable_irq(hose->serr_irq);
  88. }
  89. void pcibios_enable_timers(struct pci_channel *hose)
  90. {
  91. if (hose->err_irq) {
  92. init_timer(&hose->err_timer);
  93. hose->err_timer.data = (unsigned long)hose;
  94. hose->err_timer.function = pcibios_enable_err;
  95. }
  96. if (hose->serr_irq) {
  97. init_timer(&hose->serr_timer);
  98. hose->serr_timer.data = (unsigned long)hose;
  99. hose->serr_timer.function = pcibios_enable_serr;
  100. }
  101. }
  102. /*
  103. * A simple handler for the regular PCI status errors, called from IRQ
  104. * context.
  105. */
  106. unsigned int pcibios_handle_status_errors(unsigned long addr,
  107. unsigned int status,
  108. struct pci_channel *hose)
  109. {
  110. unsigned int cmd = 0;
  111. if (status & PCI_STATUS_REC_MASTER_ABORT) {
  112. printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr);
  113. cmd |= PCI_STATUS_REC_MASTER_ABORT;
  114. }
  115. if (status & PCI_STATUS_REC_TARGET_ABORT) {
  116. printk(KERN_DEBUG "PCI: target abort: ");
  117. pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
  118. PCI_STATUS_SIG_TARGET_ABORT |
  119. PCI_STATUS_REC_MASTER_ABORT, 1);
  120. printk("\n");
  121. cmd |= PCI_STATUS_REC_TARGET_ABORT;
  122. }
  123. if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) {
  124. printk(KERN_DEBUG "PCI: parity error detected: ");
  125. pcibios_report_status(PCI_STATUS_PARITY |
  126. PCI_STATUS_DETECTED_PARITY, 1);
  127. printk("\n");
  128. cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
  129. /* Now back off of the IRQ for awhile */
  130. if (hose->err_irq) {
  131. disable_irq_nosync(hose->err_irq);
  132. hose->err_timer.expires = jiffies + HZ;
  133. add_timer(&hose->err_timer);
  134. }
  135. }
  136. return cmd;
  137. }