--- ./arch/ppc64/kernel/irq.c.orig 2003-11-03 14:37:11.000000000 -0500 +++ ./arch/ppc64/kernel/irq.c 2003-11-03 14:38:50.000000000 -0500 @@ -853,6 +853,11 @@ int do_IRQ(struct pt_regs *regs) /* Signal a fake PMC interrupt */ PerformanceMonitorException(); } + if (lpaca->sysrqKey) { + char key = lpaca->sysrqKey; + lpaca->sysrqKey = 0; + handle_sysrq(key, NULL, NULL, 0); + } #endif if (softirq_pending(cpu)) --- ./drivers/iseries/viocons.c.orig 2003-11-03 14:40:59.000000000 -0500 +++ ./drivers/iseries/viocons.c 2003-11-03 14:47:08.000000000 -0500 @@ -807,6 +807,34 @@ static void initDataEvent(struct viochar viochar->event.xTargetInstanceId = viopath_targetinst(lp); } +static inline void do_write(HvLpIndex lp, u8 port, const char *buf, + size_t len, struct viocharlpevent *viochar) +{ + int written, i; + struct paca_struct *lpaca = get_paca(); + + for (i = 0; i < 10; i++) { + + written = internal_write(lp, port, buf, len, viochar); + if ((written < 0) || (written == len)) + /* Either an error happened, or we wrote everything */ + break; + /* + * Only part of the data made it out. This can happen if + * the overflow buffers are full. In this case, we may + * have pending write acknowledgment interrupts that + * we'll need to service before we can write some more. + * Check for this. If none, then pause and try again. + */ + len -= written; + buf += written; + if (ItLpQueue_isLpIntPending(lpaca->lpQueuePtr)) + process_iSeries_events(); + else + udelay(1000); + } +} + /* console device write */ static void viocons_write(struct console *co, const char *s, unsigned count) @@ -849,17 +877,17 @@ static void viocons_write(struct console * Newline found. Print everything up to and * including the newline */ - internal_write(lp, port, &s[begin], index-begin+1, 0); + do_write(lp, port, &s[begin], index-begin+1, 0); begin = index + 1; /* Emit a carriage return as well */ charptr[0] = '\r'; - internal_write(lp, port, charptr, 1, 0); + do_write(lp, port, charptr, 1, 0); } } /* If any characters left to write, write them now */ if (index - begin > 0) - internal_write(lp, port, &s[begin], index - begin, 0); + do_write(lp, port, &s[begin], index - begin, 0); } /* Work out a the device associate with this console @@ -1361,7 +1389,8 @@ static void vioHandleData(struct HvLpEve * the data string.*/ continue; } else if (vio_sysrq_pressed) { - handle_sysrq(cevent->immediateData[index], NULL, NULL, tty); + struct paca_struct *lpaca = get_paca(); + lpaca->sysrqKey = cevent->immediateData[index]; vio_sysrq_pressed = 0; /* continue because we don't want to add the sysrq * sequence into the data string.*/ --- ./include/asm-ppc64/paca.h.orig 2003-11-03 14:39:22.000000000 -0500 +++ ./include/asm-ppc64/paca.h 2003-11-03 14:40:36.000000000 -0500 @@ -87,7 +87,9 @@ struct paca_struct { u8 xHrdIntCount; /* Count of active hardware interrupts 0x79 */ u8 active; /* Is this cpu active? 0x1a */ u8 available; /* Is this cpu available? 0x1b */ - u8 resv1[4]; /* 0x7B-0x7F */ + u8 sysrqKey; /* sysrq key if one requested, else 0 + + u8 resv1[3]; /* 0x7B-0x7F */ /*===================================================================================== * CACHE_LINE_2 0x0080 - 0x00FF