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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.    * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
  3.    *
  4.    * This module handles PCI interrupt events sent by the iSeries Hypervisor.
  5. */
  6. #include <linux/pci.h>
  7. #include <linux/init.h>
  8. #include <linux/threads.h>
  9. #include <linux/smp.h>
  10. #include <linux/param.h>
  11. #include <linux/string.h>
  12. #include <linux/bootmem.h>
  13. #include <linux/blk.h>
  14. #include <linux/ide.h>
  15. #include <linux/rtc.h>
  16. #include <linux/time.h>
  17. #include <asm/iSeries/HvTypes.h>
  18. #include <asm/iSeries/HvLpEvent.h>
  19. #include <asm/iSeries/HvCallPci.h>
  20. #include <asm/iSeries/XmPciLpEvent.h>
  21. #include <asm/ppcdebug.h>
  22. #include <asm/time.h>
  23. #include <asm/flight_recorder.h>
  24. extern struct flightRecorder* PciFr;
  25. long Pci_Interrupt_Count = 0;
  26. long Pci_Event_Count     = 0;
  27. enum XmPciLpEvent_Subtype {
  28. XmPciLpEvent_BusCreated    = 0, // PHB has been created
  29. XmPciLpEvent_BusError    = 1, // PHB has failed
  30. XmPciLpEvent_BusFailed    = 2, // Msg to Seconday, Primary failed bus
  31. XmPciLpEvent_NodeFailed    = 4, // Multi-adapter bridge has failed
  32. XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered
  33. XmPciLpEvent_BusRecovered  = 12, // PHB has been recovered
  34. XmPciLpEvent_UnQuiesceBus  = 18, // Secondary bus unqiescing
  35. XmPciLpEvent_BridgeError   = 21, // Bridge Error
  36. XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt
  37. };
  38. struct XmPciLpEvent_BusInterrupt {
  39. HvBusNumber busNumber;
  40. HvSubBusNumber subBusNumber;
  41. };
  42. struct XmPciLpEvent_NodeInterrupt {
  43. HvBusNumber busNumber;
  44. HvSubBusNumber subBusNumber;
  45. HvAgentId deviceId;
  46. };
  47. struct XmPciLpEvent {
  48. struct HvLpEvent hvLpEvent;
  49. union {
  50. u64 alignData; // Align on an 8-byte boundary
  51. struct {
  52. u32 fisr;
  53. HvBusNumber busNumber;
  54. HvSubBusNumber subBusNumber;
  55. HvAgentId deviceId;
  56. } slotInterrupt;
  57. struct XmPciLpEvent_BusInterrupt busFailed;
  58. struct XmPciLpEvent_BusInterrupt busRecovered;
  59. struct XmPciLpEvent_BusInterrupt busCreated;
  60. struct XmPciLpEvent_NodeInterrupt nodeFailed;
  61. struct XmPciLpEvent_NodeInterrupt nodeRecovered;
  62. } eventData;
  63. };
  64. static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm);
  65. static void logXmEvent( char* ErrorText, int busNumber);
  66. static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm)
  67. {
  68. //PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_handler, type 0x%xn",eventParm->xType );
  69. ++Pci_Event_Count;
  70. if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) {
  71. switch( eventParm->xFlags.xFunction ) {
  72. case HvLpEvent_Function_Int:
  73. intReceived( (struct XmPciLpEvent*)eventParm, regsParm );
  74. break;
  75. case HvLpEvent_Function_Ack:
  76. printk(KERN_ERR "XmPciLpEvent.c: Unexpected ack receivedn");
  77. break;
  78. default:
  79. printk(KERN_ERR "XmPciLpEvent.c: Unexpected event function %dn",(int)eventParm->xFlags.xFunction);
  80. break;
  81. }
  82. }
  83. else if (event) {
  84. printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%xn",(int)eventParm->xType);
  85. }
  86. else {
  87. printk(KERN_ERR "XmPciLpEvent.c: NULL event receivedn");
  88. }
  89. }
  90. static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm)
  91. {
  92. int irq;
  93. ++Pci_Interrupt_Count;
  94. //PPCDBG(PPCDBG_BUSWALK,"PCI: XmPciLpEvent.c: intReceivedn");
  95. switch (eventParm->hvLpEvent.xSubtype) {
  96. case XmPciLpEvent_SlotInterrupt:
  97. irq = eventParm->hvLpEvent.xCorrelationToken;
  98. /* Dispatch the interrupt handlers for this irq */
  99. ppc_irq_dispatch_handler(regsParm, irq);
  100. HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
  101.       eventParm->eventData.slotInterrupt.subBusNumber,
  102.       eventParm->eventData.slotInterrupt.deviceId);
  103. break;
  104. /* Ignore error recovery events for now */
  105. case XmPciLpEvent_BusCreated:
  106.         logXmEvent("System bus created.",eventParm->eventData.busCreated.busNumber);
  107. break;
  108. case XmPciLpEvent_BusError:
  109. case XmPciLpEvent_BusFailed:
  110. logXmEvent("System bus failed.", eventParm->eventData.busFailed.busNumber);
  111. break;
  112. case XmPciLpEvent_BusRecovered:
  113. case XmPciLpEvent_UnQuiesceBus:
  114. logXmEvent("System bus recovered.",eventParm->eventData.busRecovered.busNumber);
  115. break;
  116. case XmPciLpEvent_NodeFailed:
  117. case XmPciLpEvent_BridgeError:
  118.         logXmEvent("Multi-adapter bridge failed.",eventParm->eventData.nodeFailed.busNumber);
  119.         break;
  120. case XmPciLpEvent_NodeRecovered:
  121. logXmEvent("Multi-adapter bridge recovered",eventParm->eventData.nodeRecovered.busNumber);
  122. break;
  123. default:
  124.         logXmEvent("Unrecognized event subtype.",eventParm->hvLpEvent.xSubtype);
  125. break;
  126. };
  127. }
  128. /* This should be called sometime prior to buswalk (init_IRQ would be good) */
  129. int XmPciLpEvent_init()
  130. {
  131. int xRc;
  132. PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_init, Register Event type 0x%04Xn",HvLpEvent_Type_PciIo);
  133. xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler);
  134. if (xRc == 0) {
  135. xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
  136. if (xRc != 0) {
  137. printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%xn", xRc);
  138. }
  139. }
  140. else {
  141. printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%xn", xRc);
  142.      }
  143.     return xRc;
  144. }
  145. /***********************************************************************/
  146. /* printk                                                              */
  147. /*   XmPciLpEvent: System bus failed, bus 0x4A. Time:128-16.10.44      */
  148. /* pcifr                                                               */
  149. /*  0045. XmPciLpEvent: System bus failed, bus 0x4A. Time:128-16.10.44 */
  150. /***********************************************************************/
  151. static void logXmEvent( char* ErrorText, int busNumber) {
  152. struct  timeval  TimeClock;
  153. struct  rtc_time CurTime;
  154. do_gettimeofday(&TimeClock);
  155. to_tm(TimeClock.tv_sec, &CurTime);
  156. char    EventLog[128];
  157. sprintf(EventLog,"XmPciLpEvent: %s, Bus:0x%03X.  Time:%02d.%02d.%02d",
  158. ErrorText,busNumber,
  159. CurTime.tm_hour,CurTime.tm_min,CurTime.tm_sec);
  160. fr_Log_Entry(PciFr,EventLog);
  161. printk(KERN_INFO "%sn",EventLog);
  162. }