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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * ras.c
  3.  * Copyright (C) 2001 Dave Engebretsen IBM Corporation
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18.  */
  19. /* Change Activity:
  20.  * 2001/09/21 : engebret : Created with minimal EPOW and HW exception support.
  21.  * End Change Activity 
  22.  */
  23. #include <linux/ptrace.h>
  24. #include <linux/errno.h>
  25. #include <linux/threads.h>
  26. #include <linux/kernel_stat.h>
  27. #include <linux/signal.h>
  28. #include <linux/sched.h>
  29. #include <linux/ioport.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/timex.h>
  32. #include <linux/init.h>
  33. #include <linux/slab.h>
  34. #include <linux/pci.h>
  35. #include <linux/delay.h>
  36. #include <linux/irq.h>
  37. #include <linux/proc_fs.h>
  38. #include <linux/random.h>
  39. #include <linux/sysrq.h>
  40. #include <asm/uaccess.h>
  41. #include <asm/bitops.h>
  42. #include <asm/system.h>
  43. #include <asm/io.h>
  44. #include <asm/pgtable.h>
  45. #include <asm/irq.h>
  46. #include <asm/cache.h>
  47. #include <asm/prom.h>
  48. #include <asm/ptrace.h>
  49. #include <asm/iSeries/LparData.h>
  50. #include <asm/machdep.h>
  51. #include <asm/rtas.h>
  52. #include <asm/ppcdebug.h>
  53. static void ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs);
  54. static void ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs);
  55. void init_ras_IRQ(void);
  56. /* #define DEBUG */
  57. /*
  58.  * Initialize handlers for the set of interrupts caused by hardware errors
  59.  * and power system events.
  60.  */
  61. void init_ras_IRQ(void) {
  62. struct device_node *np;
  63. unsigned int *ireg, len, i;
  64. if((np = find_path_device("/event-sources/internal-errors")) &&
  65.    (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
  66. &len))) {
  67. for(i=0; i<(len / sizeof(*ireg)); i++) {
  68. request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
  69.     &ras_error_interrupt, 0, 
  70.     "RAS_ERROR", NULL);
  71. ireg++;
  72. }
  73. }
  74. if((np = find_path_device("/event-sources/epow-events")) &&
  75.    (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
  76. &len))) {
  77. for(i=0; i<(len / sizeof(*ireg)); i++) {
  78. request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
  79.     &ras_epow_interrupt, 0, 
  80.     "RAS_EPOW", NULL);
  81. ireg++;
  82. }
  83. }
  84. }
  85. /*
  86.  * Handle power subsystem events (EPOW).
  87.  *
  88.  * Presently we just log the event has occured.  This should be fixed
  89.  * to examine the type of power failure and take appropriate action where
  90.  * the time horizon permits something useful to be done.
  91.  */
  92. static void
  93. ras_epow_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  94. {
  95. struct rtas_error_log log_entry;
  96. unsigned int size = sizeof(log_entry);
  97. long status = 0xdeadbeef;
  98. status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 
  99.    0x500, irq, 
  100.    EPOW_WARNING | POWERMGM_EVENTS, 
  101.    1,  /* Time Critical */
  102.    __pa(&log_entry), size);
  103. udbg_printf("EPOW <0x%lx 0x%lx>n", 
  104.     *((unsigned long *)&log_entry), status); 
  105. printk(KERN_WARNING 
  106.        "EPOW <0x%lx 0x%lx>n",*((unsigned long *)&log_entry), status);
  107. }
  108. /*
  109.  * Handle hardware error interrupts.
  110.  *
  111.  * RTAS check-exception is called to collect data on the exception.  If
  112.  * the error is deemed recoverable, we log a warning and return.
  113.  * For nonrecoverable errors, an error is logged and we stop all processing
  114.  * as quickly as possible in order to prevent propagation of the failure.
  115.  */
  116. static void
  117. ras_error_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  118. {
  119. struct rtas_error_log log_entry;
  120. unsigned int size = sizeof(log_entry);
  121. long status = 0xdeadbeef;
  122. status = rtas_call(rtas_token("check-exception"), 6, 1, NULL, 
  123.    0x500, irq, 
  124.    INTERNAL_ERROR, 
  125.    1, /* Time Critical */
  126.    __pa(&log_entry), size);
  127. if((status != 1) && 
  128.    (log_entry.severity >= SEVERITY_ERROR_SYNC)) {
  129. udbg_printf("HW Error <0x%lx 0x%lx>n",
  130.     *((unsigned long *)&log_entry), status);
  131. printk(KERN_EMERG 
  132.        "Error: Fatal hardware error <0x%lx 0x%lx>n",
  133.        *((unsigned long *)&log_entry), status);
  134. #ifndef DEBUG
  135. /* Don't actually power off when debugging so we can test
  136.  * without actually failing while injecting errors.
  137.  */
  138. ppc_md.power_off();
  139. #endif
  140. } else {
  141. udbg_printf("Recoverable HW Error <0x%lx 0x%lx>n",
  142.     *((unsigned long *)&log_entry), status); 
  143. printk(KERN_WARNING 
  144.        "Warning: Recoverable hardware error <0x%lx 0x%lx>n",
  145.        *((unsigned long *)&log_entry), status);
  146. return;
  147. }
  148. }