Import 1.1.781.1.78
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:49 +0000 (23 15:09 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:49 +0000 (23 15:09 -0500)
89 files changed:
CREDITS
Makefile
arch/alpha/Makefile
arch/alpha/config.in
arch/alpha/kernel/entry.S
arch/alpha/lib/Makefile[new file with mode: 0644]
arch/alpha/lib/divide.S[new file with mode: 0644]
arch/i386/kernel/Makefile
arch/i386/kernel/bios32.c
arch/i386/kernel/ioport.c
arch/i386/math-emu/Makefile
arch/sparc/kernel/Makefile
arch/sparc/kernel/entry.S
arch/sparc/kernel/head.S
arch/sparc/kernel/irq.c[new file with mode: 0644]
drivers/block/cdu31a.c
drivers/block/hd.c
drivers/block/ide.c
drivers/block/mcd.c
drivers/block/sbpcd.c
drivers/char/Makefile
drivers/char/lp.c
drivers/char/serial.c
drivers/char/vesa_blank.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/Makefile
drivers/net/apricot.c
drivers/net/at1700.c
drivers/net/atp.c
drivers/net/depca.c
drivers/net/e2100.c
drivers/net/eexpress.c
drivers/net/ewrk3.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/lance.c
drivers/net/ne.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/plip.c
drivers/net/sk_g16.c
drivers/net/skeleton.c
drivers/net/slip.h
drivers/net/smc-ultra.c
drivers/net/wd.c
drivers/scsi/Makefile
drivers/scsi/aha152x.c
drivers/scsi/aha1542.c
drivers/scsi/aha1740.c
drivers/scsi/buslogic.c
drivers/scsi/eata.c
drivers/scsi/fdomain.c
drivers/scsi/in2000.c
drivers/scsi/qlogic.c
drivers/scsi/u14-34f.c
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.h
drivers/scsi/wd7000.c
fs/Makefile
fs/isofs/Makefile
fs/isofs/inode.c
fs/minix/Makefile
fs/msdos/Makefile
fs/nfs/Makefile
fs/proc/array.c
fs/proc/net.c
fs/sysv/Makefile
fs/sysv/inode.c
fs/umsdos/Makefile
fs/xiafs/Makefile
include/asm-alpha/processor.h
include/asm-i386/string.h
include/asm-sparc/head.h
include/asm-sparc/processor.h
include/linux/ioport.h
include/linux/minix_fs.h
include/linux/minix_fs_i.h
include/linux/pci.h
include/linux/string.h
kernel/ksyms.c
kernel/signal.c
mm/kmalloc.c
net/inet/af_inet.c
net/inet/dev_mcast.c
net/inet/ip.c
net/inet/tcp.c

index c094cf8..b84595d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -478,6+478,10 @@ N: Kai M"akisara
 E: Kai.Makisara@vtt.fi
 D: SCSI Tape Driver
 
+N: Peter MacDonald
+D: SLS distribution
+D: Initial implementation of VC's, pty's and select()
+
 N: James B. MacLean
 E: jmaclean@fox.nstn.ns.ca
 D: Coordinator of DOSEMU releases
index 925ba42..3f8781c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6+1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 77
+SUBLEVEL = 78
 
 ARCH = i386
 
@@ -193,7+193,7 @@ net: dummy
        $(MAKE) linuxsubdirs SUBDIRS=net
 
 modules: dummy
-       @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i modules; done
+       @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i CFLAGS="$(CFLAGS) -DMODULE" modules; done
        
 
 clean: archclean
index 2c24cfa..5044bad 100644 (file)
@@ -13,8+13,9 @@ CFLAGS := $(CFLAGS) -mno-fp-regs
 
 HEAD := arch/alpha/kernel/head.o
 
-SUBDIRS := $(SUBDIRS) arch/alpha/kernel
+SUBDIRS := $(SUBDIRS) arch/alpha/kernel arch/alpha/lib
 ARCHIVES := arch/alpha/kernel/kernel.o $(ARCHIVES)
+LIBS := arch/alpha/lib/lib.a $(LIBS)
 
 archclean:
 
index 701c0d5..eb1e7ce 100644 (file)
@@ -14,7+14,7 @@ bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
 
 if [ "$CONFIG_NET" = "y" ]; then
 comment 'Networking options'
-bool 'TCP/IP networking' CONFIG_INET y
+bool 'TCP/IP networking' CONFIG_INET n
 if [ "$CONFIG_INET" "=" "y" ]; then
 bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n
 bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
@@ -32,7+32,7 @@ fi
 
 comment 'SCSI support'
 
-bool 'SCSI support?' CONFIG_SCSI y
+bool 'SCSI support?' CONFIG_SCSI n
 
 if [ "$CONFIG_SCSI" = "n" ]; then
 
@@ -109,7+109,7 @@ if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
        fi
        bool '3c509/3c579 support' CONFIG_EL3 y
 fi
-bool 'Other ISA cards' CONFIG_NET_ISA y
+bool 'Other ISA cards' CONFIG_NET_ISA n
 if [ "$CONFIG_NET_ISA" = "y" ]; then
        bool 'Cabletron E21xx support' CONFIG_E2100 n
        bool 'DEPCA support' CONFIG_DEPCA y
index 1a41850..27ec1ee 100644 (file)
@@ -7,7+7,7 @@
 #include <asm/system.h>
 
 #define halt   .long PAL_halt
-#define rti    .long RAL_rti
+#define rti    .long PAL_rti
 
 .text
        .set noat
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
new file mode 100644 (file)
index 0000000..fa2418b
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# Makefile for alpha-specific library files..
+#
+
+.c.s:
+       $(CC) $(CFLAGS) -S $<
+.s.o:
+       $(AS) -c -o $*.o $<
+.c.o:
+       $(CC) $(CFLAGS) -c $<
+
+OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o
+
+lib.a: $(OBJS)
+       $(AR) rcs lib.a $(OBJS)
+       sync
+
+__divqu.o: divide.S
+       $(CC) -DDIV -c -o __divqu.o divide.S
+
+__remqu.o: divide.S
+       $(CC) -DREM -c -o __remqu.o divide.S
+
+__divlu.o: divide.S
+       $(CC) -DDIV -DINTSIZE -c -o __divlu.o divide.S
+
+__remlu.o: divide.S
+       $(CC) -DREM -DINTSIZE -c -o __remlu.o divide.S
+
+dep:
+       $(CPP) -M *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
diff --git a/arch/alpha/lib/divide.S b/arch/alpha/lib/divide.S
new file mode 100644 (file)
index 0000000..96c4fee
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * arch/alpha/lib/divide.S
+ *
+ * (C) 1995 Linus Torvalds
+ *
+ * Alpha division..
+ */
+
+/*
+ * The alpha chip doesn't provide hardware division, so we have to do it
+ * by hand.  The compiler expects the functions
+ *
+ *     __divqu: 64-bit unsigned long divide
+ *     __remqu: 64-bit unsigned long reminder
+ *     __divqs/__remqs: signed 64-bit
+ *     __divlu/__remlu: unsigned 32-bit
+ *     __divls/__remls: signed 32-bit
+ *
+ * These are not normal C functions: instead of the normal
+ * calling sequence, these expect their arguments in registers
+ * $24 and $25, and return the result in $27. Register $28 may
+ * be clobbered (assembly temprary), anything else must be saved. 
+ *
+ * In short: painful. I'm not going to try to be clever about it:
+ * let somebody else optimize it if they will.
+ */
+
+/*
+ * My temporaries:
+ *     $0 - current bit
+ *     $1 - shifted divisor
+ *     $2 - rest
+ *     $3 - compare status
+ *
+ *     $23 - return address
+ *     $24 - dividend
+ *     $25 - divisor
+ */
+
+/*
+ * Select function type and registers
+ */
+#ifdef DIV
+#define func(x) __div##x
+#define modulus $2
+#define quotient $27
+#else
+#define func(x) __rem##x
+#define modulus $27
+#define quotient $2
+#endif
+
+/*
+ * For 32-bit operations, we need to extend to 64-bit
+ */
+#ifdef INTSIZE
+#define function func(lu)
+#define LONGIFY(x) zapnot x,15,x
+#else
+#define function func(qu)
+#define LONGIFY(x)
+#endif
+
+.globl function
+.ent   function
+function:
+       lda     $30,-32($30)
+       stq     $0, 0($30)
+       stq     $1, 8($30)
+       stq     $2,16($30)
+       stq     $3,24($30)
+       bis     $25,$25,$1
+       bis     $24,$24,modulus
+       bis     $31,$31,quotient
+       LONGIFY($1)
+       LONGIFY(modulus)
+       beq     $1, 9f                  /* div by zero */
+       bis     $31,1,$0
+       blt     $1, 2f                  /* high bit set */
+1:     cmpult  modulus,$1,$3
+       bne     $3,3f
+       addq    $1,$1,$1
+       addq    $0,$0,$0
+       bge     $1,1b
+2:     cmpult  modulus,$1,$3
+       bne     $3,3f
+       subq    modulus,$1,modulus
+       addq    $0,quotient,quotient
+3:     srl     $0,1,$0
+       srl     $1,1,$1
+       bne     $0,2b
+9:     ldq     $0, 0($30)
+       ldq     $1, 8($30)
+       ldq     $2, 16($30)
+       ldq     $3, 32($30)
+       lda     $30,32($30)
+       ret     $31,($23),1
+       .end    function
index a1c705a..6caf1c7 100644 (file)
@@ -34,6+34,8 @@ kernel.o: $(OBJS)
 dep:
        $(CPP) -M *.c > .depend
 
+modules:
+
 dummy:
 
 #
index 9c288da..159d498 100644 (file)
@@ -451,7+451,7 @@ int revision_decode(unsigned char bus,unsigned char dev_fn)
        unsigned char           revision;
                        pcibios_read_config_byte(
                        bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &revision);
-               return revision;
+               return (int) revision;
 }
 
 
@@ -484,7+484,8 @@ int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor)
                        bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
                for (i=0;i<PCI_DEVICE_NUM;i++) 
                        if ((device==pci_device[i].device_id) 
-                        && (vendor==pci_device[i].vendor_id)) break;
+                        && (vendor==pci_device[i].vendor_id)) return i;
+               printk("Device id=%x ",device);
                return i;
 }
 
@@ -503,6+504,7 @@ int vendor_decode(unsigned char bus,unsigned char dev_fn)
                        bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
                for (i=0;i<PCI_VENDOR_NUM;i++) 
                        if (vendor==pci_vendor[i].vendor_id) return i;
+               printk("Vendor id=%x ",vendor);
                return i;
 }
 
index 11682b0..251a1ee 100644 (file)
 #include <linux/types.h>
 #include <linux/ioport.h>
 
-static unsigned long ioport_registrar[IO_BITMAP_SIZE] = {0, /* ... */};
-#define IOPORTNAMES_NUM 32
-#define IOPORTNAMES_LEN 26
-struct { int from;
-        int num;       
-        int flags;
-        char name[IOPORTNAMES_LEN];
-       } ioportnames[IOPORTNAMES_NUM];
+#define IOTABLE_SIZE 32
+#define STR(x) #x
+
+typedef struct resource_entry_t {
+       u_long from, num;
+       const char *name;
+       struct resource_entry_t *next;
+} resource_entry_t;
+
+static resource_entry_t iolist = { 0, 0, "", NULL };
+
+static resource_entry_t iotable[IOTABLE_SIZE];
 
 #define _IODEBUG
 
@@ -84,52+88,20 @@ asmlinkage void set_bitmap(unsigned long *bitmap, short base, short extent, int
        }
 }
 
-/* Check for set bits in BITMAP starting at BASE, going to EXTENT. */
-asmlinkage int check_bitmap(unsigned long *bitmap, short base, short extent)
-{
-       int mask;
-       unsigned long *bitmap_base = bitmap + (base >> 5);
-       unsigned short low_index = base & 0x1f;
-       int length = low_index + extent;
-
-       if (low_index != 0) {
-               mask = (~0 << low_index);
-               if (length < 32)
-                               mask &= ~(~0 << length);
-               if (*bitmap_base++ & mask)
-                       return 1;
-               length -= 32;
-       }
-       while (length >= 32) {
-               if (*bitmap_base++ != 0)
-                       return 1;
-               length -= 32;
-       }
-
-       if (length > 0) {
-               mask = ~(~0 << length);
-               if (*bitmap_base++ & mask)
-                       return 1;
-       }
-       return 0;
-}
-
 /*
  * This generates the report for /proc/ioports
  */
 int get_ioport_list(char *buf)
-{       int i=0,len=0;
-       while(i<IOPORTNAMES_LEN && len<4000)
-       {       if(ioportnames[i].flags)
-                       len+=sprintf(buf+len,"%04x-%04x : %s\n",
-                               ioportnames[i].from,
-                               ioportnames[i].from+ioportnames[i].num-1,
-                               ioportnames[i].name);
-               i++;
-       }
-        if(len>=4000) 
-               len+=sprintf(buf+len,"4k-Limit reached!\n");
-        return len;
+{
+       resource_entry_t *p;
+       int len = 0;
+
+       for (p = iolist.next; (p) && (len < 4000); p = p->next)
+               len += sprintf(buf+len, "%04lx-%04lx : %s\n",
+                          p->from, p->from+p->num-1, p->name);
+       if (p)
+               len += sprintf(buf+len, "4K limit reached!\n");
+       return len;
 }
 
 /*
@@ -179,37+151,54 @@ asmlinkage int sys_iopl(long ebx,long ecx,long edx,
 }
 
 /*
- * This is the 'old' snarfing worker function
+ * The workhorse function: find where to put a new entry
  */
-void do_snarf_region(unsigned int from, unsigned int num)
+static resource_entry_t *find_gap(resource_entry_t *root,
+                                 u_long from, u_long num)
 {
-        if (from > IO_BITMAP_SIZE*32)
-                return;
-        if (from + num > IO_BITMAP_SIZE*32)
-                num = IO_BITMAP_SIZE*32 - from;
-        set_bitmap(ioport_registrar, from, num, 1);
-        return;
+       unsigned long flags;
+       resource_entry_t *p;
+       
+       if (from > from+num-1)
+               return NULL;
+       save_flags(flags);
+       cli();
+       for (p = root; ; p = p->next) {
+               if ((p != root) && (p->from+p->num-1 >= from)) {
+                       p = NULL;
+                       break;
+               }
+               if ((p->next == NULL) || (p->next->from > from+num-1))
+                       break;
+       }
+       restore_flags(flags);
+       return p;
 }
 
 /*
  * Call this from the device driver to register the ioport region.
  */
-void register_iomem(unsigned int from, unsigned int num, char *name)
-{      
-       int i=0;
-       while(ioportnames[i].flags && i<IOPORTNAMES_NUM)
-        i++;
-       if(i==IOPORTNAMES_NUM)
-               printk("warning:ioportname-table is full");
-       else
-       {       
-               strncpy(ioportnames[i].name,name,IOPORTNAMES_LEN);
-               ioportnames[i].name[IOPORTNAMES_LEN-1]=(char)0;
-               ioportnames[i].from=from;
-               ioportnames[i].num=num;
-               ioportnames[i].flags=1;
+void request_region(unsigned int from, unsigned int num, const char *name)
+{
+       resource_entry_t *p;
+       int i;
+
+       for (i = 0; i < IOTABLE_SIZE; i++)
+               if (iotable[i].num == 0)
+                       break;
+       if (i == IOTABLE_SIZE)
+               printk("warning: ioport table is full\n");
+       else {
+               p = find_gap(&iolist, from, num);
+               if (p == NULL)
+                       return;
+               iotable[i].name = name;
+               iotable[i].from = from;
+               iotable[i].num = num;
+               iotable[i].next = p->next;
+               p->next = &iotable[i];
+               return;
        }
-       do_snarf_region(from,num);
 }
 
 /*
@@ -217,33+206,27 @@ void register_iomem(unsigned int from, unsigned int num, char *name)
  * It can be removed when all driver call the new function.
  */
 void snarf_region(unsigned int from, unsigned int num)
-{      register_iomem(from,num,"No name given.");
-}
-
-/*
- * The worker for releasing
- */
-void do_release_region(unsigned int from, unsigned int num)
 {
-        if (from > IO_BITMAP_SIZE*32)
-                return;
-        if (from + num > IO_BITMAP_SIZE*32)
-                num = IO_BITMAP_SIZE*32 - from;
-        set_bitmap(ioport_registrar, from, num, 0);
-        return;
+       request_region(from,num,"No name given.");
 }
 
 /* 
  * Call this when the device driver is unloaded
  */
 void release_region(unsigned int from, unsigned int num)
-{      int i=0;
-       while(i<IOPORTNAMES_NUM)
-       {       if(ioportnames[i].from==from && ioportnames[i].num==num)
-                       ioportnames[i].flags=0; 
-               i++;
+{
+       resource_entry_t *p, *q;
+
+       for (p = &iolist; ; p = q) {
+               q = p->next;
+               if (q == NULL)
+                       break;
+               if ((q->from == from) && (q->num == num)) {
+                       q->num = 0;
+                       p->next = q->next;
+                       return;
+               }
        }
-       do_release_region(from,num);
 }
 
 /*
@@ -251,11+234,7 @@ void release_region(unsigned int from, unsigned int num)
  */
 int check_region(unsigned int from, unsigned int num)
 {
-       if (from > IO_BITMAP_SIZE*32)
-               return 0;
-       if (from + num > IO_BITMAP_SIZE*32)
-               num = IO_BITMAP_SIZE*32 - from;
-       return check_bitmap(ioport_registrar, from, num);
+       return (find_gap(&iolist, from, num) == NULL) ? -EBUSY : 0;
 }
 
 /* Called from init/main.c to reserve IO ports. */
@@ -264,5+243,5 @@ void reserve_setup(char *str, int *ints)
        int i;
 
        for (i = 1; i < ints[0]; i += 2)
-               register_iomem(ints[i], ints[i+1],"reserved");
+               request_region(ints[i], ints[i+1], "reserved");
 }
index 46ff0c5..2d391a9 100644 (file)
@@ -40,6+40,8 @@ dep:
 proto:
        cproto -e -DMAKING_PROTO *.c >fpu_proto.h
 
+modules:
+
 dummy:
 
 #
index 4f379fd..91afbc5 100644 (file)
 .S.o:
        $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 
-OBJS  = entry.o traps.o
+OBJS  = entry.o traps.o irq.o process.o
 
 all: kernel.o head.o
 
dissimilarity index 74%
index 3f173ee..7aa088f 100644 (file)
-/* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
- *
- * Sparc traps are so ugly, this code is going to go through a lot
- * of changes as I find out more interesting things. See head.S for
- * the trap table and how it works, this will show you how we get
- * to these routines.
- *
- * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <asm/head.h>
-
-       .text
-       .align 4
-
-/* Default trap handler */
-       .globl my_trap_handler
-my_trap_handler:
-               rd %wim, %l4
-               or %g0, 0x1, %l5
-               sll %l5, %l0, %l5
-               cmp %l4, %l5        ! are we in the invalid register?
-       
-#if 0 /* work in progress */
-               be wash_trap_win
-#endif
-
-               nop
-               or %%g0, %l3, %o0
-               call _do_hw_interrupt
-               or %%g0, %%g0, %o1
-               wr %l0, 0x20, %psr  ! re-enable traps and reset the condition codes
-               nop
-               nop
-               nop                 ! click our heels three times, "no place like home"
-               jmp %l1
-               rett %l2
-       
-/* This is cheese and only works reliably if not coming from userland. */
-       .globl fill_window_entry
-fill_window_entry:
-       wr      %g0, 0, %wim            ! let us into the invalid window
-                                       ! without inducing another trap
-       restore
-       nop
-       nop                             ! no guarentees until 3 insns later
-       restore
-       restore %g0, 1, %l1
-       rd      %psr, %l0
-       sll     %l1, %l0, %l0
-       wr      %l0, 0, %wim
-       save    %g0, %g0, %g0
-
-/* load up the window */
-       ldd     [%sp], %l0
-       ldd     [%sp + 8], %l2
-       ldd     [%sp + 16], %l4
-       ldd     [%sp + 24], %l6
-       ldd     [%sp + 32], %i0
-       ldd     [%sp + 40], %i2
-       ldd     [%sp + 48], %i4
-       ldd     [%sp + 56], %i6
-
-       save    %g0, %g0, %g0
-       save    %g0, %g0, %g0
-       jmp     %l1
-       rett    %l2
-
-/* Cheese number two, give this a bad stack pointer and get scared. */
-       .globl spill_window_entry
-spill_window_entry:
-       save    %g0, %g0, %g0  ! save into next 'valid' window
-       std     %l0, [%sp]     ! acquire some scratch registers
-       rd      %psr, %l0
-       or      %g0, 0x1, %l1
-       sll     %l1, %l0, %l0
-       wr      %l0, 0, %wim   ! make window we are saving the 'invalid' one
-       std     %l2, [%sp + 8]
-       std     %l4, [%sp + 16]
-       std     %l6, [%sp + 24]
-       std     %i0, [%sp + 32]
-       std     %i2, [%sp + 40]
-       std     %i4, [%sp + 48]
-       std     %i6, [%sp + 56]
-       restore                ! restore back into the window we want to use
-       jmp     %l1
-       rett    %l2            ! return from spill handler
-
-
-/* This is where most generic traps enter, the registers should be:
-       %l0 == %psr
-       %l1 == %pc
-       %l2 == %npc
-       %l4 == trap_type
-       %l7 == trap_handler
-*/
-
-trap_entry:
-       srl     %l0, 0x6, %l5   ! shift over to previous priv bit
-       andcc   %l5, 0x1, %g0   ! 1 == from kernel 0 == from user
-       bz      2f
-       nop                     ! we dont handle users yet ;-(
-       
-       or      %g0, 0x1, %l5
-       sll     %l5, %l0, %l5   ! a trick, only least 5 bits are
-                               ! significant in a register shift
-                               ! count.
-       rd      %wim, %l6
-       andcc   %l6, %l5, %g0   ! if (((1<<CWP)&(%wim))==1) we are
-                               ! in an 'invalid' window
-       bz,a    3f
-       sub     %fp, C_STACK+80, %sp ! cool, just set stack and go
-                                    ! this window is valid to use
-       
-/* we aparently need to clean the trap window, inline this for speed */        
-       or      %g0, %g7, %l7   ! set up g6 and g7 for scratch
-       or      %g0, %g6, %l6   
-       
-       save    %g0, %g0, %g0   ! enter next window after the invalid one
-       std     %l0, [%sp]      ! and store it on the stack for later
-       std     %l2, [%sp + 8]  ! retrieval
-       std     %l4, [%sp + 16]
-       std     %l6, [%sp + 24]
-       std     %i0, [%sp + 32]
-       std     %i2, [%sp + 40]
-       std     %i4, [%sp + 48]
-       std     %i6, [%sp + 56]
-
-       rd      %psr, %g7       ! read the current window pointer
-       or      %g0, 0x1, %g6   ! and mask it over into the %wim
-       sll     %g6, %g7, %g6   ! value
-       wr      %g6, 0, %wim    ! make this window the now 'invalid' one
-       and     %g6, 31, %g6
-       restore                 ! re-enter the trap window, it is ok now
-
-       or      %g0, %l6, %g6   ! bring back in the old temporaries
-       or      %g0, %l7, %g7   ! to the locals they were in
-
-       b       3f
-       sub     %fp, C_STACK+80, %sp ! fix stack pointer
-
-       
-/* for now if we get a from-user trap you lose... */
-
-       .data
-       .align 4
-
-tfu_youlose:   .asciz "trap from userland, you lose...\n"
-       
-       .align 4
-       .text
-
-2:     
-       sethi   %hi(tfu_youlose), %o0
-       sethi   %hi(prom_printf), %o1
-       ld      [%o1 + %lo(prom_printf)], %o1
-       call    %o1     
-       or      %o0, %lo(tfu_youlose), %o0
-       
-       sethi   %hi(prom_halt), %o1
-       ld      [%o1 + %lo(prom_halt)], %o1
-       call    %o1                             ! its over
-       nop
-       
-/* nop and just return, here is where I would jump to the
- * appropriate handler.
- */
-
-       jmp %1
-       rett %l2
-       nop
+/* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
+ *
+ * Sparc traps are so ugly, this code is going to go through a lot
+ * of changes as I find out more interesting things. See head.S for
+ * the trap table and how it works, this will show you how we get
+ * to these routines.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/head.h>
+
+/* Here are macros for routines we do often, this allows me to inline this
+ * without making the code look real ugly. Well, the macro looks ugly too but
+ * makes the trap entry code easier to understand.
+ */
+
+/* I really don't like synthetic instructions. So I avoid them like the
+ * plague.
+ */
+
+/* Note that when I have to write a window out, and it is a user's window, I
+ * have to check that the pages of memory that I am going to throw the window(s)
+ * onto are valid and are writable by the user (this is %sp to %sp + 64) before
+ * I start dumping stuff there. We always assume that kernels stack is ok.
+ *
+ * If we have to save a kernel window, only one branch is taken. This should
+ * make trap handlers quicker in this scenario.
+ *
+ * Once 'current' is loaded into %g6, it stays there until we leave
+ * this macro.
+ *
+ * XXX must do some checking on the assumption that kernel stack is always ok
+ */
+
+/* I will document how this works real soon. TODO */
+
+#define TRAP_WIN_CLEAN \
+       or      %g0, %g5, %l5;    /* we need the globals to do our work */ \
+       or      %g0, %g6, %l6;    /* and %l0 to %l4 are loaded with important */ \
+       or      %g0, %g7, %l7;    /* information like the psr and pc's to return to */ \
+       sethi   %hi(_current), %g6; \
+       ld      [%g6 + %lo(_current)], %g6; \
+       ld      [%g6 + THREAD_UWINDOWS], %g7; /* how many user wins are active? */ \
+       subcc   %g7, 0x0, %g0
+       bne     2f;                            /* If there are any, branch. */ \
+       save    %g0, %g0, %g0;                 /* Save into that window either way. */ \
+       std     %l0, [%sp];                    /* If above shows only kernel windows */ \
+1:     std     %l2, [%sp + 0x8];              /* then we get here. */ \
+       std     %l4, [%sp + 0x10]; \
+       std     %l6, [%sp + 0x18]; \
+       std     %i0, [%sp + 0x20]; \
+       std     %i2, [%sp + 0x28]; \
+       std     %i4, [%sp + 0x30]; \
+       std     %i6, [%sp + 0x38]; \
+       or      %g0, 0x1, %g5; \
+       rd      %psr, %g7; \
+       sll     %g5, %g7, %g5; \
+       wr      %g5, 0x0, %wim;                 /* update %wim to 'now' invalid */ \
+       and     %g7, 0x1f, %g7; \
+       st      %g7, [%g6 + THREAD_WIM];        /* save 'this' threads mask */ \
+       restore %g0, %g0, %g0; \
+       or      %g0, %l5, %g5;                  /* restore the globals we used */ \
+       or      %g0, %l6, %g6; \
+       b       8f;                             /* we are done */ \
+       or      %g0, %l7, %g7; \
+2:     sub     %g7, 0x1, %g7; \
+       st      %g7, [%g6 + THREAD_UWINDOWS];   /* There are user windows if we */ \
+       andcc   %sp, 0x7, %g0;                  /* get here. Check for stack alignment. */ \
+       bne     5f;                             /* Stack is unaligned, yuck. */ \
+       sra     %sp, 0x1e, %g7;                 /* This stuff checks to see if top 3-bits */ \
+       subcc   %g7, 0x0, %g0;                  /* of stack pointer address are ok. */ \
+       be,a    3f; \
+       andn    %sp, 0xfff, %g7; \
+       subcc   %g7, -1, %g0; \
+       bne     5f;                             /* bad stack pointer, ugh */ \
+       andn    %sp, 0xfff, %g7; \
+3:     lda     [%g7] ASI_PTE, %g7;             /* Ok, user stack is a valid address */ \
+       srl     %g7, 0x1d, %g7; \
+       subcc   %g7, 0x6, %g0;                  /* Can the user write to it? */ \
+       bne     5f; \
+       and     %sp, 0xfff, %g7; \
+       subcc   %g7, 0xfc1, %g0;                /* Is our save area on one page? */ \
+       bl,a    1b; \
+       std     %l0, [%sp]; \
+       add     %sp, 0x38, %g5;                 /* Nope, have to check both pages */ \
+       sra     %g5, 0x1e, %g7; \
+       subcc   %g7, 0x0, %g0; \
+       be,a    4f; \
+       andn    %g5, 0xfff, %g7; \
+       subcc   %g7, -1, %g0; \
+       bne     5f; \
+       andn    %g5, 0xfff, %g7; \
+4:     lda     [%g7] ASI_PTE, %g7;             /* Stack space in 2nd page is valid */ \
+       srl     %g7, 0x1d, %g7; \
+       subcc   %g7, 0x6, %g0;                  /* Can user write here too? */ \
+       be,a    1b; \
+       std     %l0, [%sp]; \
+5:     ld      [%g6 + THREAD_UWINDOWS], %g7;   /* This is due to either bad page perms */ \
+       add     %g6, THREAD_REG_WINDOW, %g5;    /* for the users stack area, or the stack */ \
+6:     std     %l0, [%g5];                     /* pointer is misaligned. See above. */ \
+       std     %l2, [%g5 + 0x8]; \
+       std     %l4, [%g5 + 0x10]; \
+       std     %l6, [%g5 + 0x18]; \
+       std     %i0, [%g5 + 0x20]; \
+       std     %i2, [%g5 + 0x28]; \
+       std     %i4, [%g5 + 0x30]; \
+       std     %i6, [%g5 + 0x38]; \
+       subcc   %g7, 0x1, %g7; \
+       bge,a   6b;                             /* while(uwindows>=0) { write_win(); */ \
+       save    %g5, 0x40, %g5;                 /*     uwindows--; } */ \
+       st      %sp, [%g6 + THREAD_USP]; \
+       or      %g0, 0x1, %g5; \
+       rd      %psr, %g7; \
+       sll     %g5, %g7, %g5; \
+       wr      %g5, 0x0, %wim; \
+       and     %g7, 0x1f, %g7; \
+       st      %g7, [%g6 + THREAD_WIM];        /* Update thread_struct fields */ \
+       ld      [%g6 + THREAD_UWINDOWS], %g7; \
+       add     %g7, 0x1, %g5; \
+       st      %g5, [%g6 + THREAD_W_SAVED]; \
+       st      %g0, [%g6 + THREAD_UWINDOWS]; \
+7:     subcc   %g7, 0x1, %g7;                  /* Restore back to where we started. */ \
+       bge     7b; \
+       restore %g0, %g0, %g0; \
+       or      %g0, %l5, %g5;                  /* Restore the globals. */ \
+       or      %g0, %l6, %g6; \
+       or      %g0, %l7, %g7; \
+8:                                              /* We are done when we get here. */ \
+
+
+/* As if the last macro wasn't enough, we have to go through a very similar routine
+ * upon entry to most traps and interrupts. This is save away the current window
+ * if it is the trap window, clean it, and adjust the stack for the handler c-code
+ * to work.
+ */
+
+#define ENTER_TRAP \
+       rd      %wim, %l4; \
+       or      %g0, 0x1, %l5; \
+       sll     %l5, %l0, %l5; \
+       andcc   %l0, 0x40, %g0; \
+       bz      1f; \
+       andcc   %l4, %l5, %g0; \
+       bz,a    3f; \
+       sub     %fp, 0xb0, %sp; \
+       TRAP_WIN_CLEAN \
+       b       3f; \
+       sub     %fp, 0xb0, %sp; \
+1:     sethi   %hi(_current), %l6; \
+       ld      [%l6 + %lo(_current)], %l6; \
+       ld      [%l6 + THREAD_WIM], %l5; \
+       and     %l0, 0x1f, %l4; \
+       cmp     %l5, %l3; \
+       ble,a   4f; \
+       sethi   %hi(_nwindowsm1), %l4; \
+       sub     %l5, %l3, %l3; \
+       b       5f; \
+       sub     %l3, 0x1, %l5; \
+4:     ld      [%l4 + %lo(_nwindowsm1)], %l4; \
+       sub     %l4, %l3, %l4; \
+       add     %l5, %l4, %l5; \
+5:     st      %l5, [%l6 + THREAD_UWINDOWS]; \
+       bz,a    2f; \
+       sethi   %hi(TASK_SIZE-176), %l5; \
+       TRAP_WIN_CLEAN; \
+       sethi   %hi(_current), %l6; \
+       ld      [%l6 + %lo(_current)], %l6; \
+       sethi   %hi(TASK_SIZE-176), %l5; \
+2:     or      %l5, %lo(TASK_SIZE-176), %l5; \
+       add     %l6, %l5, %sp; \
+3: \
+
+#define ENTER_IRQ \
+       rd      %wim, %l4; \
+       or      %g0, 0x1, %l5; \
+       sll     %l5, %l0, %l5; \
+       andcc   %l0, 0x40, %g0; \
+       bz      1f; \
+       andcc   %l4, %l5, %g0; \
+       bz,a    0f; \
+       sethi   %hi(_eintstack), %l7; \
+       TRAP_WIN_CLEAN \
+       sethi   %hi(_eintstack), %l7; \
+0:     cmp     %fp, %l7; \
+       bge,a   3f; \
+       sub     %l7, 0xb0, %sp; \
+       b       3f; \
+       sub     %fp, 0xb0, %sp; \
+1:     sethi   %hi(_current), %l6; \
+       ld      [%l6 + %lo(_current)], %l6; \
+       ld      [%l6 + PCB_WIM], %l5; \
+       and     %l0, 0x1f, %l7; \
+       cmp     %l5, %l7; \
+       ble,a   4f; \
+       sethi   %hi(_nwindowsm1), %l4; \
+       sub     %l5, %l7, %l7; \
+       b       5f; \
+       sub     %l7, 0x1, %l5; \
+4:     ld      [%l4 + %lo(_nwindowsm1)], %l4; \
+       sub     %l4, %l7, %l4; \
+       add     %l5, %l4, %l5; \
+5:     st      %l5, [%l6 + THREAD_UWINDOWS]; \
+       bz,a    2f; \
+       sethi   %hi(_eintstack), %l7; \
+       TRAP_WIN_CLEAN; \
+       sethi   %hi(_eintstack), %l7; \
+2: \
+       sub     %l7, 0xb0, %sp; \
+3: \
+
+       .text
+       .align 4
+
+/* Default trap handler */
+       .globl my_trap_handler
+my_trap_handler:
+               rd %wim, %l4
+               or %g0, 0x1, %l5
+               sll %l5, %l0, %l5
+               cmp %l4, %l5        ! are we in the invalid window?
+       
+               TRAP_WIN_CLEAN
+
+               nop
+               or %%g0, %l3, %o0
+               call _do_hw_interrupt
+               or %%g0, %%g0, %o1
+               wr %l0, 0x20, %psr  ! re-enable traps and reset the condition codes
+               nop
+               nop
+               nop                 ! click our heels three times, "no place like home"
+               jmp %l1
+               rett %l2
+       
+/* This routine is optimized for kernel window fills. User fills take about two
+ * or three extra jumps on the average. We'll see how this works out.
+ */
+
+/* Don't use local labels, or if you do be REAL CAREFUL. TRAP_WIN_CLEAN is
+ * full of them! If you think this routine is hairy, window spills are worse,
+ * see below.
+ */
+
+       .globl fill_window_entry
+fill_window_entry:
+       andcc   %l0, 0x40, %g0          ! see if this is a user window fill
+       bz,a    fill_from_user
+       nop
+
+       TRAP_WIN_CLEAN                  /* danger, danger... */
+       wr      %l0, 0x0, %psr  
+       nop
+       jmp     %l1
+       rett    %l2
+
+fill_from_user:
+       sethi   %hi(_current), %l6
+       ld      [%l6 + %lo(_current)], %l6
+       ld      [%l6 + THREAD_WIM], %l5
+       and     %l0, 0x1f, %l3
+
+/* I don't know whats worse, the extra comparison here, or an extra load
+ * from a lookup table, we'll see.
+ */
+       cmp     %l5, %l3
+       ble,a   1f
+       sethi   %hi(_nwindowsm1), %l4
+       sub     %l5, %l3, %l3
+       b       2f
+       sub     %l3, 0x1, %l5
+1:     ld      [%l4 + %lo(_nwindowsm1)], %l4
+       sub     %l4, %l3, %l4
+       add     %l5, %l4, %l5
+2:     st      %l5, [%l6 + THREAD_UWINDOWS]
+
+       TRAP_WIN_CLEAN             /* danger, danger... */
+       sethi   %hi(_current), %l6
+       ld      [%l6 + %lo(_current)], %l6
+       ld      [%l6 + THREAD_KSP], %sp
+       and     %l0, 0x1f, %l3
+       sethi   %hi(lnx_winmask), %l6
+       or      %l6, %lo(lnx_winmask), %l6
+       ldub    [%l6 + %l3], %l5
+       b       back_to_userland_safety         ! may need a sched()
+       rd      %wim, %l4
+
+/* A window spill has occurred.  This presents a weird situation, a restore
+ * was attempted and a trap occurred. Therefore the restore attempt had no
+ * effect on window movement and the trap saved, which means it went in the
+ * other direction. :-( We are in a trap window which is two restores away
+ * from the window we want to un-invalidate sorta speak and three away from
+ * the one which will become invalid after this routine. There are probably
+ * bugs already this routine. Bugs suck.
+ */
+
+/* This is a very complicated and hairy routine, don't expect to understand
+ * it the first time. :>
+ */
+
+       .globl spill_window_entry
+spill_window_entry:
+       wr      %g0, 0, %wim            ! Can not enter invalid register without this.
+       andcc   %l0, 0x40, %g0          ! From user?
+       restore                         ! restore to where trap occurred
+       bz      spill_from_user
+       restore                         ! enter invalid register, whee...
+       restore %g0, 0x1, %l1           ! enter one-past invalid register
+       rd      %psr, %l0               ! this is the window we need to save
+       and     %l0, 0x1f, %l0
+       sll     %l1, %l0, %l1
+       wr      %l1, 0x0, %wim
+       sethi   %hi(_current), %l1
+       ld      [%l1 + %lo(_current)], %l1
+       st      %l0, [%l1 + THREAD_WIM]
+       save    %g0, %g0, %g0           ! back to invalid register
+       ldd     %l0, [%sp]              ! load the window from stack
+       ldd     %l2, [%sp + 8]
+       ldd     %l4, [%sp + 16]
+       ldd     %l6, [%sp + 24]
+       ldd     %i0, [%sp + 32]
+       ldd     %i2, [%sp + 40]
+       ldd     %i4, [%sp + 48]
+       ldd     %i6, [%sp + 56]
+       save    %g0, %g0, %g0           ! to window where trap happened
+       save    %g0, %g0, %g0           ! back to trap window, so rett works
+       wr      %l0, 0x0, %psr          ! load condition codes
+       nop
+       jmp     %l1
+       rett    %l2                     ! are you as confused as I am?
+
+spill_from_user:
+       andcc   %sp, 0x7, %g0           ! check for alignment of user stack
+       bne     spill_bad_stack
+       sra     %sp, 0x1e, %l7
+       cmp     %l7, 0x0
+       be,a    1f
+       andn    %sp, 0xfff, %l7
+       cmp     %l7, -1
+       bne     spill_bad_stack
+       andn    %sp, 0xfff, %l7
+1:     lda     [%l7] ASI_PTE, %l7
+       srl     %l7, 0x1d, %l7
+       andn    %l7, 0x2, %l7
+       cmp     %l7, 0x4
+       bne     spill_bad_stack
+       and     %sp, 0xfff, %l7
+       cmp     %l7, 0xfc1
+       bl,a    spill_stack_ok
+       restore %g0, 1, %l1
+       add     %sp, 0x38, %l5
+       sra     %sp, 0x1e, %l7
+       cmp     %l7, 0x0
+       be,a    1f
+       andn    %sp, 0xfff, %l7
+       cmp     %l7, -1
+       bne     spill_bad_stack
+       andn    %sp, 0xfff, %l7
+1:     lda     [%l7] ASI_PTE, %l7
+       srl     %l7, 0x1d, %l7
+       andn    %l7, 0x2, %l7
+       cmp     %l7, 0x4
+       be,a    spill_stack_ok
+       restore %g0, 0x1, %l1
+
+spill_bad_stack:
+       save    %g0, %g0, %g0                   ! save to where restore happened
+       save    %g0, 0x1, %l4                   ! save is an add remember? to trap window
+       sethi   %hi(_current), %l6
+       ld      [%l6 + %lo(_current)], %l6
+       st      %l4, [%l6 + THREAD_UWINDOWS]    ! update current->tss values
+       ld      [%l6 + THREAD_WIN], %l5
+       sll     %l4, %l5, %l4
+       wr      %l4, 0x0, %wim
+       ld      [%l6 + THREAD_KSP], %sp         ! set to kernel stack pointer
+       wr      %l0, 0x20, %psr                 ! turn off traps
+       std     %l0, [%sp + C_STACK]            ! set up thread_frame on stack
+       rd      %y, %l3
+       std     %l2, [%sp + C_STACK + 0x8]
+       or      %g0, 0x6, %o0                   ! so _sparc_trap knows what to do
+       st      %g1, [%sp + C_STACK + 0x14]     ! no need to save %g0, always zero
+       or      %g0, %l0, %o1
+       std     %g2, [%sp + C_STACK + 0x18]
+       or      %g0, %l1, %o2
+       std     %g4, [%sp + C_STACK + 0x20]
+       add     %sp, C_STACK, %o3
+       std     %g6, [%sp + C_STACK + 0x28]
+       std     %i0, [%sp + C_STACK + 0x30]
+       std     %i2, [%sp + C_STACK + 0x38]
+       std     %i4, [%sp + C_STACK + 0x40]
+       call    _sparc_trap
+       std     %i6, [%sp + C_STACK + 0x48]
+       
+       ldd     [%sp + C_STACK], %l0
+       ldd     [%sp + C_STACK + 0x8], %l2
+       wr      %l3, 0, %y
+       ld      [%sp + C_STACK + 0x14], %g1
+       ldd     [%sp + C_STACK + 0x18], %g2
+       ldd     [%sp + C_STACK + 0x20], %g4
+       ldd     [%sp + C_STACK + 0x28], %g6
+       ldd     [%sp + C_STACK + 0x30], %i0
+       ldd     [%sp + C_STACK + 0x38], %i2
+       ldd     [%sp + C_STACK + 0x40], %i4
+       wr      %l0, 0, %psr                    ! disable traps again
+       ldd     [%sp + C_STACK + 0x48], %i6
+       sethi   %hi(_current), %l6
+       ld      [%l6 + %lo(_current)], %l6
+       ld      [%l6 + THREAD_W_SAVED], %l7
+       cmp     %l7, 0x0
+       bl,a    1f
+       wr      %g0, 0x0, %wim
+       b,a     leave_trap
+
+1:     or      %g0, %g6, %l3
+       or      %g0, %l6, %g6
+       st      %g0, [%g6 + THREAD_W_SAVED]
+       restore %g0, %g0, %g0
+       restore %g0, %g0, %g0
+       restore %g0, 0x1, %l1
+       rd      %psr, %l0
+       sll     %l1, %l0, %l1
+       wr      %l1, 0x0, %wim
+       and     %l0, 0x1f, %l0
+       st      %l0, [%g6 + THREAD_WIM]
+       nop
+       save    %g0, %g0, %g0
+       ldd     [%sp], %l0                      ! load number one
+       ldd     [%sp + 0x8], %l2
+       ldd     [%sp + 0x10], %l4
+       ldd     [%sp + 0x18], %l6
+       ldd     [%sp + 0x20], %i0
+       ldd     [%sp + 0x28], %i2
+       ldd     [%sp + 0x30], %i4
+       ldd     [%sp + 0x38], %i6
+       save    %g0, %g0, %g0
+       ldd     [%sp], %l0                      ! load number two
+       ldd     [%sp + 0x8], %l2        
+       ldd     [%sp + 0x10], %l4
+       ldd     [%sp + 0x18], %l6
+       ldd     [%sp + 0x20], %i0
+       ldd     [%sp + 0x28], %i2
+       ldd     [%sp + 0x30], %i4
+       ldd     [%sp + 0x38], %i6
+       save    %g0, %g0, %g0                   ! re-enter trap window
+       wr      %l0, 0x0, %psr                  ! restore condition codes
+       or      %g0, %l3, %g6                   ! restore scratch register
+       jmp     %l1
+       rett    %l2
+
+spill_stack_ok:
+       rd      %psr, %l0
+       sll     %l1, %l0, %l1
+       wr      %l1, 0x0, %wim
+       sethi   %hi(_current), %l2
+       ld      [%l2 + %lo(_current)], %l2
+       and     %l0, 0x1f, %l0
+       st      %l0, [%l2 + THREAD_WIM]
+       save    %g0, %g0, %g0
+       ldd     [%sp], %l0                      ! only one load necessary
+       ldd     [%sp + 0x8], %l2
+       ldd     [%sp + 0x10], %l4
+       ldd     [%sp + 0x18], %l6
+       ldd     [%sp + 0x20], %i0
+       ldd     [%sp + 0x28], %i2
+       ldd     [%sp + 0x30], %i4
+       ldd     [%sp + 0x38], %i6
+       save    %g0, %g0, %g0
+       save    %g0, %g0, %g0                   ! save into trap window
+       wr      %l0, 0x0, %psr                  ! local number 0 here has cond codes
+       nop
+       jmp     %l1
+       rett    %l2
+
+/* The following two things point to window management tables. The first
+   one is used to quickly look up how many user windows there are from
+   trap-land. The second is used in a trap handler to determine if a rett
+   instruction will land us smack inside the invalid window that possibly
+   the trap was called to fix-up.
+*/
+
+/* For now these are static tables geared for a 7 window sparc. */
+
+               .data
+               .align 4
+lnx_winmask:   .byte   2, 4, 8, 16, 32, 64, 128,1  ! lnx_winmask[0..7]
+
+       
index 53285d4..69df5ba 100644 (file)
@@ -488,20+488,6 @@ _msgbufmapped:
         .word   1
 
 
-/* The following two things point to window management tables. The first
-   one is used to quickly look up how many user windows there are from
-   trap-land. The second is used in a trap handler to determine if a rett
-   instruction will land us smack inside the invalid window that possibly
-   the trap was called to fix-up.
-*/
-
-          .data
-          .skip   32                      ! alignment byte & negative indices
-lnx_uw:       .skip   32                      ! u_char uwtab[-31..31];
-lnx_winmask:  .skip   32                      ! u_char wmask[0..31];
-
-        .text
-       
 
 /* Cool, here we go. Pick up the romvec pointer in %o0 and stash it in
    %g7 and at _prom_vector_p. And also quickly check whether we are on
@@ -567,18+553,18 @@ found_v2:
 not_v2:
 
 /* Get the machine type via the mysterious romvec node operations.
  Here we can find out whether we are on a sun4 sun4c, sun4m, or
  a sun4m. The "nodes" are set up as a bunch of n-ary trees which
  you can traverse to get information about devices and such. The
  information acquisition happens via the node-ops which are defined
  in the linux_openprom.h header file. Of particular interest is the
  'nextnode(int node)' function as it does the smart thing when
  presented with a value of '0', it gives you the first node in the
  tree. These node integers probably offset into some internal prom
  pointer table the openboot has. It's completely undocumented, so
  I'm not about to go sifting through the prom address space, but may
  do so if I get suspicious enough. :-)
-*/
* Here we can find out whether we are on a sun4 sun4c, sun4m, or
* a sun4m. The "nodes" are set up as a bunch of n-ary trees which
* you can traverse to get information about devices and such. The
* information acquisition happens via the node-ops which are defined
* in the linux_openprom.h header file. Of particular interest is the
* 'nextnode(int node)' function as it does the smart thing when
* presented with a value of '0', it gives you the first node in the
* tree. These node integers probably offset into some internal prom
* pointer table the openboot has. It's completely undocumented, so
* I'm not about to go sifting through the prom address space, but may
* do so if I get suspicious enough. :-)
+ */
 
                or      %g0, %g7, %l1
                add     %l1, 0x1c, %l1          
@@ -648,10+634,10 @@ is_sun4c:                                 ! OK, this is a sun4c, yippie
 
 
 /* That was easy, now lets try to print some message on the screen.
  We don't have to worry about bad address translations when the prom
  addresses our pointers because our pointers are at 0x0-kern_size
  as the prom expects.
-*/
* We don't have to worry about bad address translations when the prom
* addresses our pointers because our pointers are at 0x0-kern_size
* as the prom expects.
+ */
 
                set     boot_msg, %o0   
                ld      [prom_printf], %o1
@@ -703,11+689,11 @@ rest_of_boot:
  */
 
 /* Uh, oh, interrupt time. This crap is real confusing. What I want to do is
  clear all interrupts, map the interrupt enable register which in effect
  enables non-maskable interrupts (or NMI's). Actuall we take no interrupts
  until we frob with the %tbr (trap base register) which the prom has set 
  to all its routines which allows some sanity during bootup.
-*/
* clear all interrupts, map the interrupt enable register which in effect
* enables non-maskable interrupts (or NMI's). Actuall we take no interrupts
* until we frob with the %tbr (trap base register) which the prom has set 
* to all its routines which allows some sanity during bootup.
+ */
 
 #if 0 /* paranoid, need to fix this routine now */
                sethi   %hi(IE_reg_addr), %l0
@@ -722,8+708,8 @@ rest_of_boot:
 #endif /* paranoid, see above */
        
 /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
  show-time!
-*/
* show-time!
+ */
 
                set     1f, %g1
                jmp     %g1
@@ -779,9+765,9 @@ rest_of_boot:
 
 
 /*
  Maybe the prom zero's out our BSS section, maybe it doesn't. I certainly 
  don't know, do you?
-*/
* Maybe the prom zero's out our BSS section, maybe it doesn't. I certainly 
* don't know, do you?
+ */
 
                set     _edata, %o0
                set     _end, %o1
@@ -831,6+817,9 @@ rest_of_boot:
                add     %g3, 0x1, %g3
                sethi   %hi(_nwindows), %g4
                st      %g3, [%g4 + %lo(_nwindows)]     ! store final value
+               sub     %g3, 0x1, %g3
+               sethi   %hi(_nwindowsm1), %g4
+               st      %g3, [%g4 + %lo(_nwindowsm1)]
 
 
 /* Here we go */
@@ -893,10+882,10 @@ halt_me:
        .align 4
 
 /*
  Fill up the prom vector, note in particular the kind first element,
  no joke. I don't need all of them in here as the entire prom vector
  gets initialized in c-code so all routines can use it.
-*/
* Fill up the prom vector, note in particular the kind first element,
* no joke. I don't need all of them in here as the entire prom vector
* gets initialized in c-code so all routines can use it.
+ */
 
                        .globl _prom_vector_p
 
@@ -913,24+902,34 @@ prom_nodefuncs:           .skip 4                 ! Magical Node functions
 prom_printf:           .skip 4                 ! minimal printf()
 
 /* The prom_abort pointer MUST be mapped in all contexts, because if you
  don't then if a user process is running when you press the abort key
  sequence, all sorts of bad things can happen
-*/
* don't then if a user process is running when you press the abort key
* sequence, all sorts of bad things can happen
+ */
 
 prom_abort:            .skip 4         ! "L1-A" magic cookie
                                        ! must be mapped in ALL contexts
 
 /* prom_sync is a place where the kernel should place a pointer to a kernel
  function that when called will sync all pending information to the drives
  and then promptly return. If the kernel gets aborted with 'L1-A' one can
  give the 'sync' command to the boot prompt and this magic cookie gets
  executed. Nice feature eh?
-*/
* function that when called will sync all pending information to the drives
* and then promptly return. If the kernel gets aborted with 'L1-A' one can
* give the 'sync' command to the boot prompt and this magic cookie gets
* executed. Nice feature eh?
+ */
 
 prom_sync:             .skip 4                 ! hook in prom for "sync" func
 
        .align 4
 
+/* We calculate the following at boot time, window fills/spills and trap entry
+ * code uses these to keep track of the register windows.
+ */
+
+       .globl _nwindows
+       .globl _nwindowsm1
+_nwindows:     .skip 4
+_nwindowsm1:   .skip 4
+
+       .align 4
 /* Boot time priviledged register values, plus magic %o2 value */
 
        .globl _boot_wim
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
new file mode 100644 (file)
index 0000000..b4b8ad8
--- /dev/null
@@ -0,0 +1,131 @@
+/*  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
+ *                            Sparc the IRQ's are basically 'cast in stone'
+ *                            and you are supposed to probe the prom's device
+ *                            node trees to find out who's got which IRQ.
+ *
+ *  Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ *
+ */
+
+/*
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * The same sigaction struct is used, and with similar semantics (ie there
+ * is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there
+ * are similarities.
+ *
+ * sa_handler(int irq_NR) is the default function called (0 if no).
+ * sa_mask is horribly ugly (I won't even mention it)
+ * sa_flags contains various info: SA_INTERRUPT etc
+ * sa_restorer is the unused
+ */
+
+
+void disable_irq(unsigned int irq_nr)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+int get_irq_list(char *buf)
+{
+  int len = 0;
+
+  return len;
+}
+
+/*
+ * do_IRQ handles IRQ's that have been installed without the
+ * SA_INTERRUPT flag: it uses the full signal-handling return
+ * and runs with other interrupts enabled. All relatively slow
+ * IRQ's should use this format: notably the keyboard/timer
+ * routines.
+ */
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+  kstat.interrupts[irq]++;
+  return;
+}
+
+/*
+ * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
+ * stuff - the handler is also running with interrupts disabled unless
+ * it explicitly enables them later.
+ */
+asmlinkage void do_fast_IRQ(int irq)
+{
+  kstat.interrupts[irq]++;
+  return;
+}
+
+#define SA_PROBE SA_ONESHOT
+
+/*
+ * Using "struct sigaction" is slightly silly, but there
+ * are historical reasons and it works well, so..
+ */
+static int irqaction(unsigned int irq, struct sigaction * new_sa)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       restore_flags(flags);
+       return 0;
+}
+               
+int request_irq(unsigned int irq, void (*handler)(int),
+       unsigned long flags, const char * devname)
+{
+       return irqaction(irq,&sa);
+}
+
+void free_irq(unsigned int irq)
+{
+  unsigned long flags;
+
+  save_flags(flags);
+  restore_flags(flags);
+  return;
+}
+
+static void math_error_irq(int cpl)
+{
+  return;
+}
+
+static void no_action(int cpl) { }
+
+unsigned int probe_irq_on (void)
+{
+  unsigned int irqs = 0;
+
+  return irqs;
+}
+
+int probe_irq_off (unsigned int irqs)
+{
+  unsigned int i = 0;
+
+  return i;
+}
+
+void init_IRQ(void)
+{
+  int i;
+
+  for (i = 0; i < 16 ; i++)
+    set_intr_gate(0x20+i,bad_interrupt[i]);
+
+  return;
+}
index e69d71d..8b437a2 100644 (file)
@@ -2863,7+2863,7 @@ cdu31a_init(unsigned long mem_start, unsigned long mem_end)
 
    if (drive_found)
    {
-      register_iomem(sony_cd_base_io, 4,"cdu31a");
+      request_region(sony_cd_base_io, 4,"cdu31a");
       
       if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
       {
index d1b2e1e..273ae20 100644 (file)
 #include <linux/genhd.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/ioport.h>
 
 #define REALLY_SLOW_IO
 #include <asm/system.h>
@@ -1023,6+1024,9 @@ static void hd_geninit(void)
                if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
                        printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
                        NR_HD = 0;
+               } else {
+                       request_region(HD_DATA, 8, "hd");
+                       request_region(HD_CMD, 1, "hd(cmd)");
                }
        }
        hd_gendisk.nr_real = NR_HD;
index 10034af..d961d57 100644 (file)
@@ -1885,8+1885,8 @@ static void probe_for_drives (byte hwif)
                (void) probe_irq_off(probe_irq_on()); /* clear dangling irqs */
 #endif /* PROBE_FOR_IRQS */
                if (devs[0].present || devs[1].present) {
-                       register_iomem(IDE_PORT(HD_DATA,HWIF),8,"ide");
-                       register_iomem(IDE_PORT(HD_CMD,HWIF),1,"ide");
+                       request_region(IDE_PORT(HD_DATA,HWIF),8,"ide");
+                       request_region(IDE_PORT(HD_CMD,HWIF),1,"ide");
                }
                restore_flags(flags);
        }
index 4cd0d26..07a18e7 100644 (file)
@@ -1168,7+1168,7 @@ mcd_init(unsigned long mem_start, unsigned long mem_end)
                printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
                return mem_start;
        }
-       register_iomem(mcd_port, 4,"mcd");
+       request_region(mcd_port, 4,"mcd");
 
        outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
        outb(0x02,MCDPORT(0));
index 880faf8..cbfe446 100644 (file)
@@ -4228,7+4228,7 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
   blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
   read_ahead[MAJOR_NR] = SBP_BUFFER_FRAMES * (CD_FRAMESIZE / 512);
   
-  register_iomem(CDo_command,4,"sbpcd");
+  request_region(CDo_command,4,"sbpcd");
 
   for (j=0;j<NR_SBPCD;j++)
     {
index c313b21..5fcdbf7 100644 (file)
@@ -75,7+75,7 @@ endif
 
 MODULES := lp.o
 
-all: char.a modules
+all: char.a
 
 char.a: $(OBJS)
        $(AR) rcs char.a $(OBJS)
@@ -83,8+83,7 @@ char.a: $(OBJS)
 
 ifdef MODULES
 
-modules:
-       $(MAKE) CFLAGS="$(CFLAGS) -DMODULE" $(MODULES)
+modules: $(MODULES)
        (cd ../../modules;for i in $(MODULES); do ln -sf ../drivers/char/$$i .; done)
 
 else
index 8e7c271..ee5098e 100644 (file)
@@ -494,7+494,6 @@ long lp_init(long kmem_start)
        int offset = 0;
        unsigned int testvalue = 0;
        int count = 0;
-       char buf[5];
 
        if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
                printk("unable to get major %d for line printer\n", LP_MAJOR);
@@ -513,8+512,7 @@ long lp_init(long kmem_start)
                        LP_F(offset) |= LP_EXIST;
                        lp_reset(offset);
                        printk("lp%d at 0x%04x, ", offset,LP_B(offset));
-                       sprintf(buf,"lp%d",offset);
-                       register_iomem(LP_B(offset), 3,buf);
+                       request_region(LP_B(offset), 3, "lp");
                        if (LP_IRQ(offset))
                                printk("using IRQ%d\n", LP_IRQ(offset));
                        else
@@ -536,7+534,6 @@ int init_module(void)
        int offset = 0;
        unsigned int testvalue = 0;
        int count = 0;
-       char buf[5];
 
        if (register_chrdev(LP_MAJOR,"lp",&lp_fops)) {
                printk("unable to get major %d for line printer\n", LP_MAJOR);
@@ -553,8+550,7 @@ int init_module(void)
                        LP_F(offset) |= LP_EXIST;
                        lp_reset(offset);
                        printk("lp%d at 0x%04x, ", offset,LP_B(offset));
-                       sprintf(buf,"lp%d",offset);
-                       register_iomem(LP_B(offset),3,buf);
+                       request_region(LP_B(offset),3,"lp");
                        if (LP_IRQ(offset))
                                printk("using IRQ%d\n", LP_IRQ(offset));
                        else
index 0e4f563..6ee1488 100644 (file)
@@ -1479,7+1479,7 @@ static int set_serial_info(struct async_struct * info,
                info->hub6 = new_serial.hub6;
        }
        if(info->type != PORT_UNKNOWN)
-               register_iomem(info->port,8,"serial(set)");
+               request_region(info->port,8,"serial(set)");
 
        
 check_and_exit:
@@ -2353,7+2353,7 @@ static void autoconfig(struct async_struct * info)
                if ((status1 != 0xa5) || (status2 != 0x5a))
                        info->type = PORT_8250;
        }
-       register_iomem(info->port,8,"serial(auto)");
+       request_region(info->port,8,"serial(auto)");
 
        /*
         * Reset the UART.
index dbdc506..8e5e17d 100644 (file)
 
 #include <asm/io.h>
 #include <asm/system.h>
+#include <asm/segment.h>
+
 extern unsigned short video_port_reg, video_port_val;
 
 /*
@@ -236,7+238,8 @@ void vesa_unblank(void)
        vesa_blanked = 0;
 }
 
-void set_vesa_blanking(const unsigned long arg) {
+void set_vesa_blanking(const unsigned long arg)
+{
        char *argp = (char *)(arg + 1);
        unsigned int mode = get_fs_byte(argp);
        vesa_blanking_mode = ((mode < 3) ? mode : 0);
index 3b7af0e..aca6394 100644 (file)
@@ -81,6+81,7 @@ static char *version =
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
+#include <linux/config.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -229,7+230,7 @@ el1_probe1(struct device *dev, int ioaddr)
        return ENODEV;
 
     /* Grab the region so we can find the another board if autoIRQ fails. */
-    register_iomem(ioaddr, EL1_IO_EXTENT,"3c501");
+    request_region(ioaddr, EL1_IO_EXTENT,"3c501");
 
     if (dev == NULL)
        dev = init_etherdev(0, sizeof(struct net_local), 0);
index 797e39c..9acd23b 100644 (file)
@@ -172,7+172,7 @@ el2_probe1(struct device *dev, int ioaddr)
        return ENODEV;
     }
 
-    register_iomem(ioaddr, EL2_IO_EXTENT,"3c503");
+    request_region(ioaddr, EL2_IO_EXTENT,"3c503");
 
     if (dev == NULL)
        dev = init_etherdev(0, sizeof(struct ei_device), 0);
index 089db0a..a263e78 100644 (file)
@@ -370,7+370,7 @@ int el16_probe1(struct device *dev, int ioaddr)
        }
        
        /* We've committed to using the board, and can start filling in *dev. */
-       register_iomem(ioaddr, EL16_IO_EXTENT,"3c507");
+       request_region(ioaddr, EL16_IO_EXTENT,"3c507");
        dev->base_addr = ioaddr;
 
        outb(0x01, ioaddr + MISC_CTRL);
index 43d6734..067f143 100644 (file)
@@ -224,7+224,7 @@ int el3_probe(struct device *dev)
        dev->base_addr = ioaddr;
        dev->irq = irq;
        dev->if_port = if_port;
-       register_iomem(dev->base_addr, 16,"3c509");
+       request_region(dev->base_addr, 16,"3c509");
 
        {
                char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
index 2a8ab3f..99afad5 100644 (file)
@@ -192,16+192,10 @@ tar:
 
 ifdef MODULES
 
-modules:
+modules: $(MODULES)
        echo $(MODULES) > ../../modules/NET_MODULES
-       @(cd ../../modules; \
-               for i in $(MODULES:.o=.c); \
-                       do ln -sf ../drivers/net/$$i .; \
-                       done ; \
-               ln -sf ../drivers/net/CONFIG . ; \
-               $(MAKE) -f../drivers/net/Makefile -I../drivers/net \
-                       CFLAGS="$(CFLAGS) -I../net/inet -I../drivers/net -DMODULE" $(MODULES); \
-               rm $(MODULES:.o=.c) CONFIG)
+       cd ../../modules; \
+               for i in $(MODULES); do ln -sf ../drivers/net/$$i .; done
 
 else
 
index 1c938df..3463ae8 100644 (file)
@@ -44,7+44,7 @@ static char *version = "apricot.c:v0.2 05/12/94\n";
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(addr, size)       0
-#define register_iomem(addr, size,name)        do ; while(0)
+#define request_region(addr, size,name)        do ; while(0)
 #endif
 
 #ifndef HAVE_ALLOC_SKB
@@ -714,7+714,7 @@ int apricot_probe(struct device *dev)
     if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
        return ENODEV;
 
-    register_iomem(ioaddr, APRICOT_TOTAL_SIZE,"apricot");
+    request_region(ioaddr, APRICOT_TOTAL_SIZE,"apricot");
 
     dev->base_addr = ioaddr;
     ether_setup(dev);
index 21d23ec..f3df96b 100644 (file)
@@ -207,7+207,7 @@ int at1700_probe1(struct device *dev, short ioaddr)
 
        /* Grab the region so that we can find another board if the IRQ request
           fails. */
-       register_iomem(ioaddr, AT1700_IO_EXTENT,"at1700");
+       request_region(ioaddr, AT1700_IO_EXTENT,"at1700");
 
        printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
                   ioaddr, irq);
index e85e260..8f2a5dc 100644 (file)
@@ -113,7+113,7 @@ extern struct device *irq2dev_map[16];
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size)             0
-#define register_iomem(ioaddr, size,name);             do ; while (0)
+#define request_region(ioaddr, size,name);             do ; while (0)
 #endif
 
 /* use 0 for production, 1 for verification, >2 for debug */
index 088f316..f73d6a5 100644 (file)
@@ -480,7+480,7 @@ depca_probe1(struct device *dev, short ioaddr)
        }
 
 #ifdef HAVE_PORTRESERVE
-       register_iomem(ioaddr, DEPCA_TOTAL_SIZE,"depca");
+       request_region(ioaddr, DEPCA_TOTAL_SIZE,"depca");
 #endif
 
        /*
index 6d8ac54..94471dc 100644 (file)
@@ -147,7+147,7 @@ int e21_probe1(struct device *dev, int ioaddr)
                return ENODEV;
 
        /* Grab the region so we can find a different board if IRQ select fails. */
-       register_iomem(ioaddr, E21_IO_EXTENT,"e2100");
+       request_region(ioaddr, E21_IO_EXTENT,"e2100");
 
        /* Read the station address PROM.  */
        for (i = 0; i < 6; i++)
index 9c4c39e..02edd0a 100644 (file)
@@ -363,7+363,7 @@ int eexp_probe1(struct device *dev, short ioaddr)
        }
 
        /* We've committed to using the board, and can start filling in *dev. */
-       register_iomem(ioaddr, 16,"eexpress");
+       request_region(ioaddr, 16,"eexpress");
        dev->base_addr = ioaddr;
 
        for (i = 0; i < 6; i++) {
index 150991d..ab3be72 100644 (file)
@@ -352,7+352,7 @@ int ewrk3_probe(struct device *dev)
       if (!check_region(base_addr, EWRK3_IOP_INC)) {
        if (((mem_chkd >> ((base_addr - EWRK3_IO_BASE)/ EWRK3_IOP_INC))&0x01)==1) {
          if (DevicePresent(base_addr) == 0) {      /* Is EWRK3 really here? */
-           register_iomem(base_addr, EWRK3_IOP_INC,"ewrk3"); /* Register I/O region */
+           request_region(base_addr, EWRK3_IOP_INC,"ewrk3"); /* Register I/O region */
            status = ewrk3_hw_init(dev, base_addr);
          } else {
            printk("ewrk3_probe(): No device found\n");
@@ -1344,7+1344,7 @@ static struct device *isa_probe(struct device *dev)
 ** Device found. Mark its (I/O) location for future reference. Only 24
 ** EtherWORKS devices can exist between 0x100 and 0x3e0.
 */
-         register_iomem(iobase, EWRK3_IOP_INC,"ewrk3");
+         request_region(iobase, EWRK3_IOP_INC,"ewrk3");
          if (num_ewrk3s > 0) {        /* only gets here in autoprobe */
            dev = alloc_device(dev, iobase);
          } else {
@@ -1387,7+1387,7 @@ static struct device *eisa_probe(struct device *dev)
 ** EtherWORKS devices can exist in EISA space....
 */
        mem_chkd |= (0x01 << (i + 24));
-       register_iomem(iobase, EWRK3_IOP_INC,"ewrk3");
+       request_region(iobase, EWRK3_IOP_INC,"ewrk3");
        if (num_ewrk3s > 0) {        /* only gets here in autoprobe */
          dev = alloc_device(dev, iobase);
        } else {
index 2ae9105..694b3c0 100644 (file)
@@ -178,7+178,7 @@ int hpp_probe1(struct device *dev, int ioaddr)
        }
 
        /* Grab the region so we can find another board if something fails. */
-       register_iomem(ioaddr, HP_IO_EXTENT,"hp-plus");
+       request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
 
        /* Read the IRQ line. */
        outw(HW_Page, ioaddr + HP_PAGING);
index 38331b5..393b1a1 100644 (file)
@@ -125,7+125,7 @@ int hp_probe1(struct device *dev, int ioaddr)
                dev = init_etherdev(0, sizeof(struct ei_device), 0);
 
        /* Grab the region so we can find another board if something fails. */
-       register_iomem(ioaddr, HP_IO_EXTENT,"hp");
+       request_region(ioaddr, HP_IO_EXTENT,"hp");
 
        printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
 
index 829b67d..f14f781 100644 (file)
@@ -365,7+365,7 @@ unsigned long lance_probe1(int ioaddr, unsigned long mem_start)
                printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
 
        dev->base_addr = ioaddr;
-       register_iomem(ioaddr, LANCE_TOTAL_SIZE,"lance");
+       request_region(ioaddr, LANCE_TOTAL_SIZE,"lance");
 
        /* Make certain the data structures used by the LANCE are aligned. */
        dev->priv = (void *)(((int)dev->priv + 7) & ~7);
index a87d382..0b5b593 100644 (file)
@@ -259,7+259,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
 
     dev->base_addr = ioaddr;
 
-    register_iomem(ioaddr, NE_IO_EXTENT,"ne2000");
+    request_region(ioaddr, NE_IO_EXTENT,"ne2000");
 
     for(i = 0; i < ETHER_ADDR_LEN; i++)
        dev->dev_addr[i] = SA_prom[i];
index 81a3241..8e6cf4c 100644 (file)
@@ -181,7+181,7 @@ extern void *irq2dev_map[16];
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size)             0
-#define        register_iomem(ioaddr, size,name);              do ; while (0)
+#define        request_region(ioaddr, size,name);              do ; while (0)
 #endif
 
 #define NI52_TOTAL_SIZE 16
@@ -388,7+388,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
 
   printk("%s: Ni52 found at %#3x, ",dev->name,dev->base_addr);
 
-  register_iomem(ioaddr,NI52_TOTAL_SIZE,"ni52");
+  request_region(ioaddr,NI52_TOTAL_SIZE,"ni52");
 
   dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
                                   /* warning: we don't free it on errors */
index a80d590..f641131 100644 (file)
 
 #ifndef HAVE_PORTRESERVE
 #define check_region(ioaddr, size)              0
-#define register_iomem(ioaddr, size,name);             do ; while (0)
+#define request_region(ioaddr, size,name);             do ; while (0)
 #endif
 
 #ifndef NET_DEBUG
@@ -243,7+243,7 @@ static int ni65_probe1(struct device *dev,int ioaddr)
   irq2dev_map[dev->irq] = dev;
 
   /* Grab the region so we can find another board if autoIRQ fails. */
-        register_iomem(ioaddr,NI65_TOTAL_SIZE,"ni65");
+        request_region(ioaddr,NI65_TOTAL_SIZE,"ni65");
 
   p = dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
   memset((char *) dev->priv,0,sizeof(struct priv));
index 719500e..6ad5c14 100644 (file)
@@ -225,7+225,7 @@ plip_init(struct device *dev)
        }
     }
 
-    register_iomem(PAR_DATA(dev), 3,"plip");
+    request_region(PAR_DATA(dev), 3,"plip");
 
     /* Fill in the generic fields of the device structure. */
     ether_setup(dev);
index 6d33b34..f34a643 100644 (file)
@@ -329,7+329,7 @@ static char *rcsid = "$Id: sk_g16.c,v 1.1 1994/06/30 16:25:15 root Exp $";
 #ifndef HAVE_PORTRESERVE
 
 #define check_region(ioaddr, size)              0
-#define register_iomem(ioaddr, size,name);             do ; while (0)
+#define request_region(ioaddr, size,name);             do ; while (0)
 
 #endif
 
@@ -782,7+782,7 @@ int SK_probe(struct device *dev, short ioaddr)
            dev->dev_addr[5]);
 
     /* Grab the I/O Port region */
-    register_iomem(ioaddr, ETHERCARD_TOTAL_SIZE,"sk_g16");
+    request_region(ioaddr, ETHERCARD_TOTAL_SIZE,"sk_g16");
 
     /* Initialize device structure */
 
index a7daad6..a03cd2f 100644 (file)
@@ -247,7+247,7 @@ static int netcard_probe1(struct device *dev, int ioaddr)
 #endif /* jumpered DMA */
 
        /* Grab the region so we can find another board if autoIRQ fails. */
-       register_iomem(ioaddr, NETCARD_IO_EXTENT,"skeleton");
+       request_region(ioaddr, NETCARD_IO_EXTENT,"skeleton");
 
        /* Initialize the device structure. */
        if (dev->priv == NULL)
index 333df03..e994188 100644 (file)
@@ -71,6+71,11 @@ struct slip {
   unsigned long         rx_dropped;     /* No memory for skb            */
   unsigned long         tx_dropped;     /* When MTU change              */
   unsigned long         rx_over_errors; /* Frame bigger then SLIP buf.  */
+#ifdef SL_INCLUDE_CSLIP
+  unsigned long                tx_compressed;
+  unsigned long                rx_compressed;
+  unsigned long                tx_misses;
+#endif
   /* Detailed SLIP statistics. */
 
   int                  mtu;            /* Our mtu (to spot changes!)   */
index bdc8c1b..8988e2d 100644 (file)
@@ -147,7+147,7 @@ int ultra_probe1(struct device *dev, int ioaddr)
 
 
        /* OK, were are certain this is going to work.  Setup the device. */
-       register_iomem(ioaddr, 32,"smc-ultra");
+       request_region(ioaddr, 32,"smc-ultra");
 
        /* The 8390 isn't at the base address, so fake the offset */
        dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
index e6b9f11..783d7a5 100644 (file)
@@ -235,7+235,7 @@ int wd_probe1(struct device *dev, int ioaddr)
        }
 
        /* OK, were are certain this is going to work.  Setup the device. */
-       register_iomem(ioaddr, WD_IO_EXTENT,"wd");
+       request_region(ioaddr, WD_IO_EXTENT,"wd");
        ethdev_init(dev);
 
        ei_status.name = model_name;
index 39a2e7c..12ea076 100644 (file)
@@ -189,6+189,7 @@ dep:
 
 endif
 
+modules:
 
 #
 # include a dependency file if one exists
index 68cb2a9..c166343 100644 (file)
@@ -722,7+722,7 @@ int aha152x_detect(Scsi_Host_Template * tpnt)
          can_disconnect ? "enabled" : "disabled",
          can_doparity ? "enabled" : "disabled");
 
-  register_iomem(port_base, TEST-SCSISEQ,"aha152x");        /* Register */
+  request_region(port_base, TEST-SCSISEQ,"aha152x");        /* Register */
   
   /* not expecting any interrupts */
   SETPORT(SIMODE0, 0);
index 7f191a2..c11fcaa 100644 (file)
@@ -1053,7+1053,7 @@ int aha1542_detect(Scsi_Host_Template * tpnt)
                            aha1542_command(0, cmd, buffer, 512);
                    }
 #endif    
-                   register_iomem(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
+                   request_region(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
                    count++;
                    continue;
            unregister:
index 35d932e..5e74138 100644 (file)
@@ -471,7+471,7 @@ int aha1740_detect(Scsi_Host_Template * tpnt)
         printk("Unable to allocate IRQ for adaptec controller.\n");
         return 0;
     }
-    register_iomem(base, 0x5c,"aha1740");  /* Reserve the space that we need to use */
+    request_region(base, 0x5c,"aha1740");  /* Reserve the space that we need to use */
     return 1;
 }
 
index e008e09..f45317c 100644 (file)
@@ -1336,7+1336,7 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
            }
 #endif
 
-           register_iomem(bases[indx], 4,"buslogic");
+           request_region(bases[indx], 4,"buslogic");
            /* Register the IO ports that we use */
            count++;
            continue;
index 0552a35..e4c2eea 100644 (file)
@@ -385,7+385,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
 
    /* Register the I/O space that we use */
-   register_iomem(sh[j]->io_port, REG_REGION,"eata");
+   request_region(sh[j]->io_port, REG_REGION,"eata");
 
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->subversion = subversion;
index 8de63c8..92dc62d 100644 (file)
@@ -704,7+704,7 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
 
                                /* Log I/O ports with kernel */
 
-   register_iomem( port_base, 0x10 ,"fdomain");
+   request_region( port_base, 0x10 ,"fdomain");
 
    if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
       adapter_mask = 0x80;
index ea9f5ff..3f50f17 100644 (file)
  */
 /* Changes for 1.1.43+ kernels made 8/25/94, code added to check for
  * new BIOS version, derived by jshiffle@netcom.com. (WDE)
+ *
+ * 1/7/95 Fix from Peter Lu (swift@world.std.com) for datalen vs. dataptr
+ * logic, much more stable under load.
  */
 
 #include <linux/kernel.h>
@@ -195,10+198,9 @@ static void in2000_fifo_out(void)  /* uses FIFOCNTR */
 #endif
     } while((in2000_datalen > 0) && ((infcnt = (inb(INFCNT)) & 0xfe) >= 0x20) );
     /* If scatter-gather, go on to next segment */
-    if( !in2000_datalen && in2000_current_segment < in2000_nsegment)
+    if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
       {
       in2000_scatter++;
-      in2000_current_segment++;
       in2000_datalen = in2000_scatter->length;
       in2000_dataptr = (unsigned short*)in2000_scatter->address;
       }
@@ -253,10+255,9 @@ DEB(printk("FIr:%d %02x %08x %08x\n", in2000_datalen,fic,count2,(unsigned int)in
 DEB(printk("FIer:%d %02x %08x\n", in2000_datalen,fic,(unsigned int )in2000_dataptr));
 /*    while ( count-- )
        inw(INFIFO);*/  /* Throw away some extra stuff */
-    if( !in2000_datalen && in2000_current_segment < in2000_nsegment)
+    if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
       {
       in2000_scatter++;
-      in2000_current_segment++;
       in2000_datalen = in2000_scatter->length;
       in2000_dataptr = (unsigned short*)in2000_scatter->address;
       }
@@ -288,13+289,16 @@ static void in2000_intr_handle(int foo)
                scsistatus,cmdphase,scsibyte));
 
        /* Why do we assume that we need to send more data here??? ERY */
-       if ( in2000_datalen && in2000_dataptr ) /* data xfer pending */
+       if ( in2000_datalen )   /* data xfer pending */
            {
-           if ( in2000_datawrite )
+           if ( in2000_dataptr == NULL )
+               printk("int2000: dataptr=NULL datalen=%d\n",
+                       in2000_datalen);
+           else if ( in2000_datawrite )
                in2000_fifo_out();
            else
                in2000_fifo_in();
-           } else ficmsk = 0;
+           } 
        if ( (auxstatus & 0x8c) == 0x80 )
            {   /* There is a WD Chip interrupt & register read good */
            outb(2,ININTR);     /* Disable fifo interrupts */
@@ -630,7+634,7 @@ int in2000_detect(Scsi_Host_Template * tpnt)
     shpnt->io_port = base;
     shpnt->n_io_port = 12;
     shpnt->irq = irq_level;
-    register_iomem(base, 12,"in2000");  /* Prevent other drivers from using this space */
+    request_region(base, 12,"in2000");  /* Prevent other drivers from using this space */
     return 1;
 }
 
index e146d74..a106845 100644 (file)
@@ -527,7+527,7 @@ struct      Scsi_Host       *hreg;  /* registered host structure */
                host->can_queue = 1;
        sti();
 #endif
-       register_iomem( qbase , 0x10 ,"qlogic");
+       request_region( qbase , 0x10 ,"qlogic");
 
        hreg = scsi_register( host , 0 );       /* no host data */
        hreg->io_port = qbase;
index 0d77684..ef0a071 100644 (file)
@@ -352,7+352,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
    if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);
 
    /* Register the I/O space that we use */
-   register_iomem(sh[j]->io_port, REG_REGION,"u14-34f");
+   request_region(sh[j]->io_port, REG_REGION,"u14-34f");
 
    memset(HD(j), 0, sizeof(struct hostdata));
    HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
index 8eed43d..6e31a9d 100644 (file)
@@ -438,7+438,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
     /* All above tests passed, must be the right thing.  Get some useful
        info. */
 
-    register_iomem(config.port_address, 0x0c,"ultrastor"); 
+    request_region(config.port_address, 0x0c,"ultrastor"); 
     /* Register the I/O space that we use */
 
     *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
index b80a669..cc92225 100644 (file)
@@ -30,7+30,7 @@ int ultrastor_biosparam(Disk *, int, int *);
 
 
 #define ULTRASTOR_14F { NULL, NULL, /* Ptr for modules*/ \
-                         NULL,                         \
+                         "UltraStor 14F/24F/34F",      \
                          ultrastor_detect,             \
                          NULL, /* Release */           \
                          ultrastor_info,               \
index e201256..c9b1445 100644 (file)
@@ -1162,7+1162,7 @@ int wd7000_detect(Scsi_Host_Template * tpnt)
                 printk("using IO %xh IRQ %d DMA %d.\n",
                       host->iobase, host->irq, host->dma);
 
-               register_iomem(host->iobase, 4,"wd7000"); /* Register our ports */
+               request_region(host->iobase, 4,"wd7000"); /* Register our ports */
                /*
                 *  For boards before rev 6.0, scatter/gather isn't supported.
                 */
index c8481d1..e0c84b8 100644 (file)
@@ -41,6+41,8 @@ endif
 
 ifdef CONFIG_NFS_FS
 FS_SUBDIRS := $(FS_SUBDIRS) nfs
+else
+MODULE_FS_SUBDIRS := $(MODULE_FS_SUBDIRS) nfs
 endif
 
 ifdef CONFIG_XIA_FS
@@ -93,8+95,10 @@ filesystems.a: dummy
          test ! -d $$i || \
            { $(MAKE) -C $$i; $(AR) rcs filesystems.a $$i/$$i.o; }; done
 
-modules:
-       set -e; for i in $(MODULE_FS_SUBDIRS); do $(MAKE) -C $$i modules; done
+modules: $(MODULE_OBJS)
+       for i in $(MODULE_FS_SUBDIRS); do $(MAKE) -C $$i modules; done
+       cd ../modules;for i in $(MODULE_OBJS); do ln -sf ../fs/$$i .; done
+       cd ../modules;for i in $(MODULE_FS_SUBDIRS); do ln -sf ../fs/$$i/$$i.o .; done
 
 depend dep:
        $(CPP) -M *.c > .depend
index 3f67ae7..73f05b9 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_ISO9660_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
index a38881d..dd33254 100644 (file)
@@ -251,7+251,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
 
                brelse(bh);
              }
-       if(iso_blknum == 100) {
+       if(iso_blknum == vol_desc_start + 100) {
                if (!silent)
                        printk("Unable to identify CD-ROM format.\n");
                s->s_dev = 0;
index 4865ad7..82250ca 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_MINIX_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
@@ -27,6+23,8 @@ minix.o: $(OBJS)
 dep:
        $(CPP) -M *.c > .depend
 
+modules: minix.o
+
 #
 # include a dependency file if one exists
 #
index 9d36587..ecb07ce 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_MSDOS_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
index 8610c95..eabf9f6 100644 (file)
@@ -23,6+23,8 @@ nfs.o: $(OBJS)
 dep:
        $(CPP) -M *.c > .depend
 
+modules: nfs.o
+
 #
 # include a dependency file if one exists
 #
index 8f1348c..e9ec766 100644 (file)
  *
  * Alessandro Rubini :  profile extension.
  *                      <rubini@ipvvis.unipv.it>
+ *
+ * Jeff Tranter      :  added BogoMips field to cpuinfo
+ *                      <Jeff_Tranter@Mitel.COM>
  */
 
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/ioport.h>
 #include <linux/config.h>
+#include <linux/delay.h>
 
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -262,6+266,7 @@ static int get_version(char * buffer)
 
 static int get_cpuinfo(char * buffer)
 {
+#ifdef __i386__
        char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6",
                                "7","DX/4"},
                        {"Pentium 60/66","Pentium 90/100","3",
@@ -284,7+289,8 @@ static int get_cpuinfo(char * buffer)
                              "TS Counters\t: %s\n"
                              "Pentium MSR\t: %s\n"
                              "Mach. Ch. Exep.\t: %s\n"
-                             "CMPXCHGB8B\t: %s\n",
+                             "CMPXCHGB8B\t: %s\n"
+                             "BogoMips\t: %lu.%02lu\n",
                              x86+'0', 
                              x86_model ? model[x86-4][x86_model-1] : "Unknown",
                              x86_mask ? mask : "Unknown",
@@ -300,8+306,12 @@ static int get_cpuinfo(char * buffer)
                              x86_capability & 16 ? "yes" : "no",
                              x86_capability & 32 ? "yes" : "no",
                              x86_capability & 128 ? "yes" : "no",
-                             x86_capability & 256 ? "yes" : "no"
+                             x86_capability & 256 ? "yes" : "no",
+                             loops_per_sec/500000, (loops_per_sec/5000) % 100
                              );
+#else
+       return 0;
+#endif
 }
 
 static struct task_struct ** get_task(pid_t pid)
@@ -388,6+398,7 @@ static int get_arg(int pid, char * buffer)
 
 static unsigned long get_wchan(struct task_struct *p)
 {
+#ifdef __i386__
        unsigned long ebp, eip;
        unsigned long stack_page;
        int count = 0;
@@ -407,6+418,7 @@ static unsigned long get_wchan(struct task_struct *p)
                        return eip;
                ebp = *(unsigned long *) ebp;
        } while (count++ < 16);
+#endif
        return 0;
 }
 
@@ -438,7+450,7 @@ static int get_stat(int pid, char * buffer)
        }
        wchan = get_wchan(*p);
        for(i=0; i<32; ++i) {
-               switch((int) (*p)->sigaction[i].sa_handler) {
+               switch((unsigned long) (*p)->sigaction[i].sa_handler) {
                case 1: sigignore |= bit; break;
                case 0: break;
                default: sigcatch |= bit;
index 36efaca..05ab7ae 100644 (file)
@@ -170,6+170,7 @@ static int proc_lookupnet(struct inode * dir,const char * name, int len,
                        return -ENOENT;
                return 0;
        }
+       iput(dir);
        return -ENOENT;
 }
 
index 804d8c3..4de55ba 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_SYSV_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
index 76de9ef..739787c 100644 (file)
@@ -334,7+334,6 @@ static struct super_block * detected_coherent (struct super_block *sb, struct bu
        sb->sv_sb_flc_blocks = &sbd->s_free[0];
        sb->sv_sb_total_free_blocks = &sbd->s_tfree;
        sb->sv_sb_time = &sbd->s_time;
-       sb->sv_sb_state = &sbd->s_state;
        sb->sv_block_base = 0;
        sb->sv_firstinodezone = 2;
        sb->sv_firstdatazone = sbd->s_isize;
index b0fe304..2e73cf7 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_UMSDOS_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
index d2b7b61..e3c0c76 100644 (file)
@@ -7,10+7,6 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-ifndef CONFIG_XIA_FS
-CFLAGS := $(CFLAGS) -DMODULE
-endif
-
 .c.s:
        $(CC) $(CFLAGS) -S $<
 .c.o:
index 93bab75..0d56e25 100644 (file)
@@ -24,7+24,7 @@ extern int EISA_bus;
 struct thread_struct {
        unsigned long ksp;
        unsigned long usp;
-       unsigned long cr3;      /* ptbr */
+       unsigned long ptbr;
        unsigned int pcc;
        unsigned int asn;
        unsigned long unique;
index 8665a07..ab07636 100644 (file)
@@ -122,7+122,7 @@ __asm__ __volatile__(
 return __res;
 }
 
-extern inline char * strchr(const char * s,char c)
+extern inline char * strchr(const char * s, int c)
 {
 register char * __res;
 __asm__ __volatile__(
@@ -140,7+140,7 @@ __asm__ __volatile__(
 return __res;
 }
 
-extern inline char * strrchr(const char * s,char c)
+extern inline char * strrchr(const char * s, int c)
 {
 register char * __res;
 __asm__ __volatile__(
@@ -392,7+392,7 @@ __asm__("cld\n\t" \
                case 0: COMMON(""); return to;
                case 1: COMMON("\n\tmovsb"); return to;
                case 2: COMMON("\n\tmovsw"); return to;
-               case 3: COMMON("\n\tmovsw\n\tstosb"); return to;
+               case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
        }
 #undef COMMON
 }
@@ -442,7+442,7 @@ __asm__ __volatile__(
 return __res;
 }
 
-extern inline void * memchr(const void * cs,char c,size_t count)
+extern inline void * memchr(const void * cs,int c,size_t count)
 {
 register void * __res;
 if (!count)
@@ -459,7+459,7 @@ __asm__ __volatile__(
 return __res;
 }
 
-extern inline void * __memset_generic(void * s,char c,size_t count)
+extern inline void * __memset_generic(void * s, char c,size_t count)
 {
 __asm__ __volatile__(
        "cld\n\t"
@@ -533,7+533,7 @@ __asm__("cld\n\t" \
 /*
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
-extern inline void * memscan(void * addr, unsigned char c, size_t size)
+extern inline void * memscan(void * addr, int c, size_t size)
 {
        if (!size)
                return addr;
index e352554..b9e4110 100644 (file)
 #define TRAP_ENTRY_INTERRUPT_NMI(t_type, jmp_to) \
         mov t_type, %l3; b jmp_to; mov %psr, %l0; nop;
 
+/* Trap entry code in entry.S needs the offsets into task_struct
+ * to get at the thread_struct goodies during window craziness.
+ *
+ * NOTE: We need to keep these values under 0x3ff in order to do
+ *       efficient load/stores in the window fill/spill handlers.
+ *       See TRAP_WIN_CLEAN in entry.S for details.
+ */
+
+#define THREAD_UWINDOWS 0x3a8
+#define THREAD_WIM 0x3ac
+#define THREAD_W_SAVED 0x3b0
+#define THREAD_KSP 0x3b4
+#define THREAD_USP 0x3b8
+#define THREAD_REG_WINDOW 0x3c0
 
 #endif __SPARC_HEAD_H
index 7e89a30..b232c47 100644 (file)
@@ -25,16+25,25 @@ extern int EISA_bus;
  */
 #define IO_BITMAP_SIZE 32
 
+/* The first five entries here MUST be the first four. This allows me to
+ * do %lo(offset) loads and stores in entry.S. See TRAP_WIN_CLEAN to see
+ * why.
+ */
+
 struct thread_struct {
+       unsigned long uwindows;       /* how many user windows are in the set */
+       unsigned long wim;            /* user's window invalid mask */
+       unsigned long w_saved;        /* how many windows saved in reg_window[] */
        unsigned long ksp;          /* kernel stack pointer */
        unsigned long usp;          /* user's sp, throw reg windows here */
+       unsigned long psr;          /* save for condition codes */
+       unsigned long reg_window[16*24];
        unsigned long cr3;          /* why changed from ptbr? */
        unsigned int pcc;
        unsigned int asn;
        unsigned long unique;
        unsigned long flags;
        unsigned long res1, res2;
-       unsigned long psr;          /* save for condition codes */
        unsigned long pc;           /* program counter */
        unsigned long npc;          /* next program counter */
 
@@ -44,9+53,7 @@ struct thread_struct {
  * in nwindows.
  */
        unsigned long globl_regs[8];  /* global regs need to be saved too */
-       unsigned long reg_window[16*24];
        unsigned long yreg;
-       unsigned long uwindows;       /* how many user windows are in the set */
        unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */
 };
 
@@ -77,13+84,30 @@ struct thread_struct {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
-       0, 0, \
+       0, 0, 0, 0, \
         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
 }
 
+/* The thread_frame is what needs to be set up in certain circumstances
+ * upon entry to a trap. It is also loaded sometimes during a window
+ * spill if things don't go right (bad user stack pointer). In reality
+ * it is not per-process per se, it just sits in the kernel stack while
+ * the current process is in a handler then it is basically forgotten
+ * about.
+ */
+
+struct thread_frame {
+  unsigned int thr_psr;
+  unsigned int thr_pc;
+  unsigned int thr_npc;
+  unsigned int thr_y;
+  unsigned int thr_globals[8];
+  unsigned int thr_outs[8];
+};
+
 /*
  * These are the "cli()" and "sti()" for software interrupts
  * They work by increasing/decreasing the "intr_count" value, 
index 89370e4..8a019ad 100644 (file)
 extern void reserve_setup(char *str, int *ints);
 extern int check_region(unsigned int from, unsigned int extent);
 extern void snarf_region(unsigned int from, unsigned int extent);
-extern void register_iomem(unsigned int from, unsigned int extent,char* name);
+extern void request_region(unsigned int from, unsigned int extent,const char *name);
 extern void release_region(unsigned int from, unsigned int extent);
 extern int get_ioport_list(char *);
 
index 708b5b9..064ce0c 100644 (file)
  * Note the 8-bit gid and atime and ctime.
  */
 struct minix_inode {
-       u16 i_mode;
-       u16 i_uid;
-       u32 i_size;
-       u32 i_time;
-       u8  i_gid;
-       u8  i_nlinks;
-       u16 i_zone[9];
+       __u16 i_mode;
+       __u16 i_uid;
+       __u32 i_size;
+       __u32 i_time;
+       __u8  i_gid;
+       __u8  i_nlinks;
+       __u16 i_zone[9];
 };
 
 /*
@@ -48,34+48,34 @@ struct minix_inode {
  * now 16-bit. The inode is now 64 bytes instead of 32.
  */
 struct new_minix_inode {
-       u16 i_mode;
-       u16 i_nlinks;
-       u16 i_uid;
-       u16 i_gid;
-       u32 i_size;
-       u32 i_atime;
-       u32 i_mtime;
-       u32 i_ctime;
-       u32 i_zone[10];
+       __u16 i_mode;
+       __u16 i_nlinks;
+       __u16 i_uid;
+       __u16 i_gid;
+       __u32 i_size;
+       __u32 i_atime;
+       __u32 i_mtime;
+       __u32 i_ctime;
+       __u32 i_zone[10];
 };
 
 /*
  * minix super-block data on disk
  */
 struct minix_super_block {
-       u16 s_ninodes;
-       u16 s_nzones;
-       u16 s_imap_blocks;
-       u16 s_zmap_blocks;
-       u16 s_firstdatazone;
-       u16 s_log_zone_size;
-       u32 s_max_size;
-       u16 s_magic;
-       u16 s_state;
+       __u16 s_ninodes;
+       __u16 s_nzones;
+       __u16 s_imap_blocks;
+       __u16 s_zmap_blocks;
+       __u16 s_firstdatazone;
+       __u16 s_log_zone_size;
+       __u32 s_max_size;
+       __u16 s_magic;
+       __u16 s_state;
 };
 
 struct minix_dir_entry {
-       u16 inode;
+       __u16 inode;
        char name[0];
 };
 
index 757370c..c8677b4 100644 (file)
@@ -5,7+5,7 @@
  * minix fs inode data in memory
  */
 struct minix_inode_info {
-       u16 i_data[16];
+       __u16 i_data[16];
 };
 
 #endif
index 1d3b8ec..cc6885f 100644 (file)
@@ -233,8+233,9 @@ struct pci_class_type {
 #define PCI_DEVICE_ID_ATI_M32          0x4158
 #define PCI_DEVICE_ID_ATI_M64          0x4758
 
-#define PCI_VENDOR_ID_DIAMOND          0x100e
-#define PCI_DEVICE_ID_DIAMOND_VIPER    0x9001
+#define PCI_VENDOR_ID_WEITEK           0x100e
+#define PCI_DEVICE_ID_WEITEK_P9000     0x9001
+#define PCI_DEVICE_ID_WEITEK_P9100     0x9100
 
 #define PCI_VENDOR_ID_CIRRUS           0x1013
 #define PCI_DEVICE_ID_CIRRUS_5434      0x00A4
@@ -251,13+252,16 @@ struct pci_class_type {
 #define PCI_VENDOR_ID_TSENG            0x100c
 #define PCI_DEVICE_ID_TSENG_W32P       0x3205
 
+#define PCI_VENDOR_ID_CMD              0x1095
+#define PCI_DEVICE_ID_CMD_640          0x0640
+
 struct pci_vendor_type {
        unsigned short vendor_id;
        char *vendor_name;
 };
 
 
-#define PCI_VENDOR_NUM 16
+#define PCI_VENDOR_NUM 17
 #define PCI_VENDOR_TYPE { \
        {PCI_VENDOR_ID_NCR,             "NCR"}, \
        {PCI_VENDOR_ID_ADAPTEC,         "Adaptec"}, \
@@ -269,13+273,14 @@ struct pci_vendor_type {
        {PCI_VENDOR_ID_INTEL,           "Intel"}, \
        {PCI_VENDOR_ID_SMC,             "SMC"}, \
        {PCI_VENDOR_ID_ATI,             "ATI"}, \
-       {PCI_VENDOR_ID_DIAMOND,         "Diamond"}, \
+       {PCI_VENDOR_ID_WEITEK,          "Weitek"}, \
        {PCI_VENDOR_ID_CIRRUS,          "Cirrus Logic"}, \
        {PCI_VENDOR_ID_BUSLOGIC,        "Bus Logic"}, \
        {PCI_VENDOR_ID_N9,              "Number #9"}, \
        {PCI_VENDOR_ID_ALI,             "ALI"}, \
        {PCI_VENDOR_ID_TSENG,           "Tseng'Lab"}, \
-       {0,                             "Unknown vendor"} \
+       {PCI_VENDOR_ID_CMD,             "CMD"}, \
+       {0,                             ""} \
 }
 
 struct pci_device_type {
@@ -284,7+289,7 @@ struct pci_device_type {
        char *device_name;
 };
 
-#define PCI_DEVICE_NUM 31
+#define PCI_DEVICE_NUM 33
 #define PCI_DEVICE_TYPE { \
        {PCI_VENDOR_ID_NCR,     PCI_DEVICE_ID_NCR_53C810,       "53c810"}, \
        {PCI_VENDOR_ID_NCR,     PCI_DEVICE_ID_NCR_53C815,       "53c815"}, \
@@ -311,12+316,14 @@ struct pci_device_type {
        {PCI_VENDOR_ID_SMC,     PCI_DEVICE_ID_SMC_37C665,       "FDC 37C665"}, \
        {PCI_VENDOR_ID_ATI,     PCI_DEVICE_ID_ATI_M32,          "Mach 32"}, \
        {PCI_VENDOR_ID_ATI,     PCI_DEVICE_ID_ATI_M64,          "Mach 64"}, \
-       {PCI_VENDOR_ID_DIAMOND, PCI_DEVICE_ID_DIAMOND_VIPER,    "Viper"}, \
+       {PCI_VENDOR_ID_WEITEK,  PCI_DEVICE_ID_WEITEK_P9000,     "P9000"}, \
+       {PCI_VENDOR_ID_WEITEK,  PCI_DEVICE_ID_WEITEK_P9100,     "P9100"}, \
        {PCI_VENDOR_ID_CIRRUS,  PCI_DEVICE_ID_CIRRUS_5434,      "GD 5434"}, \
        {PCI_VENDOR_ID_BUSLOGIC,PCI_DEVICE_ID_BUSLOGIC_946C,    "946C"}, \
        {PCI_VENDOR_ID_N9,      PCI_DEVICE_ID_N9_I128,          "Imagine 128"}, \
        {PCI_VENDOR_ID_ALI,     PCI_DEVICE_ID_ALI_M1435,        "M1435"}, \
-       {PCI_VENDOR_ID_ALI,     PCI_DEVICE_ID_TSENG_W32P,       "ET4000W32P"}, \
+       {PCI_VENDOR_ID_TSENG,   PCI_DEVICE_ID_TSENG_W32P,       "ET4000W32P"}, \
+       {PCI_VENDOR_ID_CMD,     PCI_DEVICE_ID_CMD_640,          "640A"}, \
        {0,0,"UNKNOWN DEVICE.PLEASE FIND OUT AND MAIL POTTER@CAO-VLSI.IBP.FR"} \
 }
 
index 5ad487f..c68a376 100644 (file)
@@ -16,7+16,7 @@ extern char * strcpy(char *,const char *);
 extern char * strncpy(char *,const char *,size_t);
 extern char * strcat(char *, const char *);
 extern char * strncat(char *, const char *, size_t);
-extern char * strchr(const char *,char);
+extern char * strchr(const char *,int);
 extern char * strpbrk(const char *,const char *);
 extern char * strtok(char *,const char *);
 extern char * strstr(const char *,const char *);
@@ -25,10+25,10 @@ extern size_t strspn(const char *,const char *);
 extern int strcmp(const char *,const char *);
 extern int strncmp(const char *,const char *,size_t);
 
-extern void * memset(void *,char,size_t);
+extern void * memset(void *,int,size_t);
 extern void * memcpy(void *,const void *,size_t);
 extern void * memmove(void *,const void *,size_t);
-extern void * memscan(void *, unsigned char, size_t);
+extern void * memscan(void *,int,size_t);
 extern int memcmp(const void *,const void *,size_t);
 
 /*
index 701871d..9d24d31 100644 (file)
@@ -247,7+247,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
        X(kfree_skb),
        X(dev_kfree_skb),
        X(snarf_region),
-       X(register_iomem),
+       X(request_region),
        X(release_region),
        X(netif_rx),
        X(dev_rint),
index 22b7b60..cd8fa65 100644 (file)
@@ -117,9+117,11 @@ asmlinkage unsigned long sys_signal(int signum, void (*handler)(int))
                return -EINVAL;
        if (signum==SIGKILL || signum==SIGSTOP)
                return -EINVAL;
-       err = verify_area(VERIFY_READ, handler, 1);
-       if (err)
-               return err;
+       if (handler != SIG_DFL && handler != SIG_IGN) {
+               err = verify_area(VERIFY_READ, handler, 1);
+               if (err)
+                       return err;
+       }
        tmp.sa_handler = handler;
        tmp.sa_mask = 0;
        tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
@@ -151,9+153,11 @@ asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
                        new_sa.sa_mask |= _S(signum);
                        new_sa.sa_mask &= _BLOCKABLE;
                }
-               err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
-               if (err)
-                       return err;
+               if (new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
+                       err = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
+                       if (err)
+                               return err;
+               }
        }
        if (oldaction) {
                int err = verify_area(VERIFY_WRITE, oldaction, sizeof(*oldaction));
index 8b8f717..96d527c 100644 (file)
@@ -137,8+137,8 @@ for (order = 0;BLOCKSIZE(order);order++)
         AREASIZE(order)) 
         {
         printk ("Cannot use %d bytes out of %d in order = %d block mallocs\n",
-                NBLOCKS (order) * BLOCKSIZE(order) + 
-                        sizeof (struct page_descriptor),
+                (int) (NBLOCKS (order) * BLOCKSIZE(order) + 
+                        sizeof (struct page_descriptor)),
                 (int) AREASIZE(order),
                 BLOCKSIZE (order));
         panic ("This only happens if someone messes with kmalloc");
@@ -185,7+185,7 @@ void * kmalloc (size_t size, int priority)
 order = get_order (size);
 if (order < 0)
     {
-    printk ("kmalloc of too large a block (%d bytes).\n",size);
+    printk ("kmalloc of too large a block (%d bytes).\n",(int) size);
     return (NULL);
     }
 
@@ -288,7+288,7 @@ printk ("Hey. This is very funny. I tried %d times to allocate a whole\n"
         "the author of this kmalloc: wolff@dutecai.et.tudelft.nl.\n"
         "(Executive summary: This can't happen)\n", 
                 MAX_GET_FREE_PAGE_TRIES,
-                size);
+                (int) size);
 return NULL;
 }
 
index ac47f72..75f2354 100644 (file)
@@ -738,6+738,10 @@ static int inet_release(struct socket *sock, struct socket *peer)
 
        /* Start closing the connection.  This may take a while. */
 
+#ifdef CONFIG_IP_MULTICAST
+       /* Applications forget to leave groups before exiting */
+       ip_mc_drop_socket(sk);
+#endif
        /*
         * If linger is set, we don't return until the close
         * is complete.  Other wise we return immediately. The
index c78097f..efdaa00 100644 (file)
@@ -109,7+109,7 @@ void dev_mc_delete(struct device *dev, void *addr, int alen, int all)
                if(memcmp((*dmi)->dmi_addr,addr,(*dmi)->dmi_addrlen)==0 && alen==(*dmi)->dmi_addrlen)
                {
                        struct dev_mc_list *tmp= *dmi;
-                       if((*dmi)->dmi_users-- && !all)
+                       if(--(*dmi)->dmi_users && !all)
                                return;
                        *dmi=(*dmi)->next;
                        dev->mc_count--;
index 68892ad..e82829e 100644 (file)
@@ -128,12+128,6 @@ struct ip_mib ip_statistics={1,64,};       /* Forwarding=Yes, Default TTL=64 */
 struct ip_mib ip_statistics={0,64,};   /* Forwarding=No, Default TTL=64 */
 #endif
 
-#ifdef CONFIG_IP_MULTICAST
-
-struct ip_mc_list *ip_mc_head=NULL;
-
-#endif
-
 /*
  *     Handle the issuing of an ioctl() request
  *     for the ip device. This is scheduled to
@@ -2020,26+2014,34 @@ int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length)
        struct ip_mc_list *im;
        unsigned long flags;
        int len=0;
+       struct device *dev;
        
-       
-       len=sprintf(buffer,"Device    : Multicast\n");  
+       len=sprintf(buffer,"Device    : Count\tGroup    Users Timer\n");  
        save_flags(flags);
        cli();
        
-       im=ip_mc_head;
-       
-       while(im!=NULL)
+       for(dev = dev_base; dev; dev = dev->next)
        {
-               len+=sprintf(buffer+len,"%-10s: %08lX\n", im->interface->name, im->multiaddr);
-               pos=begin+len;
-               if(pos<offset)
-               {
-                       len=0;
-                       begin=pos;
-               }
-               if(pos>offset+length)
-                       break;
-               im=im->next;
+                if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST))
+                {
+                        len+=sprintf(buffer+len,"%-10s: %5d\n",
+                                       dev->name, dev->mc_count);
+                        for(im = dev->ip_mc_list; im; im = im->next)
+                        {
+                                len+=sprintf(buffer+len,
+                                       "\t\t\t%08lX %5d %d:%08lX\n",
+                                        im->multiaddr, im->users,
+                                       im->tm_running, im->timer.expires);
+                                pos=begin+len;
+                                if(pos<offset)
+                                {
+                                        len=0;
+                                        begin=pos;
+                                }
+                                if(pos>offset+length)
+                                        break;
+                        }
+                }
        }
        restore_flags(flags);
        *start=buffer+(offset-begin);
index e4c0b32..ad648dc 100644 (file)
@@ -640,7+640,7 @@ static void retransmit_timer(unsigned long data)
                         * this reset_timer() call is a hack, this is not
                         * how KEEPOPEN is supposed to work.
                         */
-                       reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
+                       reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
 
                        /* Send something to keep the connection open. */
                        if (sk->prot->write_wakeup)
close