Included here is a patch to linux-2.1.121-r3000-pre1.tgz
that allows a working serial console line to the decstation 2100.
It includes the patches recently posted by Harald to mask the
interrupt bits in cpu register $12.
Undoubtedly there are more bugs in the dz.c driver - but this
seems to allow interactive dialog in single user mode...
The console line should be plugged into the outlet on the back of
the decstation that has a small printer symbol above it.
Anyone who tries this out - please let me know the results.
-Tom Riemer
-----------------------------------------------------------------
diff -rubN linux-2.1.121-r3000/arch/mips/dec/irq.c
linux-2.1.121-r3000_pl8/arch/mips/dec/irq.c
--- linux-2.1.121-r3000/arch/mips/dec/irq.c Sun Oct 4 11:40:36 1998
+++ linux-2.1.121-r3000_pl8/arch/mips/dec/irq.c Sat Nov 14 14:24:50 1998
@@ -51,39 +51,15 @@
*imr |= dec_interrupt[irq_nr].iemask;
wbflush();
}
- set_cp0_status(ST0_IM, dec_interrupt[irq_nr].cpu_mask);
-}
-
-static inline void mask_irq_flags(unsigned int irq_nr, unsigned long *flags)
-{
- if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC
interrupt */
- *imr &= ~dec_interrupt[irq_nr].iemask;
- wbflush();
- } else /* This is a cpu interrupt */
- *flags &= ~dec_interrupt[irq_nr].cpu_mask;
-}
-
-static inline void unmask_irq_flags(unsigned int irq_nr, unsigned long *flags)
-{
- if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC
interrupt */
- *imr |= dec_interrupt[irq_nr].iemask;
- wbflush();
- }
- *flags |= dec_interrupt[irq_nr].cpu_mask;
+ set_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) |
dec_interrupt[irq_nr].cpu_mask);
}
void disable_irq(unsigned int irq_nr)
{
unsigned long flags;
-/* TEST */
- panic("disable_irq called");
save_and_cli(flags);
- if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC
interrupt */
- *imr &= ~dec_interrupt[irq_nr].iemask;
- wbflush();
- } else /* This is a cpu interrupt */
- flags &= ~dec_interrupt[irq_nr].cpu_mask;
+ mask_irq(irq_nr);
restore_flags(flags);
}
@@ -91,14 +67,8 @@
{
unsigned long flags;
-/* TEST */
- panic("enable_irq called");
save_and_cli(flags);
- if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC
interrupt */
- *imr |= dec_interrupt[irq_nr].iemask;
- wbflush();
- }
- flags |= dec_interrupt[irq_nr].cpu_mask;
+ unmask_irq(irq_nr);
restore_flags(flags);
}
@@ -213,7 +183,7 @@
*p = new;
if (!shared) {
- unmask_irq_flags(irq, &flags);
+ unmask_irq(irq);
}
restore_flags(flags);
return 0;
@@ -268,7 +238,7 @@
save_and_cli(flags);
*p = action->next;
if (!irq[irq_action])
- mask_irq_flags(irq, &flags);
+ mask_irq(irq);
restore_flags(flags);
kfree(action);
return;
diff -rubN linux-2.1.121-r3000/arch/mips/kernel/r2300_switch.S
linux-2.1.121-r3000_pl8/arch/mips/kernel/r2300_switch.S
--- linux-2.1.121-r3000/arch/mips/kernel/r2300_switch.S Sun Oct 4 11:51:54 1998
+++ linux-2.1.121-r3000_pl8/arch/mips/kernel/r2300_switch.S Sat Nov 14
14:24:50 1998
@@ -45,11 +45,17 @@
CPU_RESTORE_NONSCRATCH($28)
addiu t0, $28, KERNEL_STACK_SIZE-32
sw t0, kernelsp
- lw a3, TASK_MM($28)
+ mfc0 t1, CP0_STATUS /* Do we really need this? */
+ ori a3, $0, 0xff00
+ and t1, a3
lw a2, THREAD_STATUS($28)
+ nor a3, $0, a3
+ and a2, a3
+ lw a3, TASK_MM($28)
+ or a2, t1
lw a3, MM_CONTEXT(a3)
mtc0 a2, CP0_STATUS
- andi a3, KU_USER
+ andi a3, ASID_MASK
jr ra
mtc0 a3, CP0_ENTRYHI
END(r2300_resume)
diff -rubN linux-2.1.121-r3000/drivers/char/dz.c
linux-2.1.121-r3000_pl8/drivers/char/dz.c
--- linux-2.1.121-r3000/drivers/char/dz.c Thu Oct 1 14:55:25 1998
+++ linux-2.1.121-r3000_pl8/drivers/char/dz.c Sat Nov 14 14:31:29 1998
@@ -10,6 +10,8 @@
* Changed IRQ to use Harald's dec internals interrupts.h
* removed base_addr code - moving address assignment to setup.c
* Changed name of dz_init to rs_init to be consistent with tc code
+ * [13-NOV-98] triemer fixed code to receive characters
+ * after patches by harald to irq code.
*/
#ifdef MODULE
@@ -29,12 +31,13 @@
#include <linux/param.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
-
+#include <asm-mips/wbflush.h>
/* for definition of SERIAL */
#include <asm/dec/interrupts.h>
/* for definition of struct console */
#ifdef CONFIG_SERIAL_CONSOLE
+#define CONSOLE_LINE (3)
#include <linux/console.h>
#endif /* ifdef CONFIG_SERIAL_CONSOLE */
@@ -47,14 +50,81 @@
#include <asm/dec/machtype.h>
#include <asm/dec/kn01.h>
#include <asm/dec/kn02.h>
-
+#include <asm/bootinfo.h>
#include "dz.h"
-#define DZ_INTR_DEBUG 1
+/* #define DZ_INTR_DEBUG */
-DECLARE_TASK_QUEUE(tq_dz_serial);
+DECLARE_TASK_QUEUE(tq_serial);
+static struct dz_serial *lines[4];
extern struct wait_queue *keypress_wait;
+/* TO FIX - its unclear what
+ the intention for tmp_buf is all about
+ but I'm just going to point tmp_buf at temp_buffer
+ if tmp_buf is not defined
+*/
+
+unsigned char tmp_buffer[256];
+
+
+/* debugging code to send out chars via prom */
+static void debug_console( const char *s,int count)
+{
+ unsigned i;
+
+ tag *atag;
+ static int (*prom_printf) (char *,...);
+ static int (*prom_getchar) (void);
+
+
+ atag = bi_TagFind(tag_prom_printf);
+ prom_printf = (int (*)(char *,...)) *(int *) TAGVALPTR(atag);
+ atag = bi_TagFind(tag_prom_getchar);
+ prom_getchar = (int (*)(void)) *(int *) TAGVALPTR(atag);
+
+ /*
+ * Now, do each character
+ */
+ /* while (s[count] != '\0')
+ count++;
+ */
+
+ for (i = 0; i < count; i++) {
+ if (*s == 10)
+ prom_printf("%c", 13);
+ prom_printf("%c", *s++);
+ }
+}
+#ifdef DEBUG
+
+static void debug_int_console(unsigned short val, char *prn, int count)
+{
+ char bits[16];
+ int i;
+ for (i = 0; i < 16; i++)
+ if ((1<<i) & val)
+ bits[15-i] = '1';
+ else
+ bits[15-i] = '0';
+ debug_console(prn,count);
+ debug_console(bits,16);
+ debug_console("\n",1);
+}
+#endif
+
+static inline void outw (unsigned short val, unsigned port)
+{
+ volatile unsigned short *mem_port = (volatile unsigned short *)port;
+ *mem_port = val;
+}
+
+static inline unsigned short inw (unsigned port)
+{
+ volatile unsigned short *mem_port = (volatile unsigned short *)port;
+ return *mem_port;
+}
+
/*
* ------------------------------------------------------------
@@ -68,15 +138,15 @@
static inline unsigned short dz_in (struct dz_serial *info, unsigned offset)
{
volatile unsigned short *addr = (volatile unsigned short *)(info->port +
offset);
-
return *addr;
}
static inline void dz_out (struct dz_serial *info, unsigned offset, unsigned
short value)
{
- volatile unsigned short *addr = (volatile unsigned short *)(info->port +
offset);
+ volatile unsigned short *addr = (volatile unsigned short *)(info->port +
offset);
*addr = value;
+
}
/*
@@ -94,13 +164,12 @@
struct dz_serial *info = (struct dz_serial *)tty->driver_data;
unsigned short mask, tmp;
+
mask = 1 << info->line;
tmp = dz_in (info, DZ_TCR); /* read the TX flag */
- if (tmp & mask) {
tmp &= ~mask; /* clear the TX flag */
dz_out (info, DZ_TCR, tmp);
- }
}
static void dz_start (struct tty_struct *tty)
@@ -110,10 +179,10 @@
mask = 1 << info->line;
tmp = dz_in (info, DZ_TCR); /* read the TX flag */
- if (!(tmp & mask)) {
+
tmp |= mask; /* set the TX flag */
dz_out (info, DZ_TCR, tmp);
- }
+
}
/*
@@ -147,7 +216,7 @@
static inline void dz_sched_event (struct dz_serial *info, int event)
{
info->event |= 1 << event;
- queue_task (&info->tqueue, &tq_dz_serial);
+ queue_task (&info->tqueue, &tq_serial);
mark_bh (SERIAL_BH);
}
@@ -160,16 +229,26 @@
*/
static inline void receive_chars (struct dz_serial *info_in)
{
+
struct dz_serial *info;
- struct tty_struct *tty;
+ struct tty_struct *tty = 0;
struct async_icount *icount;
int ignore = 0;
unsigned short status, tmp;
unsigned char ch;
- do {
- status = dz_in (info_in, DZ_RBUF); /* get the char in */
- info = &multi[LINE(status)]; /* re-arrange info to point to the
proper port */
+ /* this code is going to be a problem...
+ the call to tty_flip_buffer is going to need
+ to be rethought...
+ */
+ do
+ {
+ status = dz_in (info_in, DZ_RBUF);
+ info = lines[LINE(status)];
+
+ /* punt so we don't get duplicate characters */
+ if (!(status & DZ_DVAL))
+ goto ignore_char;
#ifdef DZ_INTR_DEBUG
printk ("line (%d)...", LINE(status));
@@ -189,7 +268,6 @@
icount = &info->icount;
if (!tty) break;
-
if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
*tty->flip.char_buf_ptr = ch;
@@ -204,10 +282,11 @@
icount->frame++;
if (status & DZ_OERR) /* overrun error */
icount->overrun++;
- /*
- check to see if we should ignore the character
+
+ /* check to see if we should ignore the character
and mask off conditions that should be ignored
*/
+
if (status & info->ignore_status_mask) {
if (++ignore > 100 ) break;
goto ignore_char;
@@ -217,11 +296,18 @@
tmp = status & info->read_status_mask;
if (tmp & DZ_PERR)
+ {
*tty->flip.flag_buf_ptr = TTY_PARITY;
+ debug_console("PERR\n",5);
+ }
else if (tmp & DZ_FERR)
+ {
*tty->flip.flag_buf_ptr = TTY_FRAME;
- /* overrun might be special ?!? I don't know for the DZ chip so in doubt
... */
- if (tmp & DZ_OERR) {
+ debug_console("FERR\n",5);
+ }
+ if (tmp & DZ_OERR)
+ {
+ debug_console("OERR\n",5);
if (tty->flip.count < TTY_FLIPBUF_SIZE) {
tty->flip.count++;
tty->flip.flag_buf_ptr++;
@@ -230,13 +316,14 @@
}
}
}
-
tty->flip.flag_buf_ptr++;
tty->flip.char_buf_ptr++;
tty->flip.count++;
-
ignore_char:
} while (status & DZ_DVAL);
+
+ if (tty)
+ tty_flip_buffer_push(tty);
}
/*
@@ -250,6 +337,7 @@
{
unsigned char tmp;
+
if (info->x_char) { /* XON/XOFF chars */
dz_out (info, DZ_TDR, info->x_char);
info->icount.tx++;
@@ -307,34 +395,17 @@
*/
static void dz_interrupt (int irq, void *dev, struct pt_regs *regs)
{
- struct dz_serial *info = (struct dz_serial *)dev;
+ struct dz_serial *info;
unsigned short status;
-#ifdef DZ_INTR_DEBUG
- printk ("dz_interrupt_multi (%d)...", irq);
-#endif
-
- status = dz_in (info, DZ_CSR); /* get the reason why we just got an irq */
+ status = dz_in ((struct dz_serial *)dev, DZ_CSR); /* get the reason why we
just got an irq */
+ info = lines[LINE(status)]; /* re-arrange info the proper port */
- if (status & DZ_RDONE) { /* RX interrupt */
-#ifdef DZ_INTR_DEBUG
- printk (" RX ");
-#endif
- receive_chars (info); /* the receive function will deal with the
identification
- of the line causing the irq */
- }
+ if (status & DZ_RDONE)
+ receive_chars (info); /* the receive function */
- if (status & DZ_TRDY) { /* TX interrupt */
-#ifdef DZ_INTR_DEBUG
- printk (" TX line (%d)...", LINE(status));
-#endif
- info = &multi[LINE(status)]; /* re-arrange info to point to the proper
port */
+ if (status & DZ_TRDY)
transmit_chars (info);
- }
-
-#ifdef DZ_INTR_DEBUG
- printk ("end\n");
-#endif
}
/*
@@ -354,7 +425,7 @@
*/
static void do_serial_bh (void)
{
- run_task_queue (&tq_dz_serial);
+ run_task_queue (&tq_serial);
}
static void do_softint (void *private_data)
@@ -435,6 +506,12 @@
/* set up the speed */
change_speed (info);
+ /* clear the line transmitter buffer
+ I can't figure out why I need to do this - but
+ its necessary - in order for the console portion
+ and the interrupt portion to live happily side by side.
+ */
+
info->is_initialized = 1;
restore_flags (flags);
@@ -461,6 +538,7 @@
dz_stop (info->tty);
+
info->cflags &= ~DZ_CREAD; /* turn off receive enable flag */
dz_out (info, DZ_LPR, info->cflags);
@@ -537,6 +615,7 @@
default : info->cflags |= DZ_B9600;
}
+ info->cflags |= DZ_RXENAB;
dz_out (info, DZ_LPR, info->cflags);
/* setup accept flag */
@@ -554,35 +633,6 @@
/*
* -------------------------------------------------------------------
- * dz_put_char ()
- *
- * This is for console output over ttyS.
- * -------------------------------------------------------------------
- */
-static void dz_put_char (struct tty_struct *tty, unsigned char ch)
-{
- struct dz_serial *info = (struct dz_serial *)tty->driver_data;
- unsigned long flags;
-
- if (!tty || !info->xmit_buf) return;
-
- save_flags (flags);
- cli ();
-
- if (info->xmit_cnt >= DZ_XMIT_SIZE-1) {
- restore_flags (flags);
- return;
- }
-
- info->xmit_buf[info->xmit_head++] = ch;
- info->xmit_head &= DZ_XMIT_SIZE-1;
- info->xmit_cnt++;
-
- restore_flags (flags);
-}
-
-/*
- * -------------------------------------------------------------------
* dz_flush_char ()
*
* Flush the buffer.
@@ -616,12 +666,16 @@
{
struct dz_serial *info = (struct dz_serial *)tty->driver_data;
unsigned long flags;
-
int c, ret = 0;
- if (!tty || !info->xmit_buf || !tmp_buf) return ret;
+ if (!tty ) return ret;
+ if (!info->xmit_buf) return ret;
+ if (!tmp_buf) tmp_buf = tmp_buffer;
+
+
if (from_user) {
+
down (&tmp_buf_sem);
while (1) {
c = MIN(count, MIN(DZ_XMIT_SIZE - info->xmit_cnt - 1, DZ_XMIT_SIZE -
info->xmit_head));
@@ -650,6 +704,8 @@
up (&tmp_buf_sem);
} else {
+
+
while (1) {
save_flags (flags);
cli ();
@@ -671,8 +727,17 @@
}
}
- if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) dz_start
(info->tty);
+ if (info->xmit_cnt)
+ {
+ if (!tty->stopped)
+ {
+ if (!tty->hw_stopped)
+ {
+ dz_start (info->tty);
+ }
+ }
+ }
return ret;
}
@@ -695,7 +760,7 @@
/*
* -------------------------------------------------------------------
- * dz_char_in_buffer ()
+ * dz_chars_in_buffer ()
*
* compute the amount of char left to be transmitted
* -------------------------------------------------------------------
@@ -1194,6 +1259,7 @@
int retval, line;
line = MINOR(tty->device) - tty->driver.minor_start;
+
/* The dz lines for the mouse/keyboard must be
* opened using their respective drivers.
*/
@@ -1203,9 +1269,9 @@
if ((line == DZ_KEYBOARD) || (line == DZ_MOUSE))
return -ENODEV;
- info = &multi[line];
-
+ info = lines[line];
info->count++;
+
tty->driver_data = info;
info->tty = tty;
@@ -1216,6 +1282,7 @@
if (retval)
return retval;
+
retval = block_til_ready (tty, filp, info);
if (retval)
return retval;
@@ -1226,11 +1293,11 @@
else
*tty->termios = info->callout_termios;
change_speed (info);
+
}
info->session = current->session;
info->pgrp = current->pgrp;
-
return 0;
}
@@ -1239,7 +1306,7 @@
printk("%s%s\n", dz_name, dz_version);
}
-/* dz_init inits the driver */
+
__initfunc(int dz_init(void))
{
int i, flags;
@@ -1250,9 +1317,6 @@
show_serial_version ();
- /* Initialize the tty_driver structure */
- /* SGI: Not all of this is exactly right for us. */
-
memset(&serial_driver, 0, sizeof(struct tty_driver));
serial_driver.magic = TTY_DRIVER_MAGIC;
serial_driver.name = "ttyS";
@@ -1302,13 +1366,16 @@
save_flags(flags); cli();
i = 0;
- for (info = &multi[i]; i < DZ_NB_PORT; i++) {
+ for (info = &multi[i]; i < DZ_NB_PORT; i++)
+ {
+ lines[i] = info;
info->magic = SERIAL_MAGIC;
- if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100)) {
+
+ if ((mips_machtype == MACH_DS23100) || (mips_machtype == MACH_DS5100))
info->port = (unsigned long) KN01_DZ11_BASE;
- } else {
+ else
info->port = (unsigned long) KN02_DZ11_BASE;
- }
+
info->line = i;
info->tty = 0;
info->close_delay = 50;
@@ -1334,15 +1401,54 @@
printk("ttyS%02d at 0x%04x (irq = %d)\n", info->line, info->port, SERIAL);
}
- if (request_irq (SERIAL, dz_interrupt, (SA_INTERRUPT), "DZ", &multi[0]))
- panic ("Unable to register DZ interrupt\n");
+ /* reset the chip */
+#ifndef CONFIG_SERIAL_CONSOLE
+ dz_out(info, DZ_CSR, DZ_CLR);
+ while ((tmp = dz_in(info,DZ_CSR)) & DZ_CLR) ;
+ wbflush();
+
+ /* enable scanning */
+ dz_out(info, DZ_CSR, DZ_MSE);
+#endif
+ /* order matters here... the trick is that flags
+ is updated... in request_irq - to immediatedly obliterate
+ it is unwise. */
restore_flags(flags);
+
+ if (request_irq (SERIAL, dz_interrupt, SA_INTERRUPT, "DZ", lines[0]))
+ panic ("Unable to register DZ interrupt\n");
+
return 0;
}
#ifdef CONFIG_SERIAL_CONSOLE
+static void dz_console_put_char (unsigned char ch)
+{
+ long flags;
+ int loops = 1000;
+ unsigned short tmp = ch;
+ /* this code sends stuff out to serial device - spinning its
+ wheels and waiting. */
+
+ /* force the issue - point it at lines[3]*/
+
+ dz_console=&multi[CONSOLE_LINE];
+
+ save_flags(flags);
+ cli();
+
+
+ /* spin our wheels */
+ while (((dz_in(dz_console,DZ_TCR) & DZ_TRDY) != DZ_TRDY) && loops--)
+ ;
+
+ /* Actually transmit the character. */
+ dz_out (dz_console, DZ_TDR, tmp);
+
+ restore_flags(flags);
+}
/*
* -------------------------------------------------------------------
* dz_console_print ()
@@ -1350,15 +1456,19 @@
* dz_console_print is registered for printk.
* -------------------------------------------------------------------
*/
+
static void dz_console_print (struct console *cons, const char *str, unsigned
int count)
{
- while (count--) {
+ debug_console(str,count);
+ return;
+ /* turn off interrupts */
+
+ while (count--)
+ {
if (*str == '\n')
- dz_put_char (dz_console->tty, '\r');
- dz_put_char (dz_console->tty, *str++);
+ dz_console_put_char('\r');
+ dz_console_put_char(*str++);
}
-
- dz_start (dz_console->tty);
}
static int dz_console_wait_key(struct console *co)
@@ -1378,6 +1488,7 @@
int parity = 'n';
int cflag = CREAD | HUPCL | CLOCAL;
char *s;
+ unsigned short mask,tmp;
if (options) {
baud = simple_strtoul(options, NULL, 10);
@@ -1427,6 +1538,34 @@
}
co->cflag = cflag;
+ /* TOFIX: force to console line */
+ dz_console = &multi[CONSOLE_LINE];
+ dz_console->port = KN01_DZ11_BASE;
+ dz_console->line = CONSOLE_LINE;
+
+ dz_out(dz_console, DZ_CSR, DZ_CLR);
+ while ((tmp = dz_in(dz_console,DZ_CSR)) & DZ_CLR)
+ ;
+
+ /* enable scanning */
+ dz_out(dz_console, DZ_CSR, DZ_MSE);
+
+ /* Set up flags... */
+ dz_console->cflags = 0;
+ dz_console->cflags |= DZ_B9600;
+ dz_console->cflags |= DZ_CS8;
+ dz_console->cflags |= DZ_PARENB;
+ dz_out (dz_console, DZ_LPR, dz_console->cflags);
+
+
+ mask = 1 << dz_console->line;
+ tmp = dz_in (dz_console, DZ_TCR); /* read the TX flag */
+ if (!(tmp & mask)) {
+ tmp |= mask; /* set the TX flag */
+ dz_out (dz_console, DZ_TCR, tmp);
+ }
+
+
return 0;
}
@@ -1438,8 +1577,8 @@
dz_console_wait_key,
NULL,
dz_console_setup,
- CON_PRINTBUFFER,
- -1,
+ CON_CONSDEV | CON_PRINTBUFFER,
+ CONSOLE_LINE,
0,
NULL
};
@@ -1447,6 +1586,7 @@
__initfunc (long dz_serial_console_init(long kmem_start, long kmem_end))
{
register_console(&dz_sercons);
+
return kmem_start;
}
diff -rubN linux-2.1.121-r3000/drivers/char/dz.h
linux-2.1.121-r3000_pl8/drivers/char/dz.h
--- linux-2.1.121-r3000/drivers/char/dz.h Thu Oct 1 14:55:25 1998
+++ linux-2.1.121-r3000_pl8/drivers/char/dz.h Sat Nov 14 14:24:50 1998
@@ -94,7 +94,7 @@
#define DZ_B9600 0x0E00
#define DZ_CREAD 0x1000 /* Enable receiver */
-
+#define DZ_RXENAB 0x1000 /* enable receive char */
/*
* Addresses for the DZ registers
*/
@@ -208,7 +208,6 @@
static void do_softint (void *);
static void do_serial_hangup (void *);
static void change_speed (struct dz_serial *);
-static void dz_put_char (struct tty_struct *, unsigned char);
static void dz_flush_chars (struct tty_struct *);
static void dz_console_print (struct console *, const char *, unsigned int);
static void dz_flush_buffer (struct tty_struct *);
diff -rubN linux-2.1.121-r3000/drivers/net/declance.c
linux-2.1.121-r3000_pl8/drivers/net/declance.c
--- linux-2.1.121-r3000/drivers/net/declance.c Thu Oct 1 14:55:26 1998
+++ linux-2.1.121-r3000_pl8/drivers/net/declance.c Sat Nov 14 14:24:51 1998
@@ -963,6 +963,7 @@
return 0;
}
+#ifdef CONFIG_TC
static int tc_probe(struct device *dev, unsigned char *esar_base)
{
extern slot_info tc_bus[MAX_SLOT];
@@ -984,6 +985,7 @@
}
return 0;
}
+#endif
/* Find all the lance cards on the system and initialize them */
__initfunc(int dec_lance_probe (struct device *dev))
diff -rubN linux-2.1.121-r3000/include/asm-mips/system.h
linux-2.1.121-r3000_pl8/include/asm-mips/system.h
--- linux-2.1.121-r3000/include/asm-mips/system.h Sat Oct 3 13:57:47 1998
+++ linux-2.1.121-r3000_pl8/include/asm-mips/system.h Sat Nov 14 14:24:51 1998
@@ -92,14 +92,20 @@
__asm__ __volatile__(
".set\tpush\n\t"
".set\tnoreorder\n\t"
+ "mfc0\t$8,$12\n\t"
+ "ori\t$9,$0,0xff00\n\t"
+ "and\t$8,$9\n\t"
+ "nor\t$9,$0,$9\n\t"
+ "and\t%0,$9\n\t"
+ "or\t%0,$8\n\t"
"mtc0\t%0,$12\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
".set\tpop\n\t"
- : /* no output */
+ :
: "r" (flags)
- : "memory");
+ : "$8", "$9", "memory");
}
/*
|