aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2012-03-21 11:47:07 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-03-27 20:31:58 -0400
commit6431f20879e338306b997cd75a36824cf9d6e687 (patch)
tree3ae6dd6a4347861b1834ea6b612ae686d23e0c1e /arch/powerpc
parent1a5c2e63f497bdb5912138888053a02870ed1153 (diff)
powerpc: Make function that parses RTAS error logs global
The IO event interrupt code has a function that finds specific sections in an RTAS error log. We want to use it in the EPOW code so make it global. Rename things to make it less cryptic: find_xelog_section() -> get_pseries_errorlog() struct pseries_elog_section -> struct pseries_errorlog Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/rtas.h33
-rw-r--r--arch/powerpc/kernel/rtas.c34
-rw-r--r--arch/powerpc/platforms/pseries/io_event_irq.c68
3 files changed, 69 insertions, 66 deletions
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 01c143bb77ae..a01fa3eee6bd 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -204,6 +204,39 @@ struct rtas_ext_event_log_v6 {
204 /* Variable length. */ 204 /* Variable length. */
205}; 205};
206 206
207/* pSeries event log format */
208
209/* Two bytes ASCII section IDs */
210#define PSERIES_ELOG_SECT_ID_PRIV_HDR (('P' << 8) | 'H')
211#define PSERIES_ELOG_SECT_ID_USER_HDR (('U' << 8) | 'H')
212#define PSERIES_ELOG_SECT_ID_PRIMARY_SRC (('P' << 8) | 'S')
213#define PSERIES_ELOG_SECT_ID_EXTENDED_UH (('E' << 8) | 'H')
214#define PSERIES_ELOG_SECT_ID_FAILING_MTMS (('M' << 8) | 'T')
215#define PSERIES_ELOG_SECT_ID_SECONDARY_SRC (('S' << 8) | 'S')
216#define PSERIES_ELOG_SECT_ID_DUMP_LOCATOR (('D' << 8) | 'H')
217#define PSERIES_ELOG_SECT_ID_FW_ERROR (('S' << 8) | 'W')
218#define PSERIES_ELOG_SECT_ID_IMPACT_PART_ID (('L' << 8) | 'P')
219#define PSERIES_ELOG_SECT_ID_LOGIC_RESOURCE_ID (('L' << 8) | 'R')
220#define PSERIES_ELOG_SECT_ID_HMC_ID (('H' << 8) | 'M')
221#define PSERIES_ELOG_SECT_ID_EPOW (('E' << 8) | 'P')
222#define PSERIES_ELOG_SECT_ID_IO_EVENT (('I' << 8) | 'E')
223#define PSERIES_ELOG_SECT_ID_MANUFACT_INFO (('M' << 8) | 'I')
224#define PSERIES_ELOG_SECT_ID_CALL_HOME (('C' << 8) | 'H')
225#define PSERIES_ELOG_SECT_ID_USER_DEF (('U' << 8) | 'D')
226
227/* Vendor specific Platform Event Log Format, Version 6, section header */
228struct pseries_errorlog {
229 uint16_t id; /* 0x00 2-byte ASCII section ID */
230 uint16_t length; /* 0x02 Section length in bytes */
231 uint8_t version; /* 0x04 Section version */
232 uint8_t subtype; /* 0x05 Section subtype */
233 uint16_t creator_component; /* 0x06 Creator component ID */
234 uint8_t data[]; /* 0x08 Start of section data */
235};
236
237struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
238 uint16_t section_id);
239
207/* 240/*
208 * This can be set by the rtas_flash module so that it can get called 241 * This can be set by the rtas_flash module so that it can get called
209 * as the absolutely last thing before the kernel terminates. 242 * as the absolutely last thing before the kernel terminates.
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 9f843cdfee9e..4d1a7babe342 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -868,6 +868,40 @@ int rtas_ibm_suspend_me(struct rtas_args *args)
868} 868}
869#endif 869#endif
870 870
871/**
872 * Find a specific pseries error log in an RTAS extended event log.
873 * @log: RTAS error/event log
874 * @section_id: two character section identifier
875 *
876 * Returns a pointer to the specified errorlog or NULL if not found.
877 */
878struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
879 uint16_t section_id)
880{
881 struct rtas_ext_event_log_v6 *ext_log =
882 (struct rtas_ext_event_log_v6 *)log->buffer;
883 struct pseries_errorlog *sect;
884 unsigned char *p, *log_end;
885
886 /* Check that we understand the format */
887 if (log->extended_log_length < sizeof(struct rtas_ext_event_log_v6) ||
888 ext_log->log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
889 ext_log->company_id != RTAS_V6EXT_COMPANY_ID_IBM)
890 return NULL;
891
892 log_end = log->buffer + log->extended_log_length;
893 p = ext_log->vendor_log;
894
895 while (p < log_end) {
896 sect = (struct pseries_errorlog *)p;
897 if (sect->id == section_id)
898 return sect;
899 p += sect->length;
900 }
901
902 return NULL;
903}
904
871asmlinkage int ppc_rtas(struct rtas_args __user *uargs) 905asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
872{ 906{
873 struct rtas_args args; 907 struct rtas_args args;
diff --git a/arch/powerpc/platforms/pseries/io_event_irq.c b/arch/powerpc/platforms/pseries/io_event_irq.c
index 1a709bc48ce1..ef9d9d84c7d5 100644
--- a/arch/powerpc/platforms/pseries/io_event_irq.c
+++ b/arch/powerpc/platforms/pseries/io_event_irq.c
@@ -63,73 +63,9 @@ EXPORT_SYMBOL_GPL(pseries_ioei_notifier_list);
63 63
64static int ioei_check_exception_token; 64static int ioei_check_exception_token;
65 65
66/* pSeries event log format */
67
68/* Two bytes ASCII section IDs */
69#define PSERIES_ELOG_SECT_ID_PRIV_HDR (('P' << 8) | 'H')
70#define PSERIES_ELOG_SECT_ID_USER_HDR (('U' << 8) | 'H')
71#define PSERIES_ELOG_SECT_ID_PRIMARY_SRC (('P' << 8) | 'S')
72#define PSERIES_ELOG_SECT_ID_EXTENDED_UH (('E' << 8) | 'H')
73#define PSERIES_ELOG_SECT_ID_FAILING_MTMS (('M' << 8) | 'T')
74#define PSERIES_ELOG_SECT_ID_SECONDARY_SRC (('S' << 8) | 'S')
75#define PSERIES_ELOG_SECT_ID_DUMP_LOCATOR (('D' << 8) | 'H')
76#define PSERIES_ELOG_SECT_ID_FW_ERROR (('S' << 8) | 'W')
77#define PSERIES_ELOG_SECT_ID_IMPACT_PART_ID (('L' << 8) | 'P')
78#define PSERIES_ELOG_SECT_ID_LOGIC_RESOURCE_ID (('L' << 8) | 'R')
79#define PSERIES_ELOG_SECT_ID_HMC_ID (('H' << 8) | 'M')
80#define PSERIES_ELOG_SECT_ID_EPOW (('E' << 8) | 'P')
81#define PSERIES_ELOG_SECT_ID_IO_EVENT (('I' << 8) | 'E')
82#define PSERIES_ELOG_SECT_ID_MANUFACT_INFO (('M' << 8) | 'I')
83#define PSERIES_ELOG_SECT_ID_CALL_HOME (('C' << 8) | 'H')
84#define PSERIES_ELOG_SECT_ID_USER_DEF (('U' << 8) | 'D')
85
86/* Vendor specific Platform Event Log Format, Version 6, section header */
87struct pseries_elog_section {
88 uint16_t id; /* 0x00 2-byte ASCII section ID */
89 uint16_t length; /* 0x02 Section length in bytes */
90 uint8_t version; /* 0x04 Section version */
91 uint8_t subtype; /* 0x05 Section subtype */
92 uint16_t creator_component; /* 0x06 Creator component ID */
93 uint8_t data[]; /* 0x08 Start of section data */
94};
95
96static char ioei_rtas_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; 66static char ioei_rtas_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
97 67
98/** 68/**
99 * Find data portion of a specific section in RTAS extended event log.
100 * @elog: RTAS error/event log.
101 * @sect_id: secsion ID.
102 *
103 * Return:
104 * pointer to the section data of the specified section
105 * NULL if not found
106 */
107static struct pseries_elog_section *find_xelog_section(struct rtas_error_log *elog,
108 uint16_t sect_id)
109{
110 struct rtas_ext_event_log_v6 *xelog =
111 (struct rtas_ext_event_log_v6 *) elog->buffer;
112 struct pseries_elog_section *sect;
113 unsigned char *p, *log_end;
114
115 /* Check that we understand the format */
116 if (elog->extended_log_length < sizeof(struct rtas_ext_event_log_v6) ||
117 xelog->log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
118 xelog->company_id != RTAS_V6EXT_COMPANY_ID_IBM)
119 return NULL;
120
121 log_end = elog->buffer + elog->extended_log_length;
122 p = xelog->vendor_log;
123 while (p < log_end) {
124 sect = (struct pseries_elog_section *)p;
125 if (sect->id == sect_id)
126 return sect;
127 p += sect->length;
128 }
129 return NULL;
130}
131
132/**
133 * Find the data portion of an IO Event section from event log. 69 * Find the data portion of an IO Event section from event log.
134 * @elog: RTAS error/event log. 70 * @elog: RTAS error/event log.
135 * 71 *
@@ -138,7 +74,7 @@ static struct pseries_elog_section *find_xelog_section(struct rtas_error_log *el
138 */ 74 */
139static struct pseries_io_event * ioei_find_event(struct rtas_error_log *elog) 75static struct pseries_io_event * ioei_find_event(struct rtas_error_log *elog)
140{ 76{
141 struct pseries_elog_section *sect; 77 struct pseries_errorlog *sect;
142 78
143 /* We should only ever get called for io-event interrupts, but if 79 /* We should only ever get called for io-event interrupts, but if
144 * we do get called for another type then something went wrong so 80 * we do get called for another type then something went wrong so
@@ -152,7 +88,7 @@ static struct pseries_io_event * ioei_find_event(struct rtas_error_log *elog)
152 return NULL; 88 return NULL;
153 } 89 }
154 90
155 sect = find_xelog_section(elog, PSERIES_ELOG_SECT_ID_IO_EVENT); 91 sect = get_pseries_errorlog(elog, PSERIES_ELOG_SECT_ID_IO_EVENT);
156 if (unlikely(!sect)) { 92 if (unlikely(!sect)) {
157 printk_once(KERN_WARNING "io_event_irq: RTAS extended event " 93 printk_once(KERN_WARNING "io_event_irq: RTAS extended event "
158 "log does not contain an IO Event section. " 94 "log does not contain an IO Event section. "