Commit 9f3f3558 authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds

[PATCH] ppc64: Use correct buffer size in RTAS call

Firmware expects the size of the buffer that you hand it when you ask it
for information about a hardware error to be of a very specific size, but
different versions of firmware appearently expect different sizes; using
the wrong size results in a painful, hard-to-debug crash in firmware.  Benh
provided a patch for this some months ago, but appreantly missed this code
path.  This patch sets up the log buffer size dynamically; it also fixes a
bug with the return code not being handled correctly.
Signed-off-by: default avatarLinas Vepstas <linas@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 78d51cf8
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/paca.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/param.h> #include <asm/param.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -75,7 +74,6 @@ rtas_token(const char *service) ...@@ -75,7 +74,6 @@ rtas_token(const char *service)
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
} }
/** Return a copy of the detailed error text associated with the /** Return a copy of the detailed error text associated with the
* most recent failed call to rtas. Because the error text * most recent failed call to rtas. Because the error text
* might go stale if there are any other intervening rtas calls, * might go stale if there are any other intervening rtas calls,
...@@ -86,28 +84,32 @@ static int ...@@ -86,28 +84,32 @@ static int
__fetch_rtas_last_error(void) __fetch_rtas_last_error(void)
{ {
struct rtas_args err_args, save_args; struct rtas_args err_args, save_args;
u32 bufsz;
bufsz = rtas_token ("rtas-error-log-max");
if ((bufsz == RTAS_UNKNOWN_SERVICE) ||
(bufsz > RTAS_ERROR_LOG_MAX)) {
printk (KERN_WARNING "RTAS: bad log buffer size %d\n", bufsz);
bufsz = RTAS_ERROR_LOG_MAX;
}
err_args.token = rtas_token("rtas-last-error"); err_args.token = rtas_token("rtas-last-error");
err_args.nargs = 2; err_args.nargs = 2;
err_args.nret = 1; err_args.nret = 1;
err_args.rets = (rtas_arg_t *)&(err_args.args[2]);
err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf); err_args.args[0] = (rtas_arg_t)__pa(rtas_err_buf);
err_args.args[1] = RTAS_ERROR_LOG_MAX; err_args.args[1] = bufsz;
err_args.args[2] = 0; err_args.args[2] = 0;
save_args = rtas.args; save_args = rtas.args;
rtas.args = err_args; rtas.args = err_args;
PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
__pa(&err_args));
enter_rtas(__pa(&rtas.args)); enter_rtas(__pa(&rtas.args));
PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
err_args = rtas.args; err_args = rtas.args;
rtas.args = save_args; rtas.args = save_args;
return err_args.rets[0]; return err_args.args[2];
} }
int rtas_call(int token, int nargs, int nret, int *outputs, ...) int rtas_call(int token, int nargs, int nret, int *outputs, ...)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment