From: Nathan Fontenot Add log_rtas_error(), to be called in the event that a rtas call returns a hardware error (-1) so we can log additional information about the hardware error. --- arch/ppc64/kernel/rtas.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+) diff -puN arch/ppc64/kernel/rtas.c~ppc64-log-rtas-error arch/ppc64/kernel/rtas.c --- 25/arch/ppc64/kernel/rtas.c~ppc64-log-rtas-error 2004-02-21 20:58:17.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/rtas.c 2004-02-21 20:58:17.000000000 -0800 @@ -59,6 +59,8 @@ struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED }; +char rtas_err_buf[RTAS_ERROR_LOG_MAX]; + extern unsigned long reloc_offset(void); spinlock_t rtas_data_buf_lock = SPIN_LOCK_UNLOCKED; @@ -126,6 +128,34 @@ rtas_token(const char *service) return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; } +void +log_rtas_error(struct rtas_args *rtas_args) +{ + struct rtas_args err_args; + + err_args.token = rtas_token("rtas-last-error"); + err_args.nargs = 2; + 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[1] = RTAS_ERROR_LOG_MAX; + err_args.args[2] = 0; + + get_paca()->xRtas = err_args; + + PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", + (void *)__pa((unsigned long)&err_args)); + enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas)); + PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); + + err_args = get_paca()->xRtas; + get_paca()->xRtas = *rtas_args; + + if (err_args.rets[0] == 0) + log_error(rtas_err_buf, ERR_TYPE_RTAS_LOG, 0); +} + long rtas_call(int token, int nargs, int nret, unsigned long *outputs, ...) @@ -166,6 +196,10 @@ rtas_call(int token, int nargs, int nret (void *)__pa((unsigned long)rtas_args)); enter_rtas((void *)__pa((unsigned long)rtas_args)); PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); + + if (rtas_args->rets[0] == -1) + log_rtas_error(rtas_args); + #if 0 /* Gotta do something different here, use global lock for now... */ spin_unlock_irqrestore(&rtas_args->lock, s); #else @@ -410,9 +444,14 @@ asmlinkage int ppc_rtas(struct rtas_args return -EFAULT; spin_lock_irqsave(&rtas.lock, flags); + get_paca()->xRtas = args; enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas)); args = get_paca()->xRtas; + + if (args.rets[0] == -1) + log_rtas_error(&args); + spin_unlock_irqrestore(&rtas.lock, flags); /* Copy out args. */ _