]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.19 2.1.19
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:48 +0000 (15:12 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:48 +0000 (15:12 -0500)
221 files changed:
Documentation/Configure.help
Makefile
arch/sparc/defconfig
arch/sparc/kernel/entry.S
arch/sparc/kernel/head.S
arch/sparc/kernel/process.c
arch/sparc/kernel/rtrap.S
arch/sparc/kernel/setup.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sunos.c
arch/sparc/kernel/systbls.S
arch/sparc/kernel/traps.c
arch/sparc/kernel/wof.S
arch/sparc/kernel/wuf.S
arch/sparc/mm/extable.c
arch/sparc/mm/loadmmu.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/sparc/prom/tree.c
arch/sparc64/Makefile [new file with mode: 0644]
arch/sparc64/config.in [new file with mode: 0644]
arch/sparc64/defconfig [new file with mode: 0644]
arch/sparc64/kernel/Makefile [new file with mode: 0644]
arch/sparc64/kernel/dtlb_miss.S [new file with mode: 0644]
arch/sparc64/kernel/dtlb_prot.S [new file with mode: 0644]
arch/sparc64/kernel/etrap.S [new file with mode: 0644]
arch/sparc64/kernel/finitobj.S [new file with mode: 0644]
arch/sparc64/kernel/head.S [new file with mode: 0644]
arch/sparc64/kernel/idprom.c [new file with mode: 0644]
arch/sparc64/kernel/initobj.S [new file with mode: 0644]
arch/sparc64/kernel/ioport.c [new file with mode: 0644]
arch/sparc64/kernel/itlb_miss.S [new file with mode: 0644]
arch/sparc64/kernel/process.c [new file with mode: 0644]
arch/sparc64/kernel/signal32.c [new file with mode: 0644]
arch/sparc64/kernel/systbls.S [new file with mode: 0644]
arch/sparc64/kernel/ttable.S [new file with mode: 0644]
arch/sparc64/lib/Makefile [new file with mode: 0644]
arch/sparc64/lib/blockops.S [new file with mode: 0644]
arch/sparc64/lib/memset.S [new file with mode: 0644]
arch/sparc64/mm/Makefile [new file with mode: 0644]
arch/sparc64/mm/asyncd.c [new file with mode: 0644]
arch/sparc64/mm/extable.c [new file with mode: 0644]
arch/sparc64/mm/fault.c [new file with mode: 0644]
arch/sparc64/mm/generic.c [new file with mode: 0644]
arch/sparc64/mm/init.c [new file with mode: 0644]
arch/sparc64/prom/Makefile [new file with mode: 0644]
arch/sparc64/prom/bootstr.c [new file with mode: 0644]
arch/sparc64/prom/console.c [new file with mode: 0644]
arch/sparc64/prom/devops.c [new file with mode: 0644]
arch/sparc64/prom/init.c [new file with mode: 0644]
arch/sparc64/prom/k1275d.c [new file with mode: 0644]
arch/sparc64/prom/misc.c [new file with mode: 0644]
arch/sparc64/prom/printf.c [new file with mode: 0644]
arch/sparc64/prom/tree.c [new file with mode: 0644]
drivers/block/genhd.c
drivers/char/tty_ioctl.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c523.c
drivers/net/ac3200.c
drivers/net/apricot.c
drivers/net/arcnet.c
drivers/net/at1700.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/atarilance.c
drivers/net/baycom.c
drivers/net/de4x5.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/depca.c
drivers/net/dgrs.c
drivers/net/e2100.c
drivers/net/eepro.c
drivers/net/eexpress.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/ewrk3.c
drivers/net/fmv18x.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/ibmtr.c
drivers/net/mkiss.c
drivers/net/ne.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/plip.c
drivers/net/ppp.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc9194.c
drivers/net/soundmodem.c
drivers/net/sunlance.c
drivers/net/wd.c
drivers/sbus/char/bwtwo.c
drivers/sbus/char/cgfourteen.c
drivers/sbus/char/cgsix.c
drivers/sbus/char/cgthree.c
drivers/sbus/char/fb.h
drivers/sbus/char/leo.c
drivers/sbus/char/suncons.c
drivers/sbus/char/sunfb.c
drivers/sbus/char/tcx.c
drivers/sbus/char/weitek.c
drivers/scsi/scsi.h
fs/exec.c
fs/fat/inode.c
fs/ncpfs/dir.c
fs/ncpfs/inode.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/ncplib_kernel.h
fs/proc/openpromfs.c
fs/select.c
fs/smbfs/proc.c
fs/ufs/ufs_super.c
include/asm-alpha/current.h [new file with mode: 0644]
include/asm-alpha/mmu_context.h
include/asm-alpha/processor.h
include/asm-alpha/scatterlist.h [new file with mode: 0644]
include/asm-alpha/termios.h
include/asm-i386/current.h [new file with mode: 0644]
include/asm-i386/mmu_context.h
include/asm-i386/processor.h
include/asm-i386/scatterlist.h [new file with mode: 0644]
include/asm-i386/termios.h
include/asm-i386/unistd.h
include/asm-m68k/current.h [new file with mode: 0644]
include/asm-m68k/mmu_context.h
include/asm-m68k/processor.h
include/asm-m68k/scatterlist.h [new file with mode: 0644]
include/asm-m68k/termios.h
include/asm-mips/current.h [new file with mode: 0644]
include/asm-mips/processor.h
include/asm-mips/scatterlist.h [new file with mode: 0644]
include/asm-mips/termios.h
include/asm-ppc/current.h [new file with mode: 0644]
include/asm-ppc/mmu_context.h
include/asm-ppc/processor.h
include/asm-ppc/scatterlist.h [new file with mode: 0644]
include/asm-ppc/termios.h
include/asm-sparc/atomic.h
include/asm-sparc/bitops.h
include/asm-sparc/cache.h
include/asm-sparc/current.h [new file with mode: 0644]
include/asm-sparc/mmu_context.h
include/asm-sparc/pgtable.h
include/asm-sparc/processor.h
include/asm-sparc/scatterlist.h [new file with mode: 0644]
include/asm-sparc/signal.h
include/asm-sparc/system.h
include/asm-sparc/termios.h
include/asm-sparc/unistd.h
include/asm-sparc64/a.out.h
include/asm-sparc64/bitops.h
include/asm-sparc64/bsderrno.h [new file with mode: 0644]
include/asm-sparc64/bugs.h [new file with mode: 0644]
include/asm-sparc64/byteorder.h
include/asm-sparc64/current.h [new file with mode: 0644]
include/asm-sparc64/dma.h
include/asm-sparc64/elf.h
include/asm-sparc64/head.h [new file with mode: 0644]
include/asm-sparc64/io.h [new file with mode: 0644]
include/asm-sparc64/iommu.h [new file with mode: 0644]
include/asm-sparc64/ipc.h [new file with mode: 0644]
include/asm-sparc64/irq.h [new file with mode: 0644]
include/asm-sparc64/lsu.h [new file with mode: 0644]
include/asm-sparc64/mmu_context.h [new file with mode: 0644]
include/asm-sparc64/mostek.h [new file with mode: 0644]
include/asm-sparc64/namei.h [new file with mode: 0644]
include/asm-sparc64/openprom.h [new file with mode: 0644]
include/asm-sparc64/openpromio.h [new file with mode: 0644]
include/asm-sparc64/oplib.h [new file with mode: 0644]
include/asm-sparc64/page.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/posix_types.h [new file with mode: 0644]
include/asm-sparc64/processor.h [new file with mode: 0644]
include/asm-sparc64/psrcompat.h [new file with mode: 0644]
include/asm-sparc64/pstate.h
include/asm-sparc64/ptrace.h
include/asm-sparc64/reg.h [new file with mode: 0644]
include/asm-sparc64/resource.h [new file with mode: 0644]
include/asm-sparc64/rtc.h [new file with mode: 0644]
include/asm-sparc64/sbus.h [new file with mode: 0644]
include/asm-sparc64/scatterlist.h [new file with mode: 0644]
include/asm-sparc64/segment.h [new file with mode: 0644]
include/asm-sparc64/shmparam.h [new file with mode: 0644]
include/asm-sparc64/sigcontext.h [new file with mode: 0644]
include/asm-sparc64/signal.h [new file with mode: 0644]
include/asm-sparc64/smp.h [new file with mode: 0644]
include/asm-sparc64/smp_lock.h [new file with mode: 0644]
include/asm-sparc64/socket.h [new file with mode: 0644]
include/asm-sparc64/sockios.h [new file with mode: 0644]
include/asm-sparc64/solerrno.h [new file with mode: 0644]
include/asm-sparc64/spitfire.h [new file with mode: 0644]
include/asm-sparc64/stat.h [new file with mode: 0644]
include/asm-sparc64/statfs.h [new file with mode: 0644]
include/asm-sparc64/string.h [new file with mode: 0644]
include/asm-sparc64/svr4.h [new file with mode: 0644]
include/asm-sparc64/system.h
include/asm-sparc64/termbits.h [new file with mode: 0644]
include/asm-sparc64/termios.h [new file with mode: 0644]
include/asm-sparc64/uaccess.h [new file with mode: 0644]
include/asm-sparc64/unaligned.h [new file with mode: 0644]
include/asm-sparc64/unistd.h [new file with mode: 0644]
include/asm-sparc64/upa.h [new file with mode: 0644]
include/asm-sparc64/user.h [new file with mode: 0644]
include/asm-sparc64/vuid_event.h [new file with mode: 0644]
include/asm-sparc64/winmacro.h [new file with mode: 0644]
include/linux/msdos_fs.h
include/linux/ncp.h
include/linux/sched.h
include/linux/uio.h
kernel/exit.c
kernel/fork.c
mm/mmap.c

index 65a0c4d639095ac85b65f7b162189578ff7455cd..03fb817f352c830f340ac07039d1b5f8b83b9278 100644 (file)
@@ -4063,6 +4063,11 @@ CONFIG_SUN_AUDIO
   This is support for the soundcards on Sun workstations. The code
   does not exist yet, so you might as well say N here.
 
+SB32/AWE support
+CONFIG_AWE32_SYNTH
+Enable this option if you have a SB32 or SB AWE soundcard. See
+linux/drivers/sound/lowlevel/README.awe for more info.
+
 Kernel profiling support
 CONFIG_PROFILE
   This is for kernel hackers who want to know how much time the kernel
index b7aa5f52fed86ffc0ad27715857b1b540c4324c5..4e38bc09ab0aef41abdbc9375834f5cd6b3fff8e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 18
+SUBLEVEL = 19
 
 ARCH = i386
 
index 29228d24e87422ea9228f1fc96672ce72cab03a8..1bbcec84ad2c4805ecc1fb8fea0132406769a030 100644 (file)
@@ -11,7 +11,7 @@ CONFIG_EXPERIMENTAL=y
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KERNELD=y
 
 #
index 25476be280c9c5bb67c058dff6436603011f3e4e..72168f594a0335e2cc46f6d338a17ca862e6efc2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.128 1996/12/18 06:33:39 tridge Exp $
+/* $Id: entry.S,v 1.129 1996/12/30 00:31:07 davem Exp $
  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1722,4 +1722,42 @@ flush_patch_exception:
        jmpl    %o7 + 0xc, %g0                  ! see asm-sparc/processor.h
         mov    1, %g1                          ! signal EFAULT condition
 
+       .align  4
+       .globl  C_LABEL(kill_user_windows), kuw_patch1_7win
+       .globl  kuw_patch1
+kuw_patch1_7win:       sll     %o3, 6, %o3
+
+       /* No matter how much overhead this routine has in the worst
+        * case scenerio, it is several times better than taking the
+        * traps with the old method of just doing flush_user_windows().
+        */
+C_LABEL(kill_user_windows):
+       ld      [%g6 + THREAD_UMASK], %o0       ! get current umask
+       orcc    %g0, %o0, %g0                   ! if no bits set, we are done
+       be      3f                              ! nothing to do
+        rd     %psr, %o5                       ! must clear interrupts
+       or      %o5, PSR_PIL, %o4               ! or else that could change
+       wr      %o4, 0x0, %psr                  ! the uwinmask state
+       WRITE_PAUSE                             ! burn them cycles
+1:
+       ld      [%g6 + THREAD_UMASK], %o0       ! get consistant state
+       orcc    %g0, %o0, %g0                   ! did an interrupt come in?
+       be      4f                              ! yep, we are done
+        rd     %wim, %o3                       ! get current wim
+       srl     %o3, 1, %o4                     ! simulate a save
+kuw_patch1:
+       sll     %o3, 7, %o3                     ! compute next wim
+       or      %o4, %o3, %o3                   ! result
+       andncc  %o0, %o3, %o0                   ! clean this bit in umask
+       bne     kuw_patch1                      ! not done yet
+        srl    %o3, 1, %o4                     ! begin another save simulation
+       wr      %o3, 0x0, %wim                  ! set the new wim
+       st      %g0, [%g6 + THREAD_UMASK]       ! clear uwinmask
+4:
+       wr      %o5, 0x0, %psr                  ! re-enable interrupts
+       WRITE_PAUSE                             ! burn baby burn
+3:
+       retl                                    ! return
+        st     %g0, [%g6 + THREAD_W_SAVED]     ! no windows saved
+
 /* End of entry.S */
index d756630fafb21af5046d3bf1e5f93143f7c3bded..8484eb4b785bfe992bd367d05775cbfec3cc0cae 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.75 1996/12/20 07:54:57 davem Exp $
+/* $Id: head.S,v 1.76 1996/12/30 00:31:09 davem Exp $
  * head.S: The initial boot code for the Sparc port of Linux.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1062,6 +1062,10 @@ sun4c_continue_boot:
                PATCH_INSN(rirq_7win_patch5, rirq_patch5)
 
 #endif
+
+               /* Patch for killing user windows from the register file. */
+               PATCH_INSN(kuw_patch1_7win, kuw_patch1)
+
                /* Now patch the kernel window flush sequences.
                 * This saves 2 traps on every switch and fork.
                 */
index 04c8c130ee8db8a5d064c628d1d67edc06d59781..2d39132566de5eac2323ba15979d5e4ab0a6aa6f 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.85 1996/12/18 06:33:42 tridge Exp $
+/*  $Id: process.c,v 1.87 1996/12/30 06:16:21 davem Exp $
  *  linux/arch/sparc/kernel/process.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -280,7 +280,7 @@ void show_thread(struct thread_struct *tss)
  */
 void exit_thread(void)
 {
-       flush_user_windows();
+       kill_user_windows();
 #ifndef __SMP__
        if(last_task_used_math == current) {
 #else
@@ -296,15 +296,13 @@ void exit_thread(void)
                current->flags &= ~PF_USEDFPU;
 #endif
        }
-       mmu_exit_hook();
 }
 
 void flush_thread(void)
 {
        /* Make sure old user windows don't get in the way. */
-       flush_user_windows();
-       current->tss.w_saved = 0;
-       current->tss.uwinmask = 0;
+       kill_user_windows();
+
        current->tss.sstk_info.cur_status = 0;
        current->tss.sstk_info.the_stack = 0;
 
@@ -326,7 +324,6 @@ void flush_thread(void)
 #endif
        }
 
-       mmu_flush_hook();
        /* Now, this task is no longer a kernel thread. */
        current->tss.flags &= ~SPARC_FLAG_KTHREAD;
        current->tss.current_ds = USER_DS;
index 51ec98f9565c92b179dc9236cc61db64d8fce68c..04b0695e470e192ffeb0fec66e411a0fcde66b4d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.40 1996/12/10 06:06:18 davem Exp $
+/* $Id: rtrap.S,v 1.41 1996/12/28 18:14:21 davem Exp $
  * rtrap.S: Return from Sparc trap low-level code.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -70,7 +70,6 @@ ret_trap_entry:
         sethi  %hi(C_LABEL(need_resched)), %twin_tmp1
 
        wr      %t_psr, 0x0, %psr
-       WRITE_PAUSE
        b       ret_trap_kernel
         nop
 
@@ -179,7 +178,6 @@ ret_trap_unaligned_pc:
        ld      [%sp + REGWIN_SZ + PT_PSR], %o3
 
        wr      %t_wim, 0x0, %wim               ! or else...
-       WRITE_PAUSE
 
        wr      %t_psr, PSR_ET, %psr
        WRITE_PAUSE
@@ -206,7 +204,6 @@ rtrap_patch4:       srl     %g2, 7,  %g2
 rtrap_patch5:  and     %g1, 0xff, %g1
 
        wr      %g1, 0x0, %wim
-       WRITE_PAUSE
 
        /* Grrr, make sure we load from the right %sp... */
        LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
@@ -232,7 +229,6 @@ rtrap_patch5:       and     %g1, 0xff, %g1
 
 ret_trap_user_stack_is_bolixed:
        wr      %t_wim, 0x0, %wim
-       WRITE_PAUSE
 
        wr      %t_psr, PSR_ET, %psr
        WRITE_PAUSE
index be6cc488d7ccf292445f116dc0091b4c368cd044..150eab9d4716026086c9bfd60477ef60bc6c49cc 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.78 1996/12/19 08:06:30 davem Exp $
+/*  $Id: setup.c,v 1.79 1996/12/23 10:57:02 ecd Exp $
  *  linux/arch/sparc/kernel/setup.c
  *
  *  Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
@@ -248,7 +248,7 @@ extern unsigned ramdisk_size;
 
 extern int root_mountflags;
 
-extern void register_console(void (*proc)(char *));
+extern void register_console(void (*proc)(const char *));
 
 char saved_command_line[256];
 char reboot_command[256];
@@ -310,7 +310,7 @@ __initfunc(void setup_arch(char **cmdline_p,
                printk("SUN4U\n");
                break;
        case ap1000:
-               register_console(prom_printf);
+               register_console((void (*) (const char *))prom_printf);
                printk("AP1000\n");
                packed = 1;
                break;
index 629694eda133ab9257af93e062e4fe34f2c5a0b1..3bfe00f732079581b621e1f9a49f9530ad91a0fd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.32 1996/12/18 06:33:45 tridge Exp $
+/* $Id: sparc_ksyms.c,v 1.33 1996/12/29 20:46:01 davem Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
index 20e4d98cca8f30ab208e55cc81614ad95a1b6772..947c9ae047b7501f9632d4d5a5c046fde1589f3f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.32 1996/12/19 05:25:46 davem Exp $
+/* $Id: sys_sparc.c,v 1.33 1996/12/24 08:59:33 davem Exp $
  * linux/arch/sparc/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -201,18 +201,47 @@ sparc_breakpoint (struct pt_regs *regs)
 #endif
 }
 
-extern int
-sys_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction);
+extern void check_pending(int signum);
 
 asmlinkage int
 sparc_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction)
 {
-    if (signum >= 0){
-       return sys_sigaction (signum, action, oldaction);
-    } else {
-       current->tss.new_signal = 1;
-       return sys_sigaction (-signum, action, oldaction);
-    }
+       struct sigaction new_sa, *p;
+
+       if(signum < 0) {
+               current->tss.new_signal = 1;
+               signum = -signum;
+       }
+
+       if (signum<1 || signum>32)
+               return -EINVAL;
+       p = signum - 1 + current->sig->action;
+       if (action) {
+               int err = verify_area(VERIFY_READ,action,sizeof(struct sigaction));
+               if (err)
+                       return err;
+               if (signum==SIGKILL || signum==SIGSTOP)
+                       return -EINVAL;
+               if(copy_from_user(&new_sa, action, sizeof(struct sigaction)))
+                       return -EFAULT; 
+               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) {
+               if (copy_to_user(oldaction, p, sizeof(struct sigaction)))
+                       return -EFAULT; 
+       }
+
+       if (action) {
+               *p = new_sa;
+               check_pending(signum);
+       }
+
+       return 0;
 }
 
 #ifndef CONFIG_AP1000
index 67bcf8cea52b1d64b4b42fc15c07630a05625f54..8d019b315d06f1507617ec1fd8e28a75a99da317 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.69 1996/12/21 04:50:38 tridge Exp $
+/* $Id: sys_sunos.c,v 1.71 1996/12/29 20:46:02 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -26,7 +26,6 @@
  * to do the inverse mapping.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -1155,49 +1154,52 @@ asmlinkage int sunos_accept(int fd, struct sockaddr *sa, int *addrlen)
 
 #define SUNOS_SV_INTERRUPT 2
 
-extern asmlinkage int sys_sigaction(int, const struct sigaction *, struct sigaction *);
+extern void check_pending(int signum);
 
 asmlinkage int sunos_sigaction(int signum, const struct sigaction *action,
        struct sigaction *oldaction)
 {
-       struct sigaction tmp_sa, *tmp_sap;
+       struct sigaction new_sa, *p;
        const  int sigaction_size = sizeof (struct sigaction) - sizeof (void *);
        int err;
-       int old_fs = USER_DS;
 
        current->personality |= PER_BSD;
 
+       if (signum<1 || signum>32)
+               return -EINVAL;
+
+       p = signum - 1 + current->sig->action;
        if (action) {
-               if(copy_from_user(&tmp_sa, action, sigaction_size))
+               if(copy_from_user(&new_sa, action, sigaction_size))
                        return -EFAULT;
-               if (oldaction) {
-                       err = verify_area(VERIFY_WRITE,oldaction,sigaction_size);
+               if (signum==SIGKILL || signum==SIGSTOP)
+                       return -EINVAL;
+               memset(&new_sa, 0, sizeof(struct sigaction));
+               if(copy_from_user(&new_sa, action, sigaction_size))
+                       return -EFAULT; 
+               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 (tmp_sa.sa_flags & SUNOS_SV_INTERRUPT)
-                       tmp_sa.sa_flags &= ~SUNOS_SV_INTERRUPT;
-               else
-                       tmp_sa.sa_flags |= SA_RESTART;
-               old_fs = get_fs ();
-               set_fs (get_ds ());
-               tmp_sap = &tmp_sa;
-       } else {
-               tmp_sap = (struct sigaction *) action;
+               new_sa.sa_flags ^= SUNOS_SV_INTERRUPT;
        }
 
-       err = sys_sigaction (signum, tmp_sap, oldaction);
-
-       if (err == 0 && oldaction){
+       if (oldaction) {
+               if (copy_to_user(oldaction, p, sigaction_size))
+                       return -EFAULT; 
                if (oldaction->sa_flags & SA_RESTART)
                        oldaction->sa_flags &= ~SA_RESTART;
                else
                        oldaction->sa_flags |= SUNOS_SV_INTERRUPT;
        }
-       if (action)
-               set_fs (old_fs);
-       return err;
+
+       if (action) {
+               *p = new_sa;
+               check_pending(signum);
+       }
+
+       return 0;
 }
 
 
index f78864cc7c7ba9a7169fc57fa2fa7e12e96fa1aa..4bf526c1d64324a90b0c11bc2f7531e96cac21c6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.55 1996/12/18 06:33:47 tridge Exp $
+/* $Id: systbls.S,v 1.56 1996/12/29 20:46:03 davem Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -106,7 +106,7 @@ C_LABEL(sys_call_table):
        .long C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
        .long C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
        .long C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
-       .long C_LABEL(sys_nis_syscall), C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+       .long C_LABEL(sys_nis_syscall), C_LABEL(sys_sigpending), C_LABEL(sys_query_module)
        .long C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
        .long C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
        .long C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
index 71137c51ff29ba2fc67a71cac62af8d0656e95c9..08cd59fda570a447192d2a713ea932ad4a7126da 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.49 1996/12/18 06:33:49 tridge Exp $
+/* $Id: traps.c,v 1.50 1996/12/29 20:46:05 davem Exp $
  * arch/sparc/kernel/traps.c
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -10,7 +10,6 @@
 
 #include <linux/sched.h>  /* for jiffies */
 #include <linux/kernel.h>
-#include <linux/config.h>
 #include <linux/signal.h>
 
 #include <asm/delay.h>
index 584d3eb53add20479488d658eefd6d15e250b466..823f9d1fce5ee7f8d7a944b6691d21d024532404 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: wof.S,v 1.30 1996/12/10 06:06:19 davem Exp $
+/* $Id: wof.S,v 1.31 1996/12/28 18:14:22 davem Exp $
  * wof.S: Sparc window overflow handler.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -205,7 +205,6 @@ spwin_user_stack_is_bolixed:
         * c-code to gun down the process.
         */
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        andcc   %glob_tmp, PSR_PS, %g0
        bne     spwin_bad_ustack_from_kernel
         nop
@@ -249,8 +248,7 @@ spnwin_patch3:      and     %twin_tmp, 0xff, %twin_tmp      ! patched on 7win Sparcs
 
        /* Turn on traps and call c-code to deal with it. */
        wr      %t_psr, PSR_ET, %psr
-       WRITE_PAUSE
-
+       nop
        call    C_LABEL(window_overflow_fault)
         nop
 
@@ -316,7 +314,6 @@ C_LABEL(spwin_sun4c_stackchk):
         sra    %sp, 29, %glob_tmp
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4
         nop
 
@@ -327,7 +324,6 @@ C_LABEL(spwin_sun4c_stackchk):
         and    %sp, 0xfff, %glob_tmp           ! delay slot
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4
         nop
 
@@ -348,7 +344,6 @@ spwin_sun4c_twopages:
         add    %sp, 0x38, %glob_tmp    /* Is second page in vma hole? */
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4
         nop
 
@@ -360,7 +355,6 @@ spwin_sun4c_twopages:
         add    %sp, 0x38, %glob_tmp
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4
         nop
 
@@ -374,7 +368,6 @@ spwin_sun4c_onepage:
         nop
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4
         nop
 
@@ -429,6 +422,5 @@ C_LABEL(spwin_srmmu_stackchk):
         restore %g0, %g0, %g0
 
        rd      %psr, %glob_tmp
-       WRITE_PAUSE
        b       spwin_user_stack_is_bolixed + 0x4       ! we faulted, ugh
         nop
index 6ece3118ef67abff61d58c56c31c10e24a96c21d..a1f198050375ce15fd455067b671e54e335c6bfc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: wuf.S,v 1.28 1996/12/10 06:06:20 davem Exp $
+/* $Id: wuf.S,v 1.29 1996/12/28 18:14:23 davem Exp $
  * wuf.S: Window underflow trap handler for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller
@@ -184,8 +184,7 @@ fwin_user_stack_is_bolixed:
        ENTER_SYSCALL
 
        wr      %t_psr, PSR_ET, %psr                    ! enable traps
-       WRITE_PAUSE
-
+       nop
        call    C_LABEL(window_underflow_fault)
         mov    %g4, %o0
 
@@ -343,7 +342,7 @@ C_LABEL(srmmu_fwin_stackchk):
         nop
 
        wr      %t_psr, 0x0, %psr
-       WRITE_PAUSE
+       nop
        b       fwin_user_finish_up + 0x4
         nop
 
index dfbcab8dc3f6ce5275eb2b8415fe9cf773bd8351..7fe26ad96edda0f499518fd6db79f9e96528e582 100644 (file)
@@ -37,7 +37,7 @@ search_one_table(const struct exception_table_entry *start,
         }
         if (first > start && first[-1].insn < value
            && !first[-1].fixup && first->insn < value) {
-               *g2 = (value - firstp[-1].insn)/4;
+               *g2 = (value - first[-1].insn)/4;
                return first->fixup;
         }
         return 0;
@@ -60,7 +60,7 @@ search_exception_table(unsigned long addr, unsigned long *g2)
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
-                                      mp->ex_table_stop-1, addr, g2);
+                                      mp->ex_table_end-1, addr, g2);
                if (ret) return ret;
        }
 #endif
index 4e5ba0ebc1dea1bd5a1537035b164df73161dfc4..2c31f0a74384dad06bf034f884363c2c045198e7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: loadmmu.c,v 1.43 1996/12/18 06:43:24 tridge Exp $
+/* $Id: loadmmu.c,v 1.45 1996/12/30 06:16:28 davem Exp $
  * loadmmu.c:  This code loads up all the mm function pointers once the
  *             machine type has been determined.  It also sets the static
  *             mmu values such as PAGE_NONE, etc.
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/a.out.h>
+#include <asm/mmu_context.h>
 
 unsigned long page_offset = 0xf0000000;
 unsigned long stack_top = 0xf0000000 - PAGE_SIZE;
@@ -30,8 +31,8 @@ void (*free_task_struct)(struct task_struct *tsk);
 
 void (*quick_kernel_fault)(unsigned long);
 
-void (*mmu_exit_hook)(void);
-void (*mmu_flush_hook)(void);
+void (*init_new_context)(struct mm_struct *mm);
+void (*destroy_context)(struct mm_struct *mm);
 
 /* translate between physical and virtual addresses */
 unsigned long (*mmu_v2p)(unsigned long);
@@ -135,7 +136,6 @@ pmd_t * (*pmd_alloc)(pgd_t *, unsigned long);
 void (*pgd_free)(pgd_t *);
 
 pgd_t * (*pgd_alloc)(void);
-void (*pgd_flush)(pgd_t *);
 
 int (*pte_write)(pte_t);
 int (*pte_dirty)(pte_t);
index 1e2665b9e0b5d7aafb551e72c206c96b535ffa6f..20efc8a1bf4808b41fdd2b6c7cdab36ac77ea36d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.119 1996/12/19 08:06:37 davem Exp $
+/* $Id: srmmu.c,v 1.122 1996/12/30 06:16:31 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
@@ -28,6 +28,7 @@
 #include <asm/asi.h>
 #include <asm/msi.h>
 #include <asm/a.out.h>
+#include <asm/mmu_context.h>
 
 /* Now the cpu specific definitions. */
 #include <asm/viking.h>
@@ -284,48 +285,6 @@ static void srmmu_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp)
        }
 }
 
-static inline void srmmu_uncache_page(unsigned long addr)
-{
-       pgd_t *pgdp = srmmu_pgd_offset(init_task.mm, addr);
-       pmd_t *pmdp;
-       pte_t *ptep;
-
-       if((pgd_val(*pgdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-               ptep = (pte_t *) pgdp;
-       } else {
-               pmdp = srmmu_pmd_offset(pgdp, addr);
-               if((pmd_val(*pmdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-                       ptep = (pte_t *) pmdp;
-               } else {
-                       ptep = srmmu_pte_offset(pmdp, addr);
-               }
-       }
-
-       flush_cache_page_to_uncache(addr);
-       set_pte(ptep, __pte((pte_val(*ptep) & ~SRMMU_CACHE)));
-       flush_tlb_page_for_cbit(addr);
-}
-
-static inline void srmmu_recache_page(unsigned long addr)
-{
-       pgd_t *pgdp = srmmu_pgd_offset(init_task.mm, addr);
-       pmd_t *pmdp;
-       pte_t *ptep;
-
-       if((pgd_val(*pgdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-               ptep = (pte_t *) pgdp;
-       } else {
-               pmdp = srmmu_pmd_offset(pgdp, addr);
-               if((pmd_val(*pmdp) & SRMMU_ET_MASK) == SRMMU_ET_PTE) {
-                       ptep = (pte_t *) pmdp;
-               } else {
-                       ptep = srmmu_pte_offset(pmdp, addr);
-               }
-       }
-       set_pte(ptep, __pte((pte_val(*ptep) | SRMMU_CACHE)));
-       flush_tlb_page_for_cbit(addr);
-}
-
 static unsigned long srmmu_getpage(void)
 {
        unsigned long page = get_free_page(GFP_KERNEL);
@@ -722,10 +681,6 @@ static pgd_t *srmmu_pgd_alloc(void)
        return NEW_PGD();
 }
 
-static void srmmu_pgd_flush(pgd_t *pgdp)
-{
-}
-
 static void srmmu_set_pte_cacheable(pte_t *ptep, pte_t pteval)
 {
        srmmu_set_entry(ptep, pte_val(pteval));
@@ -801,9 +756,8 @@ static void srmmu_quick_kernel_fault(unsigned long address)
 #endif
 }
 
-static inline void alloc_context(struct task_struct *tsk)
+static inline void alloc_context(struct mm_struct *mm)
 {
-       struct mm_struct *mm = tsk->mm;
        struct ctx_list *ctxp;
 
        ctxp = ctx_free.next;
@@ -841,14 +795,26 @@ static inline void free_context(int context)
 static void srmmu_switch_to_context(struct task_struct *tsk)
 {
        if(tsk->mm->context == NO_CONTEXT) {
-               alloc_context(tsk);
-               flush_cache_mm(current->mm);
+               alloc_context(tsk->mm);
+               flush_cache_mm(tsk->mm);
                ctxd_set(&srmmu_context_table[tsk->mm->context], tsk->mm->pgd);
-               flush_tlb_mm(current->mm);
+               flush_tlb_mm(tsk->mm);
        }
        srmmu_set_context(tsk->mm->context);
 }
 
+static void srmmu_init_new_context(struct mm_struct *mm)
+{
+       alloc_context(mm);
+
+       flush_cache_mm(mm);
+       ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
+       flush_tlb_mm(mm);
+
+       if(mm == current->mm)
+               srmmu_set_context(mm->context);
+}
+
 /* Low level IO area allocation on the SRMMU. */
 void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly)
 {
@@ -1328,11 +1294,6 @@ static unsigned long viking_no_mxcc_getpage(void)
        return page;
 }
 
-static void viking_no_mxcc_pgd_flush(pgd_t *pgdp)
-{
-       viking_no_mxcc_flush_page((unsigned long)pgdp);
-}
-
 static void viking_flush_tlb_all(void)
 {
        module_stats.invall++;
@@ -1450,7 +1411,9 @@ static void cypress_flush_cache_mm(struct mm_struct *mm)
                save_and_cli(flags);
                octx = srmmu_get_context();
                srmmu_set_context(mm->context);
-               a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+               a = 0x20; b = 0x40; c = 0x60;
+               d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
                faddr = (0x10000 - 0x100);
                goto inside;
                do {
@@ -1488,7 +1451,9 @@ static void cypress_flush_cache_range(struct mm_struct *mm, unsigned long start,
                save_and_cli(flags);
                octx = srmmu_get_context();
                srmmu_set_context(mm->context);
-               a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+               a = 0x20; b = 0x40; c = 0x60;
+               d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
                start &= SRMMU_PMD_MASK;
                while(start < end) {
                        faddr = (start + (0x10000 - 0x100));
@@ -1532,7 +1497,9 @@ static void cypress_flush_cache_page(struct vm_area_struct *vma, unsigned long p
                save_and_cli(flags);
                octx = srmmu_get_context();
                srmmu_set_context(mm->context);
-               a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+               a = 0x20; b = 0x40; c = 0x60;
+               d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+
                page &= PAGE_MASK;
                line = (page + PAGE_SIZE) - 0x100;
                goto inside;
@@ -1656,34 +1623,6 @@ static unsigned long cypress_getpage(void)
        return page;
 }
 
-static void cypress_pgd_flush(pgd_t *pgdp)
-{
-       register unsigned long a, b, c, d, e, f, g;
-       unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
-       unsigned long line;
-
-       a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
-       page &= PAGE_MASK;
-       line = (page + PAGE_SIZE) - 0x100;
-       goto inside;
-       do {
-               line -= 0x100;
-       inside:
-               __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
-                                    "sta %%g0, [%0 + %2] %1\n\t"
-                                    "sta %%g0, [%0 + %3] %1\n\t"
-                                    "sta %%g0, [%0 + %4] %1\n\t"
-                                    "sta %%g0, [%0 + %5] %1\n\t"
-                                    "sta %%g0, [%0 + %6] %1\n\t"
-                                    "sta %%g0, [%0 + %7] %1\n\t"
-                                    "sta %%g0, [%0 + %8] %1\n\t" : :
-                                    "r" (line),
-                                    "i" (ASI_M_FLUSH_PAGE),
-                                    "r" (a), "r" (b), "r" (c), "r" (d),
-                                    "r" (e), "r" (f), "r" (g));
-       } while(line != page);
-}
-
 static void cypress_flush_tlb_all(void)
 {
        module_stats.invall++;
@@ -1888,19 +1827,6 @@ static unsigned long hypersparc_getpage(void)
        return page;
 }
 
-static void hypersparc_pgd_flush(pgd_t *pgdp)
-{
-       volatile unsigned long clear;
-       unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
-       unsigned long flags;
-
-       save_and_cli(flags);
-       if(srmmu_hwprobe(page))
-               hyper_flush_cache_page(page);
-       clear = srmmu_get_fstatus();
-       restore_flags(flags);
-}
-
 static void hypersparc_flush_tlb_all(void)
 {
        module_stats.invall++;
@@ -1996,6 +1922,61 @@ static void hypersparc_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp)
 
 static void hypersparc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
 {
+       volatile unsigned long clear;
+       unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
+       unsigned long flags;
+
+       /* Do PGD flush. */
+       save_and_cli(flags);
+       if(srmmu_hwprobe(page))
+               hyper_flush_cache_page(page);
+       clear = srmmu_get_fstatus();
+       restore_flags(flags);
+
+       if(tsk->mm->context != NO_CONTEXT) {
+               flush_cache_mm(current->mm);
+               ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
+               flush_tlb_mm(current->mm);
+       }
+}
+
+static void viking_no_mxcc_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
+{
+       viking_no_mxcc_flush_page((unsigned long)pgdp);
+       if(tsk->mm->context != NO_CONTEXT) {
+               flush_cache_mm(current->mm);
+               ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
+               flush_tlb_mm(current->mm);
+       }
+}
+
+static void cypress_update_rootmmu_dir(struct task_struct *tsk, pgd_t *pgdp) 
+{
+       register unsigned long a, b, c, d, e, f, g;
+       unsigned long page = ((unsigned long) pgdp) & PAGE_MASK;
+       unsigned long line;
+
+       a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0;
+       page &= PAGE_MASK;
+       line = (page + PAGE_SIZE) - 0x100;
+       goto inside;
+       do {
+               line -= 0x100;
+       inside:
+               __asm__ __volatile__("sta %%g0, [%0] %1\n\t"
+                                    "sta %%g0, [%0 + %2] %1\n\t"
+                                    "sta %%g0, [%0 + %3] %1\n\t"
+                                    "sta %%g0, [%0 + %4] %1\n\t"
+                                    "sta %%g0, [%0 + %5] %1\n\t"
+                                    "sta %%g0, [%0 + %6] %1\n\t"
+                                    "sta %%g0, [%0 + %7] %1\n\t"
+                                    "sta %%g0, [%0 + %8] %1\n\t" : :
+                                    "r" (line),
+                                    "i" (ASI_M_FLUSH_PAGE),
+                                    "r" (a), "r" (b), "r" (c), "r" (d),
+                                    "r" (e), "r" (f), "r" (g));
+       } while(line != page);
+
        if(tsk->mm->context != NO_CONTEXT) {
                flush_cache_mm(current->mm);
                ctxd_set(&srmmu_context_table[tsk->mm->context], pgdp);
@@ -2007,14 +1988,28 @@ static void hypersparc_switch_to_context(struct task_struct *tsk)
 {
        hyper_flush_whole_icache();
        if(tsk->mm->context == NO_CONTEXT) {
-               alloc_context(tsk);
-               flush_cache_mm(current->mm);
+               alloc_context(tsk->mm);
+               flush_cache_mm(tsk->mm);
                ctxd_set(&srmmu_context_table[tsk->mm->context], tsk->mm->pgd);
-               flush_tlb_mm(current->mm);
+               flush_tlb_mm(tsk->mm);
        }
        srmmu_set_context(tsk->mm->context);
 }
 
+static void hypersparc_init_new_context(struct mm_struct *mm)
+{
+       hyper_flush_whole_icache();
+
+       alloc_context(mm);
+
+       flush_cache_mm(mm);
+       ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
+       flush_tlb_mm(mm);
+
+       if(mm == current->mm)
+               srmmu_set_context(mm->context);
+}
+
 /* IOMMU things go here. */
 
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
@@ -2842,10 +2837,8 @@ static void srmmu_update_mmu_cache(struct vm_area_struct * vma, unsigned long ad
 {
 }
 
-static void srmmu_exit_hook(void)
+static void srmmu_destroy_context(struct mm_struct *mm)
 {
-       struct mm_struct *mm = current->mm;
-
        if(mm->context != NO_CONTEXT && mm->count == 1) {
                flush_cache_mm(mm);
                ctxd_set(&srmmu_context_table[mm->context], swapper_pg_dir);
@@ -2855,17 +2848,6 @@ static void srmmu_exit_hook(void)
        }
 }
 
-static void srmmu_flush_hook(void)
-{
-       if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-               alloc_context(current);
-               flush_cache_mm(current->mm);
-               ctxd_set(&srmmu_context_table[current->mm->context], current->mm->pgd);
-               flush_tlb_mm(current->mm);
-               srmmu_set_context(current->mm->context);
-       }
-}
-
 static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
                                       unsigned long address, pte_t pte)
 {
@@ -2930,10 +2912,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
        }
 }
 
-static void hypersparc_exit_hook(void)
+static void hypersparc_destroy_context(struct mm_struct *mm)
 {
-       struct mm_struct *mm = current->mm;
-
        if(mm->context != NO_CONTEXT && mm->count == 1) {
                /* HyperSparc is copy-back, any data for this
                 * process in a modified cache line is stale
@@ -2948,17 +2928,6 @@ static void hypersparc_exit_hook(void)
        }
 }
 
-static void hypersparc_flush_hook(void)
-{
-       if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-               alloc_context(current);
-               flush_cache_mm(current->mm);
-               ctxd_set(&srmmu_context_table[current->mm->context], current->mm->pgd);
-               flush_tlb_mm(current->mm);
-               srmmu_set_context(current->mm->context);
-       }
-}
-
 /* Init various srmmu chip types. */
 __initfunc(static void srmmu_is_bad(void))
 {
@@ -3063,12 +3032,11 @@ __initfunc(static void init_hypersparc(void))
        flush_page_for_dma = hypersparc_flush_page_for_dma;
        flush_cache_page_to_uncache = hypersparc_flush_cache_page_to_uncache;
        flush_tlb_page_for_cbit = hypersparc_flush_tlb_page_for_cbit;
-       pgd_flush = hypersparc_pgd_flush;
 
        ctxd_set = hypersparc_ctxd_set;
        switch_to_context = hypersparc_switch_to_context;
-       mmu_exit_hook = hypersparc_exit_hook;
-       mmu_flush_hook = hypersparc_flush_hook;
+       init_new_context = hypersparc_init_new_context;
+       destroy_context = hypersparc_destroy_context;
        update_mmu_cache = srmmu_vac_update_mmu_cache;
        sparc_update_rootmmu_dir = hypersparc_update_rootmmu_dir;
        poke_srmmu = poke_hypersparc;
@@ -3077,17 +3045,32 @@ __initfunc(static void init_hypersparc(void))
 static void poke_cypress(void)
 {
        unsigned long mreg = srmmu_get_mmureg();
-       unsigned long faddr;
+       unsigned long faddr, tagval;
+       volatile unsigned long cypress_sucks;
        volatile unsigned long clear;
 
        clear = srmmu_get_faddr();
        clear = srmmu_get_fstatus();
 
-       for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
-               __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
-                                    "sta %%g0, [%0] %2\n\t" : :
-                                    "r" (faddr), "r" (0x40000),
-                                    "i" (ASI_M_DATAC_TAG));
+       if (!(mreg & CYPRESS_CENABLE)) {
+               for(faddr = 0x0; faddr < 0x10000; faddr += 20) {
+                       __asm__ __volatile__("sta %%g0, [%0 + %1] %2\n\t"
+                                            "sta %%g0, [%0] %2\n\t" : :
+                                            "r" (faddr), "r" (0x40000),
+                                            "i" (ASI_M_DATAC_TAG));
+               }
+       } else {
+               for(faddr = 0; faddr < 0x10000; faddr += 0x20) {
+                       __asm__ __volatile__("lda [%1 + %2] %3, %0\n\t" :
+                                            "=r" (tagval) :
+                                            "r" (faddr), "r" (0x40000),
+                                            "i" (ASI_M_DATAC_TAG));
+
+                       /* If modified and valid, kick it. */
+                       if((tagval & 0x60) == 0x60)
+                               cypress_sucks = *(unsigned long *)
+                                                       (0xf0020000 + faddr);
+               }
        }
 
        /* And one more, for our good neighbor, Mr. Broken Cypress. */
@@ -3119,7 +3102,7 @@ __initfunc(static void init_cypress_common(void))
        flush_page_for_dma = cypress_flush_page_for_dma;
        flush_cache_page_to_uncache = cypress_flush_page_to_uncache;
        flush_tlb_page_for_cbit = cypress_flush_tlb_page_for_cbit;
-       pgd_flush = cypress_pgd_flush;
+       sparc_update_rootmmu_dir = cypress_update_rootmmu_dir;
 
        update_mmu_cache = srmmu_vac_update_mmu_cache;
        poke_srmmu = poke_cypress;
@@ -3355,7 +3338,7 @@ __initfunc(static void init_viking(void))
 
                mmu_getpage = viking_no_mxcc_getpage;
                set_pte = srmmu_set_pte_nocache_nomxccvik;
-               pgd_flush = viking_no_mxcc_pgd_flush;
+               sparc_update_rootmmu_dir = viking_no_mxcc_update_rootmmu_dir;
 
                flush_cache_page_to_uncache = viking_no_mxcc_flush_page;
 
@@ -3538,7 +3521,7 @@ __initfunc(void ld_mmu_srmmu(void))
        /* Functions */
        mmu_getpage = srmmu_getpage;
        set_pte = srmmu_set_pte_cacheable;
-       switch_to_context = srmmu_switch_to_context;
+       init_new_context = srmmu_init_new_context;
        pmd_align = srmmu_pmd_align;
        pgdir_align = srmmu_pgdir_align;
        vmalloc_start = srmmu_vmalloc_start;
@@ -3581,7 +3564,6 @@ __initfunc(void ld_mmu_srmmu(void))
        pmd_alloc = srmmu_pmd_alloc;
        pgd_free = srmmu_pgd_free;
        pgd_alloc = srmmu_pgd_alloc;
-       pgd_flush = srmmu_pgd_flush;
 
        pte_write = srmmu_pte_write;
        pte_dirty = srmmu_pte_dirty;
@@ -3593,8 +3575,7 @@ __initfunc(void ld_mmu_srmmu(void))
        pte_mkdirty = srmmu_pte_mkdirty;
        pte_mkyoung = srmmu_pte_mkyoung;
        update_mmu_cache = srmmu_update_mmu_cache;
-       mmu_exit_hook = srmmu_exit_hook;
-       mmu_flush_hook = srmmu_flush_hook;
+       destroy_context = srmmu_destroy_context;
        mmu_lockarea = srmmu_lockarea;
        mmu_unlockarea = srmmu_unlockarea;
 
index 0492971ec1790892a0102a7d59281e372724d23c..4809a0f9f9d64c117f299f0ab96d354901bbe808 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.135 1996/12/23 05:27:50 davem Exp $
+/* $Id: sun4c.c,v 1.137 1996/12/30 06:16:36 davem Exp $
  * sun4c.c: Doing in software what should be done in hardware.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -21,6 +21,7 @@
 #include <asm/io.h>
 #include <asm/oplib.h>
 #include <asm/openprom.h>
+#include <asm/mmu_context.h>
 
 extern int num_segmaps, num_contexts;
 
@@ -1609,22 +1610,16 @@ set_context:
        restore_flags(flags);
 }
 
-static void sun4c_flush_hook(void)
+static void sun4c_init_new_context(struct mm_struct *mm)
 {
-       if(current->tss.flags & SPARC_FLAG_KTHREAD) {
-               unsigned long flags;
-
-               save_flags(flags);
-               sun4c_alloc_context(current->mm);
-               sun4c_set_context(current->mm->context);
-               restore_flags(flags);
-       }
+       sun4c_alloc_context(mm);
+       if(mm == current->mm)
+               sun4c_set_context(mm->context);
 }
 
-static void sun4c_exit_hook(void)
+static void sun4c_destroy_context(struct mm_struct *mm)
 {
        struct ctx_list *ctx_old;
-       struct mm_struct *mm = current->mm;
 
        if(mm->context != NO_CONTEXT && mm->count == 1) {
                unsigned long flags;
@@ -2038,10 +2033,6 @@ done:
        restore_flags(flags);
 }
 
-static void sun4c_pgd_flush(pgd_t *pgdp)
-{
-}
-
 extern unsigned long free_area_init(unsigned long, unsigned long);
 extern unsigned long sparc_context_init(unsigned long, int);
 extern unsigned long end;
@@ -2177,7 +2168,6 @@ __initfunc(void ld_mmu_sun4c(void))
        pmd_alloc = sun4c_pmd_alloc;
        pgd_free = sun4c_pgd_free;
        pgd_alloc = sun4c_pgd_alloc;
-       pgd_flush = sun4c_pgd_flush;
 
        pte_write = sun4c_pte_write;
        pte_dirty = sun4c_pte_dirty;
@@ -2189,8 +2179,8 @@ __initfunc(void ld_mmu_sun4c(void))
        pte_mkdirty = sun4c_pte_mkdirty;
        pte_mkyoung = sun4c_pte_mkyoung;
        update_mmu_cache = sun4c_update_mmu_cache;
-       mmu_exit_hook = sun4c_exit_hook;
-       mmu_flush_hook = sun4c_flush_hook;
+       destroy_context = sun4c_destroy_context;
+       init_new_context = sun4c_init_new_context;
        mmu_lockarea = sun4c_lockarea;
        mmu_unlockarea = sun4c_unlockarea;
 
index 1d0dd87fadd19d0e2a6054bfcbfc4a665fb8c484..0e129a1e4b3578078a7b0747dff2441bec2beaa7 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id: tree.c,v 1.13 1996/12/18 06:46:56 tridge Exp $
+/* $Id: tree.c,v 1.14 1996/12/29 20:46:12 davem Exp $
  * tree.c: Basic device tree traversal/scanning for the Linux
  *         prom library.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  */
 
-#include <linux/config.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
new file mode 100644 (file)
index 0000000..c1ef862
--- /dev/null
@@ -0,0 +1,45 @@
+# $Id: Makefile,v 1.2 1996/12/27 17:28:20 davem Exp $
+# sparc64/Makefile
+#
+# Makefile for the architecture dependent flags and dependencies on the
+# 64-bit Sparc.
+#
+# Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+#
+
+# If the solaris /bin/sh wasn't so broken, I wouldn't need the following
+# line...
+SHELL  =/bin/bash
+
+CC             = sparc64-linux-gcc -D__KERNEL__ -I$(TOPDIR)/include
+AS             = sparc64-linux-as
+LD             = sparc64-linux-ld
+NM             = sparc64-linux-nm
+AR             = sparc64-linux-ar
+RANLIB         = sparc64-linux-ranlib
+
+#
+# Uncomment the first CFLAGS if you are doing kgdb source level
+# debugging of the kernel to get the proper debugging information.
+
+#CFLAGS := $(CFLAGS) -g -pipe
+CFLAGS := $(CFLAGS) -pipe
+
+LINKFLAGS = -N -Ttext 0xFFFFF80000008000
+
+HEAD := arch/sparc/kernel/head.o
+
+SUBDIRS := $(SUBDIRS) arch/sparc64/kernel arch/sparc64/lib arch/sparc64/mm \
+       arch/sparc64/prom
+
+ARCHIVES := arch/sparc64/kernel/kernel.o arch/sparc64/mm/mm.o $(ARCHIVES)
+
+LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc64/prom/promlib.a \
+       $(TOPDIR)/arch/sparc64/lib/lib.a
+
+INITOBJ = $(TOPDIR)/arch/sparc64/kernel/initobj.o
+FINITOBJ = $(TOPDIR)/arch/sparc64/kernel/finitobj.o
+
+archclean:
+
+archdep:
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
new file mode 100644 (file)
index 0000000..0fc4d46
--- /dev/null
@@ -0,0 +1,149 @@
+# $Id: config.in,v 1.1 1996/12/27 17:28:19 davem Exp $
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+mainmenu_name "Linux/SPARC Kernel Configuration"
+
+mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+  bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
+  bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
+bool 'Support for AP1000 multicomputer' CONFIG_AP1000
+
+if [ "$CONFIG_AP1000" = "y" ]; then
+       define_bool CONFIG_NO_KEYBOARD y
+       define_bool CONFIG_APFDDI y
+       define_bool CONFIG_APBLOCK y
+       define_bool CONFIG_APBIF y
+       tristate 'OPIU DDV Driver' CONFIG_DDV
+else
+       # Global things across all Sun machines.
+       define_bool CONFIG_SBUS y
+       define_bool CONFIG_SBUSCHAR y
+       define_bool CONFIG_SUN_MOUSE y
+       define_bool CONFIG_SERIAL y
+       define_bool CONFIG_SUN_SERIAL y
+       define_bool CONFIG_SUN_KEYBOARD y
+       define_bool CONFIG_SUN_CONSOLE y
+       define_bool CONFIG_SUN_AUXIO y
+       define_bool CONFIG_SUN_IO y
+       source drivers/sbus/char/Config.in
+fi
+
+tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+bool 'Networking support' CONFIG_NET
+bool 'System V IPC' CONFIG_SYSVIPC
+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Floppy, IDE, and other block devices'
+
+bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD
+
+bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
+if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
+  tristate '   Linear (append) mode' CONFIG_MD_LINEAR
+  tristate '   RAID-0 (striping) mode' CONFIG_MD_STRIPED
+#  tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+fi
+
+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
+  bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+fi
+
+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+
+endmenu
+
+if [ "$CONFIG_NET" = "y" ]; then
+       source net/Config.in
+fi
+
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+       comment 'SCSI support type (disk, tape, CDrom)'
+
+       dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+       dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+       dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+       if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
+         bool '  Enable vendor-specific extentions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
+       fi
+       dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+
+       comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+       bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+
+       bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+
+       mainmenu_option next_comment
+       comment 'SCSI low-level drivers'
+
+       bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
+       tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
+       endmenu
+fi
+endmenu
+
+if [ "$CONFIG_NET" = "y" ]; then
+       mainmenu_option next_comment
+       comment 'Network device support'
+
+       bool 'Network device support' CONFIG_NETDEVICES
+       if [ "$CONFIG_NETDEVICES" = "y" ]; then
+               tristate 'Dummy net driver support' CONFIG_DUMMY
+               tristate 'PPP (point-to-point) support' CONFIG_PPP
+               if [ ! "$CONFIG_PPP" = "n" ]; then
+                  comment 'CCP compressors for PPP are only built as modules.'
+               fi
+               tristate 'SLIP (serial line) support' CONFIG_SLIP
+               if [ "$CONFIG_SLIP" != "n" ]; then
+                 bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+                 bool ' Keepalive and linefill' CONFIG_SLIP_SMART
+                 bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
+               fi
+               bool 'Sun LANCE support' CONFIG_SUNLANCE
+               tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
+               tristate 'Sun QuadEthernet support' CONFIG_SUNQE
+               tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
+#              bool 'FDDI driver support' CONFIG_FDDI
+#              if [ "$CONFIG_FDDI" = "y" ]; then
+#              fi
+       fi
+       endmenu
+fi
+
+source fs/Config.in
+
+mainmenu_option next_comment
+comment 'Kernel hacking'
+
+bool 'Kernel profiling support' CONFIG_PROFILE
+if [ "$CONFIG_PROFILE" = "y" ]; then
+       int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+fi
+endmenu
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
new file mode 100644 (file)
index 0000000..6998745
--- /dev/null
@@ -0,0 +1,195 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# General setup
+#
+# CONFIG_AP1000 is not set
+CONFIG_SBUS=y
+CONFIG_SBUSCHAR=y
+CONFIG_SUN_MOUSE=y
+CONFIG_SERIAL=y
+CONFIG_SUN_SERIAL=y
+CONFIG_SUN_KEYBOARD=y
+CONFIG_SUN_CONSOLE=y
+CONFIG_SUN_AUXIO=y
+CONFIG_SUN_IO=y
+
+#
+# SBUS Frame Buffer support
+#
+SUN_FBS_IN_PROCFS=y
+CONFIG_SUN_FB_DISPLAY=y
+SUN_FB_CGSIX=y
+SUN_FB_TCX=y
+SUN_FB_CGTHREE=y
+SUN_FB_CGFOURTEEN=y
+SUN_FB_BWTWO=y
+SUN_FB_LEO=y
+TADPOLE_FB_WEITEK=y
+SUN_FB_FAST_ONE=y
+SUN_FB_FAST_TWO=y
+SUN_FB_FAST_MONO=y
+SUN_FB_GENERIC=y
+
+#
+# Misc Linux/SPARC drivers
+#
+CONFIG_SUN_OPENPROMIO=y
+CONFIG_SUN_MOSTEK_RTC=y
+CONFIG_SUN_OPENPROMFS=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_JAVA=y
+
+#
+# Floppy, IDE, and other block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_STRIPED=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=y
+
+#
+# Networking options
+#
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+CONFIG_FIREWALL=y
+CONFIG_NET_ALIAS=y
+CONFIG_INET=y
+CONFIG_IP_FORWARD=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_FIREWALL=y
+# CONFIG_IP_FIREWALL_NETLINK is not set
+# CONFIG_IP_FIREWALL_VERBOSE is not set
+CONFIG_IP_MASQUERADE=y
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+# CONFIG_IP_TRANSPARENT_PROXY is not set
+# CONFIG_IP_ALWAYS_DEFRAG is not set
+# CONFIG_IP_ACCT is not set
+# CONFIG_IP_ROUTER is not set
+CONFIG_NET_IPIP=y
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# CONFIG_ARPD is not set
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_INET_PCTCP is not set
+CONFIG_INET_RARP=y
+# CONFIG_PATH_MTU_DISCOVERY is not set
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+CONFIG_IPV6=y
+
+#
+#  
+#
+CONFIG_IPX=y
+# CONFIG_IPX_INTERN is not set
+# CONFIG_IPX_PPROP_ROUTING is not set
+CONFIG_ATALK=y
+# CONFIG_AX25 is not set
+CONFIG_X25=y
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CDrom)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SCSI_SUNESP=y
+CONFIG_SCSI_QLOGICPTI=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_SUNLANCE=y
+CONFIG_HAPPYMEAL=y
+CONFIG_SUNQE=y
+CONFIG_MYRI_SBUS=y
+
+#
+# Filesystems
+#
+CONFIG_QUOTA=y
+CONFIG_MINIX_FS=y
+CONFIG_EXT_FS=y
+CONFIG_EXT2_FS=y
+CONFIG_XIA_FS=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_UMSDOS_FS=y
+CONFIG_PROC_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_RNFS_BOOTP=y
+CONFIG_RNFS_RARP=y
+CONFIG_SMB_FS=y
+CONFIG_SMB_WIN95=y
+CONFIG_NCP_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_HPFS_FS=y
+CONFIG_SYSV_FS=y
+CONFIG_AFFS_FS=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_UFS_FS=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SMD_DISKLABEL=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PROFILE is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
new file mode 100644 (file)
index 0000000..cc1a4fb
--- /dev/null
@@ -0,0 +1,32 @@
+# $Id: Makefile,v 1.1 1996/12/26 10:16:41 davem Exp $
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.S.s:
+       $(CPP) -D__ASSEMBLY__ -ansi $< -o $*.s
+
+.S.o:
+       $(CC) -D__ASSEMBLY__ -ansi -c $< -o $*.o
+
+all: kernel.o head.o initobj.o finitobj.o
+
+O_TARGET := kernel.o
+O_OBJS   := etrap.o rtrap.o signal32.o
+OX_OBJS  := sparc64_ksyms.o
+
+head.o: head.S
+       $(CC) -D__ASSEMBLY__ -ansi -c $*.S -o $*.o
+
+initobj.o: initobj.S
+       $(CC) -D__ASSEMBLY__ -ansi -c initobj.S -o initobj.o
+
+finitobj.o: initobj.S
+       $(CC) -D__ASSEMBLY__ -ansi -c finitobj.S -o finitobj.o
+
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/kernel/dtlb_miss.S b/arch/sparc64/kernel/dtlb_miss.S
new file mode 100644 (file)
index 0000000..c92d7b9
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: dtlb_miss.S,v 1.4 1996/12/28 18:39:40 davem Exp $
+ * dtlb_miss.S:        Data TLB miss code, this is included directly
+ *              into the trap table.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+       /* We are in the MMU globals, %g7 contains the physical
+        * address of current->mm->pgd at all times.
+        *
+        * Many subtle things are done here.  The high bits of
+        * the virtual address missed are most easily obtained
+        * from the tag target (it is at address zero in ASI_IMMU
+        * so no address formation is necessary to get at this).
+        * This is used to compute the pgd and pmd table offsets.
+        *
+        * Even more clever is that physical page zero is always
+        * a page full of zeroes.  This means we can just follow
+        * through with all the page table traversals even if nothing
+        * is mapped because we'll just do loads from page zero
+        * and get yet another zero.  We only need to do the check
+        * for the valid bit being set in the final pte we obtain.
+        *
+        * Furthermore, we set the TSB base register to the address
+        * zero, and we use the 8KB tsb ptr to calculate the pte
+        * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+        * so no address formation is necessary, saves more instructions.
+        *
+        * We use physical address accesses to get at the page
+        * tables, and this is for two reasons.  This makes it
+        * impossible to take a fault while we are servicing the
+        * miss.  Also this physical bypass access only allocates
+        * in the E-cache, and thus we prevent D-cache pollution
+        * from the miss handlers probing the page tables.
+        *
+        * It looks very hairy and slow.  But I take only 1 more
+        * overhead of loads from ram than the Solaris version, and
+        * my version is one instruction quicker for a true TLB miss.
+        * And more importantly, all true TLB misses under Linux will be
+        * serviced in _constant_ time.  When using the TSB in the
+        * manner it was intended to be used (like solaris does) the
+        * overhead for a TLB miss is _indeterminate_ especially during
+        * processes startup when the TSB is cold.
+        *
+        * XXX I think I can knock off two more instructions here...
+        */
+
+dtlb_miss:
+       /* I-cache line 0 */
+       ldxa            [%g0] ASI_DMMU, %g1             ! grab Tag Target either way
+       brlz,pnt        %g1, 3f                         ! special kernel processing
+        srlx           %g1, 8, %g3                     ! put high vaddr bits in place
+
+1:
+       and             %g3, %g2, %g3                   ! get offset
+       ldxa            [%g7 + %g3] ASI_PHYS_USE_EC, %g5! load pgd
+       sllx            %g1, 2, %g4                     ! begin pmd_offset formation
+       and             %g4, %g2, %g3                   ! and now mask it
+       ldxa            [%g5 + %g3] ASI_PHYS_USE_EC, %g4! load pmd
+       /* I-cache line 1 */
+       ldxa            [%g0] ASI_DMMU_TSB_8KB_PTR, %g1 ! get 8KB pointer bits
+       srlx            %g1, 1, %g1                     ! shift right to get pte_offset
+       ldxa            [%g4 + %g1] ASI_PHYS_USE_EC, %g3! load pte
+       brlz,a,pt       %g3, 2f                         ! is valid bit clear?
+        stxa           %g3, [%g0] ASI_DTLB_DATA_IN     ! nope, load TTE into DTLB
+
+       ba,a,pt         %xcc, sparc64_dtlb_refbit_catch ! longer processing needed
+2:
+       retry                                           ! return from trap
+
+#define KTTE_HIGH_BITS (_PAGE_VALID | _PAGE_SZ4MB)
+#define KTTE_LOW_BITS  (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W | _PAGE_G)
+
+       nop                                             ! align next insn on cache line
+3:
+       /* I-cache line 2 */
+       srax            %g1, 19, %g5                    ! mask down high bits
+       cmp             %g5, -1                         ! if -1 this is VMALLOC area
+       be,pnt          %xcc, 1b                        ! yep
+        sethi          %uhi(KTTE_HIGH_BITS), %g4       ! begin pte formation
+
+       sllx            %g1, 23, %g1                    ! begin masking for physpage
+       sllx            %g4, 32, %g4                    ! high protection TTE bits
+       or              %g4, (KTTE_LOW_BITS), %g4       ! low protection TTE bits
+       srlx            %g1, 41, %g1                    ! put physpage into place
+       /* I-cache line 3 */
+       or              %g4, %g1, %g1                   ! finish TTE computation
+       stxa            %g1, [%g0] ASI_DTLB_DATA_IN     ! load TTE into DTLB
+       retry                                           ! return from trap
+
+       nop; nop; nop; nop; nop;
+
+#undef KTTE_HIGH_BITS
+#undef KTTE_LOW_BITS
diff --git a/arch/sparc64/kernel/dtlb_prot.S b/arch/sparc64/kernel/dtlb_prot.S
new file mode 100644 (file)
index 0000000..39cadfa
--- /dev/null
@@ -0,0 +1,63 @@
+/* $Id: dtlb_prot.S,v 1.3 1996/12/28 18:39:41 davem Exp $
+ * dtlb_prot.S:        Fast TLB protection trap processing.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+       /* We are in the MMU globals, %g7 contains the physical
+        * address of current->mm->pgd at all times.  %g2 is
+        * also preloaded with the mask 0x1ff8 to make things
+        * even quicker.
+        *
+        * Many subtle things are done here.  The high bits of
+        * the virtual address missed are most easily obtained
+        * from the tag target (it is at address zero in ASI_IMMU
+        * so no address formation is necessary to get at this).
+        * This is used to compute the pgd and pmd table offsets.
+        *
+        * Even more clever is that physical page zero is always
+        * a page full of zeroes.  This means we can just follow
+        * through with all the page table traversals even if nothing
+        * is mapped because we'll just do loads from page zero
+        * and get yet another zero.  We only need to do the check
+        * for the valid bit being set in the final pte we obtain.
+        *
+        * Furthermore, we set the TSB base register to the address
+        * zero, and we use the 8KB tsb ptr to calculate the pte
+        * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+        * so no address formation is necessary, saves more instructions.
+        *
+        * We use physical address accesses to get at the page
+        * tables, and this is for two reasons.  This makes it
+        * impossible to take a fault while we are servicing the
+        * miss.  Also this physical bypass access only allocates
+        * in the E-cache, and thus we prevent D-cache pollution
+        * from the miss handlers probing the page tables.
+        */
+
+dtlb_prot:
+       /* I-cache line 0 */
+       ldxa            [%g0] ASI_DMMU, %g1
+       srlx            %g1, 8, %g3
+       and             %g3, %g2, %g3
+       ldxa            [%g7 + %g3] ASI_PHYS_USE_EC, %g5
+       sllx            %g1, 2, %g4
+       and             %g4, %g2, %g3
+       ldxa            [%g5 + %g3] ASI_PHYS_USE_EC, %g4
+       ldxa            [%g0] ASI_DMMU_TSB_8KB_PTR, %g1
+       /* I-cache line 1 */
+       srlx            %g1, 1, %g1
+       ldxa            [%g4 + %g1] ASI_PHYS_USE_EC, %g3
+       andcc           %g3, _PAGE_WRITE, %g0
+       be,pnt          %xcc, sparc64_dtlb_fault
+        or             %g3, (_PAGE_WRITE|_PAGE_W|_PAGE_MODIFIED|_PAGE_ACCESSED), %g3
+
+       /* Blamo... */
+       stxa            %g3, [%g4 + %g1] %asi
+       stxa            %g3, [%g0] ASI_DTLB_DATA_IN
+       retry
+
+       /* I-cache line 2 */
+       nop; nop; nop; nop; nop; nop; nop; nop;
+       /* I-cache line 3 */
+       nop; nop; nop; nop; nop; nop; nop; nop;
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
new file mode 100644 (file)
index 0000000..70ab2e2
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id: etrap.S,v 1.1 1996/12/26 10:16:42 davem Exp $
+ * etrap.S: Preparing for entry into the kernel on Sparc V9.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+
+       .text
+       .align  4
+       .globl  etrap
+etrap:
+       sethi   %uhi(current_set), %g6
+       rd      %tstate, %g1
+       or      %g6, %ulo(current_set), %g6
+       rd      %tpc, %g2
+       sllx    %g6, 32, %g6
+       rd      %tnpc, %g3
+       sethi   %hi(current_set), %g4
+       or      %g4, %lo(current_set), %g4
+       or      %g6, %g4, %g6
+       rd      %y, %g4
+       ldx     [%g6 + THREAD_KSTACK], %g5
+       stx     %g1, [%g5 + REGWIN_SZ + PT_TSTATE]
+       stx     %g2, [%g5 + REGWIN_SZ + PT_TPC]
+       stx     %g3, [%g5 + REGWIN_SZ + PT_TNPC]
+       stx     %g4, [%g5 + REGWIN_SZ + PT_Y]
+       rd      %pstate, %g1
+       andn    %g1, (PSTATE_IG | PSTATE_MG | PSTATE_AG), %g2
+       save    %g5, 0x0, %sp
+       mov     %g2, %l1
+       wr      %g0, 0x0, %tl
+       mov     %g7, %l2
+       wr      %l1, 0x0, %pstate
+       stx     %g1, [%sp + REGWIN_SZ + PT_G1]
+       stx     %g2, [%sp + REGWIN_SZ + PT_G2]
+       stx     %g3, [%sp + REGWIN_SZ + PT_G3]
+       stx     %g4, [%sp + REGWIN_SZ + PT_G4]
+       stx     %g5, [%sp + REGWIN_SZ + PT_G5]
+       stx     %g6, [%sp + REGWIN_SZ + PT_G6]
+       stx     %g7, [%sp + REGWIN_SZ + PT_G7]
+       stx     %i0, [%sp + REGWIN_SZ + PT_I0]
+       stx     %i1, [%sp + REGWIN_SZ + PT_I1]
+       stx     %i2, [%sp + REGWIN_SZ + PT_I2]
+       stx     %i3, [%sp + REGWIN_SZ + PT_I3]
+       stx     %i4, [%sp + REGWIN_SZ + PT_I4]
+       stx     %i5, [%sp + REGWIN_SZ + PT_I5]
+       stx     %i6, [%sp + REGWIN_SZ + PT_I6]
+       stx     %i7, [%sp + REGWIN_SZ + PT_I7]
+       jmpl    %l2 + 0x4, %g0
+        wr     %l1, PSTATE_IE, %pstate
diff --git a/arch/sparc64/kernel/finitobj.S b/arch/sparc64/kernel/finitobj.S
new file mode 100644 (file)
index 0000000..0c05d3e
--- /dev/null
@@ -0,0 +1,6 @@
+       .section        ".text.init",#alloc,#execinstr
+       .globl  text_init_end
+text_init_end:
+       .section        ".data.init",#alloc,#write
+       .globl  data_init_end
+data_init_end:
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
new file mode 100644 (file)
index 0000000..8197215
--- /dev/null
@@ -0,0 +1,114 @@
+/* $Id: head.S,v 1.4 1996/12/28 18:39:42 davem Exp $
+ * head.S: Initial boot code for the Sparc64 port of Linux.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/pstate.h>
+#include <asm/spitfire.h>
+#include <asm/pgtable.h>
+
+       .text
+
+#include "ttable.S"
+
+sparc64_boot:
+       rdpr    %ver, %g1                       /* Get VERSION register.        */
+       mov     %o4, %g2                        /* Get OpenPROM vector.         */
+
+       /* We must be careful, 32-bit OpenBOOT will get confused if it
+        * tries to save away a register window to a 64-bit kernel
+        * stack address.  Flush all windows, disable interrupts,
+        * remap if necessary, jump onto kernel trap table, then kernel
+        * stack, or else we die.
+        */
+       flushw                                  /* Flush register file.      */
+       wrpr    %g0, 0xf, %pil                  /* Interrupts off.           */
+
+       /* Remap ourselves to upper 64-bit addresses if necessary.
+        * SILO64 will have loaded us to the right location already.
+        */
+       mov     %o7, %g4
+current_pc:
+       call    1f
+        mov    %o7, %g3
+1:
+       mov     %g4, %o7
+
+       set     current_pc, %g7
+       cmp     %g3, %g7
+       be      go_to_highmem
+        nop
+
+       /* Remap ourselves into high addresses. */
+       set     PAGE_OFFSET, %g4
+       sethi   %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
+       sllx    %g5, 32, %g5
+       or      %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W | _PAGE_G | _PAGE_L), %g5
+
+       /* Be real fucking anal... */
+       stxa    %g0, [%g4] ASI_IMMU_DEMAP
+       stxa    %g0, [%g4] ASI_DMMU_DEMAP
+       membar  #Sync
+       flush   %g4
+
+       mov     TLB_TAG_ACCESS, %g6
+       stxa    %g4, [%g6] ASI_IMMU
+       stxa    %g5, [%g0] ASI_ITLB_DATA_IN
+       membar  #Sync
+       flush   %g4
+
+       stxa    %g4, [%g6] ASI_DMMU
+       stxa    %g5, [%g0] ASI_DTLB_DATA_IN
+       membar  #Sync
+       flush   %g4
+
+go_to_highmem:
+       set     execute_in_high_mem, %g7
+       jmpl    %g7, %g0
+        nop
+
+execute_in_high_mem:
+
+       set     nwindows, %g7
+       and     %g1, VERS_MAXWIN, %g5
+       add     %g5, 1, %g4
+       stx     %g4, [%g7]
+       set     nwindowsm1, %g6
+       stx     %g5, [%g6]
+       set     romvec, %g7
+       stx     %g2, [%g7]
+       set     prom_sp, %g7
+       stx     %sp, [%g7]
+       set     swapper_pg_dir, %g6
+       set     PAGE_OFFSET, %g4                ! this stays here for a long time
+       sub     %g6, %g4, %g5
+       set     init_task, %g6                  ! g6 usage is fixed as well
+
+       set     sparc64_ttable_tl0, %g5
+       wrpr    %g5, %tba
+
+       set     bootup_kernel_stack, %sp
+       mov     0, %fp
+       wrpr    %g0, PSTATE_KERNEL, %pstate
+       wrpr    %g0, WSTATE_KERNEL, %wstate
+       wrpr    %g0, 0x0, %tl
+
+       /* XXX Map in PROM 32-bit trampoline code. */
+       
+       call    prom_init
+        mov    %o4, %o0
+
+       /* Off we go.... */
+       call    start_kernel
+        nop
+
+       /* Not reached... */
+
+       .data
+       .align  4
+       .globl  nwindows, nwindowsm1, romvec, prom_sp
+nwindows:      .xword  0
+nwindowsm1:    .xword  0
+romvec:                .xword  0
+prom_sp:       .xword  0
diff --git a/arch/sparc64/kernel/idprom.c b/arch/sparc64/kernel/idprom.c
new file mode 100644 (file)
index 0000000..fc84bfa
--- /dev/null
@@ -0,0 +1,51 @@
+/* $Id: idprom.c,v 1.1 1996/12/28 18:39:38 davem Exp $
+ * idprom.c: Routines to load the idprom into kernel addresses and
+ *           interpret the data contained within.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <asm/oplib.h>
+#include <asm/idprom.h>
+
+struct idprom *idprom;
+static struct idprom idprom_buffer;
+
+/* Calculate the IDPROM checksum (xor of the data bytes). */
+__initfunc(static unsigned char calc_idprom_cksum(struct idprom *idprom))
+{
+       unsigned char cksum, i, *ptr = (unsigned char *)idprom;
+
+       for (i = cksum = 0; i <= 0x0E; i++)
+               cksum ^= *ptr++;
+
+       return cksum;
+}
+
+/* Create a local IDPROM copy and verify integrity. */
+__initfunc(void idprom_init(void))
+{
+       prom_get_idprom((char *) &idprom_buffer, sizeof(idprom_buffer));
+
+       idprom = &idprom_buffer;
+
+       if (idprom->id_format != 0x01)  {
+               prom_printf("IDPROM: Unknown format type!\n");
+               prom_halt();
+       }
+
+       if (idprom->id_cksum != calc_idprom_cksum(idprom)) {
+               prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n",
+                           idprom->id_cksum, calc_idprom_cksum(idprom));
+               prom_halt();
+       }
+
+       printk("Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+              idprom->id_ethaddr[0], idprom->id_ethaddr[1],
+              idprom->id_ethaddr[2], idprom->id_ethaddr[3],
+              idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
+}
diff --git a/arch/sparc64/kernel/initobj.S b/arch/sparc64/kernel/initobj.S
new file mode 100644 (file)
index 0000000..4f4f692
--- /dev/null
@@ -0,0 +1,15 @@
+#include <asm/errno.h>
+
+       .section        ".text.init",#alloc,#execinstr
+       .globl  text_init_begin
+text_init_begin:
+       .section        ".data.init",#alloc,#write
+       .globl  data_init_begin
+data_init_begin:
+
+       .section        ".fixup",#alloc,#execinstr
+       .globl  __ret_efault
+__ret_efault:
+       ret
+        restore %g0, -EFAULT, %o0
+
diff --git a/arch/sparc64/kernel/ioport.c b/arch/sparc64/kernel/ioport.c
new file mode 100644 (file)
index 0000000..c775d81
--- /dev/null
@@ -0,0 +1,133 @@
+/* $Id: ioport.c,v 1.1 1996/12/28 18:39:39 davem Exp $
+ * ioport.c:  Simple io mapping allocator.
+ *
+ * Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/vaddrs.h>
+#include <asm/oplib.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+/* This points to the next to use virtual memory for io mappings */
+static unsigned long dvma_next_free   = DVMA_VADDR;
+unsigned long sparc_iobase_vaddr = IOBASE_VADDR;
+
+/*
+ * sparc_alloc_io:
+ * Map and allocates an obio device.
+ * Implements a simple linear allocator, you can force the function
+ * to use your own mapping, but in practice this should not be used.
+ *
+ * Input:
+ *  address: the obio address to map
+ *  virtual: if non zero, specifies a fixed virtual address where
+ *           the mapping should take place.
+ *  len:     the length of the mapping
+ *  bus_type: The bus on which this io area sits.
+ *
+ * Returns:
+ *  The virtual address where the mapping actually took place.
+ */
+
+void *sparc_alloc_io (void *address, void *virtual, int len, char *name,
+                     int bus_type, int rdonly)
+{
+       unsigned long vaddr, base_address;
+       unsigned long addr = (unsigned long) address;
+       unsigned long offset = (addr & (~PAGE_MASK));
+
+       if (virtual) {
+               vaddr = (unsigned long) virtual;
+
+               len += offset;
+               if(((unsigned long) virtual + len) > (IOBASE_VADDR + IOBASE_LEN)) {
+                       prom_printf("alloc_io: Mapping outside IOBASE area\n");
+                       prom_halt();
+               }
+               if(check_region ((vaddr | offset), len)) {
+                       prom_printf("alloc_io: 0x%lx is already in use\n", vaddr);
+                       prom_halt();
+               }
+
+               /* Tell Linux resource manager about the mapping */
+               request_region ((vaddr | offset), len, name);
+       } else {
+               vaddr = occupy_region(sparc_iobase_vaddr, IOBASE_END,
+                               (offset + len + PAGE_SIZE-1) & PAGE_MASK, PAGE_SIZE, name);
+               if (vaddr == 0) {
+                       /* Usually we cannot see printks in this case. */
+                       prom_printf("alloc_io: cannot occupy %d region\n", len);
+                       prom_halt();
+               }
+       }
+
+       base_address = vaddr;
+       /* Do the actual mapping */
+       for (; len > 0; len -= PAGE_SIZE) {
+               mapioaddr(addr, vaddr, bus_type, rdonly);
+               vaddr += PAGE_SIZE;
+               addr += PAGE_SIZE;
+       }
+
+       return (void *) (base_address | offset);
+}
+
+void sparc_free_io (void *virtual, int len)
+{
+       unsigned long vaddr = (unsigned long) virtual & PAGE_MASK;
+       unsigned long plen = (((unsigned long)virtual & ~PAGE_MASK) + len + PAGE_SIZE-1) & PAGE_MASK;
+
+       release_region(vaddr, plen);
+
+       for (; plen != 0;) {
+               plen -= PAGE_SIZE;
+               unmapioaddr(vaddr + plen);
+       }
+}
+
+/* Does DVMA allocations with PAGE_SIZE granularity.  How this basically
+ * works is that the ESP chip can do DVMA transfers at ANY address with
+ * certain size and boundary restrictions.  But other devices that are
+ * attached to it and would like to do DVMA have to set things up in
+ * a special way, if the DVMA sees a device attached to it transfer data
+ * at addresses above DVMA_VADDR it will grab them, this way it does not
+ * now have to know the peculiarities of where to read the Lance data
+ * from. (for example)
+ */
+void *sparc_dvma_malloc (int len, char *name)
+{
+       unsigned long vaddr, base_address;
+
+       vaddr = dvma_next_free;
+       if(check_region (vaddr, len)) {
+               prom_printf("alloc_dma: 0x%lx is already in use\n", vaddr);
+               prom_halt();
+       }
+       if(vaddr + len > (DVMA_VADDR + DVMA_LEN)) {
+               prom_printf("alloc_dvma: out of dvma memory\n");
+               prom_halt();
+       }
+
+       /* Basically these can be mapped just like any old
+        * IO pages, cacheable bit off, etc.  The physical
+        * pages are now mapped dynamically to save space.
+        */
+       base_address = vaddr;
+       mmu_map_dma_area(base_address, len);
+       /* Assign the memory area. */
+       dvma_next_free = PAGE_ALIGN(dvma_next_free+len);
+
+       request_region(base_address, len, name);
+
+       return (void *) base_address;
+}
diff --git a/arch/sparc64/kernel/itlb_miss.S b/arch/sparc64/kernel/itlb_miss.S
new file mode 100644 (file)
index 0000000..a48e7cc
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id: itlb_miss.S,v 1.4 1996/12/28 18:39:42 davem Exp $
+ * itlb_miss.S:        Instruction TLB miss code, this is included directly
+ *              into the trap table.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+       /* We are in the MMU globals, %g7 contains the physical
+        * address of current->mm->pgd at all times.  %g2 is
+        * also preloaded with the mask 0x1ff8 to make things
+        * even quicker.
+        *
+        * Many subtle things are done here.  The high bits of
+        * the virtual address missed are most easily obtained
+        * from the tag target (it is at address zero in ASI_IMMU
+        * so no address formation is necessary to get at this).
+        * This is used to compute the pgd and pmd table offsets.
+        *
+        * Even more clever is that physical page zero is always
+        * a page full of zeroes.  This means we can just follow
+        * through with all the page table traversals even if nothing
+        * is mapped because we'll just do loads from page zero
+        * and get yet another zero.  We only need to do the check
+        * for the valid bit being set in the final pte we obtain.
+        *
+        * Furthermore, we set the TSB base register to the address
+        * zero, and we use the 8KB tsb ptr to calculate the pte
+        * offset.  Again it is at address zero in ASI_IMMU_TSB_8KB_PTR
+        * so no address formation is necessary, saves more instructions.
+        *
+        * We use physical address accesses to get at the page
+        * tables, and this is for two reasons.  This makes it
+        * impossible to take a fault while we are servicing the
+        * miss.  Also this physical bypass access only allocates
+        * in the E-cache, and thus we prevent D-cache pollution
+        * from the miss handlers probing the page tables.
+        *
+        * It looks very hairy and slow.  But I take only 1 more
+        * overhead of loads from ram than the Solaris version, and
+        * my version is one instruction quicker for a true TLB miss.
+        * And more importantly, all true TLB misses under Linux will be
+        * serviced in _constant_ time.  When using the TSB in the
+        * manner it was intended to be used (like solaris does) the
+        * overhead for a TLB miss is _indeterminate_ especially during
+        * processes startup when the TSB is cold.
+        */
+
+itlb_miss:
+       /* I-cache line 0 */
+       ldxa            [%g0] ASI_IMMU, %g1             ! grab Tag Target
+       srlx            %g1, 8, %g3                     ! put high vaddr bits in place
+       and             %g3, %g2, %g3                   ! get offset
+       ldxa            [%g7 + %g3] ASI_PHYS_USE_EC, %g5! load pgd
+       sllx            %g1, 2, %g4                     ! begin pmd_offset formation
+       and             %g4, %g2, %g3                   ! and now mask it
+       ldxa            [%g5 + %g3] ASI_PHYS_USE_EC, %g4! load pmd
+       ldxa            [%g0] ASI_IMMU_TSB_8KB_PTR, %g1 ! get 8KB pointer bits
+       /* I-cache line 1 */
+       srlx            %g1, 1, %g1                     ! shift right to get pte_offset
+       ldxa            [%g4 + %g1] ASI_PHYS_USE_EC, %g2! load pte
+       brlz,a,pt       %g2, 1f                         ! is valid bit clear?
+        stxa           %g2, [%g0] ASI_ITLB_DATA_IN     ! nope, load TTE into ITLB
+
+       ba,a,pt         %xcc, sparc64_itlb_refbit_catch ! longer processing needed
+1:
+       retry                                           ! return from trap
+
+       nop; nop;
+       /* I-cache line 2 */
+       nop; nop; nop; nop; nop; nop; nop; nop;
+       /* I-cache line 3 */
+       nop; nop; nop; nop; nop; nop; nop; nop;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
new file mode 100644 (file)
index 0000000..e0ac223
--- /dev/null
@@ -0,0 +1,582 @@
+/*  $Id: process.c,v 1.1 1996/12/28 18:39:39 davem Exp $
+ *  arch/sparc64/kernel/process.c
+ *
+ *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <stdarg.h>
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/config.h>
+
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/delay.h>
+#include <asm/processor.h>
+#include <asm/pstate.h>
+#include <asm/elf.h>
+
+extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
+
+#ifndef __SMP__
+
+/*
+ * the idle loop on a Sparc... ;)
+ */
+asmlinkage int sys_idle(void)
+{
+       if (current->pid != 0)
+               return -EPERM;
+
+       /* endless idle loop with no priority at all */
+       current->counter = -100;
+       for (;;)
+               schedule();
+       return 0;
+}
+
+#else
+
+/*
+ * the idle loop on a SparcMultiPenguin...
+ */
+asmlinkage int sys_idle(void)
+{
+       if (current->pid != 0)
+               return -EPERM;
+
+       /* endless idle loop with no priority at all */
+       current->counter = -100;
+       schedule();
+       return 0;
+}
+
+/* This is being executed in task 0 'user space'. */
+int cpu_idle(void *unused)
+{
+       volatile int *spap = &smp_process_available;
+       volatile int cval;
+
+       while(1) {
+               if(0==*spap)
+                       continue;
+               cli();
+               /* Acquire exclusive access. */
+               while((cval = smp_swap(spap, -1)) == -1)
+                       while(*spap == -1)
+                               ;
+                if (0==cval) {
+                       /* ho hum, release it. */
+                       *spap = 0;
+                       sti();
+                        continue;
+                }
+               /* Something interesting happened, whee... */
+               *spap = (cval - 1);
+               sti();
+               idle();
+       }
+}
+
+#endif
+
+extern char reboot_command [];
+
+#ifdef CONFIG_SUN_CONSOLE
+extern void console_restore_palette (void);
+extern int serial_console;
+#endif
+
+void halt_now(void)
+{
+       sti();
+       udelay(8000);
+       cli();
+#ifdef CONFIG_SUN_CONSOLE
+       if (!serial_console)
+               console_restore_palette ();
+#endif
+       prom_halt();
+       panic("Halt failed!");
+}
+
+void hard_reset_now(void)
+{
+       char *p;
+       
+       sti();
+       udelay(8000);
+       cli();
+
+       p = strchr (reboot_command, '\n');
+       if (p) *p = 0;
+#ifdef CONFIG_SUN_CONSOLE
+       if (!serial_console)
+               console_restore_palette ();
+#endif
+       if (*reboot_command)
+               prom_reboot (reboot_command);
+       prom_feval ("reset");
+       panic("Reboot failed!");
+}
+
+void show_regwindow(struct reg_window *rw)
+{
+       printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
+              "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
+              rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+              rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]);
+       printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
+              "i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
+              rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
+              rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
+}
+
+void show_regwindow32(struct reg_window32 *rw)
+{
+       printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx\n"
+              "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n",
+              rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+              rw->locals[4], rw->locals[5], rw->locals[6], rw->locals[7]);
+       printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx\n"
+              "i4: %08lx i5: %08lx i6: %08lx i7: %08lx\n",
+              rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
+              rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
+}
+
+void show_stackframe(struct sparc_stackf *sf)
+{
+       unsigned long size;
+       unsigned long *stk;
+       int i;
+
+       printk("l0: %016lx l1: %016lx l2: %016lx l3: %016lx\n"
+              "l4: %016lx l5: %016lx l6: %016lx l7: %016lx\n",
+              sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
+              sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
+       printk("i0: %016lx i1: %016lx i2: %016lx i3: %016lx\n"
+              "i4: %016lx i5: %016lx fp: %016lx ret_pc: %016lx\n",
+              sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
+              sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
+       printk("sp: %016lx x0: %016lx x1: %016lx x2: %016lx\n"
+              "x3: %016lx x4: %016lx x5: %016lx xx: %016lx\n",
+              (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
+              sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
+              sf->xxargs[0]);
+       size = ((unsigned long)sf->fp) - ((unsigned long)sf);
+       size -= STACKFRAME_SZ;
+       stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
+       i = 0;
+       do {
+               printk("s%d: %016lx\n", i++, *stk++);
+       } while ((size -= sizeof(unsigned long)));
+}
+
+void show_stackframe32(struct sparc_stackf32 *sf)
+{
+       unsigned long size;
+       unsigned long *stk;
+       int i;
+
+       printk("l0: %08lx l1: %08lx l2: %08lx l3: %08lx\n"
+              "l4: %08lx l5: %08lx l6: %08lx l7: %08lx\n",
+              sf->locals[0], sf->locals[1], sf->locals[2], sf->locals[3],
+              sf->locals[4], sf->locals[5], sf->locals[6], sf->locals[7]);
+       printk("i0: %08lx i1: %08lx i2: %08lx i3: %08lx\n"
+              "i4: %08lx i5: %08lx fp: %08lx ret_pc: %08lx\n",
+              sf->ins[0], sf->ins[1], sf->ins[2], sf->ins[3],
+              sf->ins[4], sf->ins[5], (unsigned long)sf->fp, sf->callers_pc);
+       printk("sp: %08lx x0: %08lx x1: %08lx x2: %08lx\n"
+              "x3: %08lx x4: %08lx x5: %08lx xx: %08lx\n",
+              (unsigned long)sf->structptr, sf->xargs[0], sf->xargs[1],
+              sf->xargs[2], sf->xargs[3], sf->xargs[4], sf->xargs[5],
+              sf->xxargs[0]);
+       size = ((unsigned long)sf->fp) - ((unsigned long)sf);
+       size -= STACKFRAME_SZ;
+       stk = (unsigned long *)((unsigned long)sf + STACKFRAME_SZ);
+       i = 0;
+       do {
+               printk("s%d: %08lx\n", i++, *stk++);
+       } while ((size -= sizeof(unsigned long)));
+}
+
+void show_regs(struct pt_regs * regs)
+{
+#if __MPP__
+       printk("CID: %d\n",mpp_cid());
+#endif
+        printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %016lx\n", regs->tstate,
+              regs->tpc, regs->tnpc, regs->y);
+       printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
+              regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+              regs->u_regs[3]);
+       printk("g4: %016lx g5: %016lx g6: %016lx g7: %016lx\n",
+              regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
+              regs->u_regs[7]);
+       printk("o0: %016lx o1: %016lx o2: %016lx o3: %016lx\n",
+              regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
+              regs->u_regs[11]);
+       printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
+              regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+              regs->u_regs[15]);
+       show_regwindow((struct reg_window *)regs->u_regs[14]);
+}
+
+void show_regs32(struct pt_regs32 *regs)
+{
+#if __MPP__
+       printk("CID: %d\n",mpp_cid());
+#endif
+        printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx\n", regs->psr,
+              regs->pc, regs->npc, regs->y);
+       printk("g0: %08lx g1: %08lx g2: %08lx g3: %08lx\n",
+              regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+              regs->u_regs[3]);
+       printk("g4: %08lx g5: %08lx g6: %08lx g7: %08lx\n",
+              regs->u_regs[4], regs->u_regs[5], regs->u_regs[6],
+              regs->u_regs[7]);
+       printk("o0: %08lx o1: %08lx o2: %08lx o3: %08lx\n",
+              regs->u_regs[8], regs->u_regs[9], regs->u_regs[10],
+              regs->u_regs[11]);
+       printk("o4: %08lx o5: %08lx sp: %08lx ret_pc: %08lx\n",
+              regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+              regs->u_regs[15]);
+       show_regwindow32((struct reg_window32 *)regs->u_regs[14]);
+}
+
+void show_thread(struct thread_struct *tss)
+{
+       int i;
+
+       printk("kregs:             0x%016lx\n", (unsigned long)tss->kregs);
+       show_regs(tss->kregs);
+       printk("sig_address:       0x%016lx\n", tss->sig_address);
+       printk("sig_desc:          0x%016lx\n", tss->sig_desc);
+       printk("ksp:               0x%016lx\n", tss->ksp);
+       printk("kpc:               0x%016lx\n", tss->kpc);
+
+       for (i = 0; i < NSWINS; i++) {
+               if (!tss->rwbuf_stkptrs[i])
+                       continue;
+               printk("reg_window[%d]:\n", i);
+               printk("stack ptr:         0x%016lx\n", tss->rwbuf_stkptrs[i]);
+               show_regwindow(&tss->reg_window[i]);
+       }
+       printk("w_saved:           0x%08lx\n", tss->w_saved);
+
+       /* XXX missing: float_regs */
+       printk("fsr:               0x%016lx\n", tss->fsr);
+       printk("fpqdepth:          0x%016lx\n", tss->fpqdepth);
+       /* XXX missing: fpqueue */
+
+       printk("sstk_info.stack:   0x%016lx\n",
+               (unsigned long)tss->sstk_info.the_stack);
+       printk("sstk_info.status:  0x%016lx\n",
+               (unsigned long)tss->sstk_info.cur_status);
+       printk("flags:             0x%016lx\n", tss->flags);
+       printk("current_ds:        0x%016lx\n", tss->current_ds);
+
+       /* XXX missing: core_exec */
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+       kill_user_windows();
+#ifndef __SMP__
+       if(last_task_used_math == current) {
+#else
+       if(current->flags & PF_USEDFPU) {
+#endif
+               /* Keep process from leaving FPU in a bogon state. */
+               put_psr(get_psr() | PSR_EF);
+               fpsave(&current->tss.float_regs[0], &current->tss.fsr,
+                      &current->tss.fpqueue[0], &current->tss.fpqdepth);
+#ifndef __SMP__
+               last_task_used_math = NULL;
+#else
+               current->flags &= ~PF_USEDFPU;
+#endif
+       }
+       mmu_exit_hook();
+}
+
+void flush_thread(void)
+{
+       kill_user_windows();
+       current->tss.w_saved = 0;
+       current->tss.uwinmask = 0;
+       current->tss.sstk_info.cur_status = 0;
+       current->tss.sstk_info.the_stack = 0;
+
+       /* No new signal delivery by default */
+       current->tss.new_signal = 0;
+#ifndef __SMP__
+       if(last_task_used_math == current) {
+#else
+       if(current->flags & PF_USEDFPU) {
+#endif
+               /* Clean the fpu. */
+               put_psr(get_psr() | PSR_EF);
+               fpsave(&current->tss.float_regs[0], &current->tss.fsr,
+                      &current->tss.fpqueue[0], &current->tss.fpqdepth);
+#ifndef __SMP__
+               last_task_used_math = NULL;
+#else
+               current->flags &= ~PF_USEDFPU;
+#endif
+       }
+
+       mmu_flush_hook();
+       /* Now, this task is no longer a kernel thread. */
+       current->tss.flags &= ~SPARC_FLAG_KTHREAD;
+       current->tss.current_ds = USER_DS;
+}
+
+static __inline__ void copy_regs(struct pt_regs *dst, struct pt_regs *src)
+{
+       __asm__ __volatile__("ldd\t[%1 + 0x00], %%g2\n\t"
+                            "ldd\t[%1 + 0x08], %%g4\n\t"
+                            "ldd\t[%1 + 0x10], %%o4\n\t"
+                            "std\t%%g2, [%0 + 0x00]\n\t"
+                            "std\t%%g4, [%0 + 0x08]\n\t"
+                            "std\t%%o4, [%0 + 0x10]\n\t"
+                            "ldd\t[%1 + 0x18], %%g2\n\t"
+                            "ldd\t[%1 + 0x20], %%g4\n\t"
+                            "ldd\t[%1 + 0x28], %%o4\n\t"
+                            "std\t%%g2, [%0 + 0x18]\n\t"
+                            "std\t%%g4, [%0 + 0x20]\n\t"
+                            "std\t%%o4, [%0 + 0x28]\n\t"
+                            "ldd\t[%1 + 0x30], %%g2\n\t"
+                            "ldd\t[%1 + 0x38], %%g4\n\t"
+                            "ldd\t[%1 + 0x40], %%o4\n\t"
+                            "std\t%%g2, [%0 + 0x30]\n\t"
+                            "std\t%%g4, [%0 + 0x38]\n\t"
+                            "ldd\t[%1 + 0x48], %%g2\n\t"
+                            "std\t%%o4, [%0 + 0x40]\n\t"
+                            "std\t%%g2, [%0 + 0x48]\n\t" : :
+                            "r" (dst), "r" (src) :
+                            "g2", "g3", "g4", "g5", "o4", "o5");
+}
+
+static __inline__ void copy_regwin(struct reg_window *dst, struct reg_window *src)
+{
+       __asm__ __volatile__("ldd\t[%1 + 0x00], %%g2\n\t"
+                            "ldd\t[%1 + 0x08], %%g4\n\t"
+                            "ldd\t[%1 + 0x10], %%o4\n\t"
+                            "std\t%%g2, [%0 + 0x00]\n\t"
+                            "std\t%%g4, [%0 + 0x08]\n\t"
+                            "std\t%%o4, [%0 + 0x10]\n\t"
+                            "ldd\t[%1 + 0x18], %%g2\n\t"
+                            "ldd\t[%1 + 0x20], %%g4\n\t"
+                            "ldd\t[%1 + 0x28], %%o4\n\t"
+                            "std\t%%g2, [%0 + 0x18]\n\t"
+                            "std\t%%g4, [%0 + 0x20]\n\t"
+                            "std\t%%o4, [%0 + 0x28]\n\t"
+                            "ldd\t[%1 + 0x30], %%g2\n\t"
+                            "ldd\t[%1 + 0x38], %%g4\n\t"
+                            "std\t%%g2, [%0 + 0x30]\n\t"
+                            "std\t%%g4, [%0 + 0x38]\n\t" : :
+                            "r" (dst), "r" (src) :
+                            "g2", "g3", "g4", "g5", "o4", "o5");
+}
+
+static __inline__ struct sparc_stackf *
+clone_stackframe(struct sparc_stackf *dst, struct sparc_stackf *src)
+{
+       unsigned long size;
+       struct sparc_stackf *sp;
+
+       size = ((unsigned long)src->fp) - ((unsigned long)src);
+       sp = (struct sparc_stackf *)(((unsigned long)dst) - size); 
+
+       if (copy_to_user(sp, src, size))
+               return 0;
+       if (put_user(dst, &sp->fp))
+               return 0;
+       return sp;
+}
+
+
+/* Copy a Sparc thread.  The fork() return value conventions
+ * under SunOS are nothing short of bletcherous:
+ * Parent -->  %o0 == childs  pid, %o1 == 0
+ * Child  -->  %o0 == parents pid, %o1 == 1
+ *
+ * NOTE: We have a separate fork kpsr/kwim because
+ *       the parent could change these values between
+ *       sys_fork invocation and when we reach here
+ *       if the parent should sleep while trying to
+ *       allocate the task_struct and kernel stack in
+ *       do_fork().
+ */
+extern void ret_from_syscall(void);
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+               struct task_struct *p, struct pt_regs *regs)
+{
+       struct pt_regs *childregs;
+       struct reg_window *new_stack;
+       unsigned long stack_offset;
+
+#ifndef __SMP__
+       if(last_task_used_math == current) {
+#else
+       if(current->flags & PF_USEDFPU) {
+#endif
+               put_psr(get_psr() | PSR_EF);
+               fpsave(&p->tss.float_regs[0], &p->tss.fsr,
+                      &p->tss.fpqueue[0], &p->tss.fpqdepth);
+#ifdef __SMP__
+               current->flags &= ~PF_USEDFPU;
+#endif
+       }
+
+       /* Calculate offset to stack_frame & pt_regs */
+       stack_offset = ((PAGE_SIZE<<1) - TRACEREG_SZ);
+
+       if(regs->psr & PSR_PS)
+               stack_offset -= REGWIN_SZ;
+       childregs = ((struct pt_regs *) (p->kernel_stack_page + stack_offset));
+       copy_regs(childregs, regs);
+       new_stack = (((struct reg_window *) childregs) - 1);
+       copy_regwin(new_stack, (((struct reg_window *) regs) - 1));
+
+       p->tss.ksp = p->saved_kernel_stack = (unsigned long) new_stack;
+       p->tss.kpc = (((unsigned long) ret_from_syscall) - 0x8);
+       p->tss.kpsr = current->tss.fork_kpsr;
+       p->tss.kwim = current->tss.fork_kwim;
+       p->tss.kregs = childregs;
+
+       if(regs->psr & PSR_PS) {
+               childregs->u_regs[UREG_FP] = p->tss.ksp;
+               p->tss.flags |= SPARC_FLAG_KTHREAD;
+               p->tss.current_ds = KERNEL_DS;
+               childregs->u_regs[UREG_G6] = (unsigned long) p;
+       } else {
+               childregs->u_regs[UREG_FP] = sp;
+               p->tss.flags &= ~SPARC_FLAG_KTHREAD;
+               p->tss.current_ds = USER_DS;
+
+               if (sp != current->tss.kregs->u_regs[UREG_FP]) {
+                       struct sparc_stackf *childstack;
+                       struct sparc_stackf *parentstack;
+
+                       /*
+                        * This is a clone() call with supplied user stack.
+                        * Set some valid stack frames to give to the child.
+                        */
+                       childstack = (struct sparc_stackf *)sp;
+                       parentstack = (struct sparc_stackf *)
+                                       current->tss.kregs->u_regs[UREG_FP];
+
+#if 0
+                       printk("clone: parent stack:\n");
+                       show_stackframe(parentstack);
+#endif
+
+                       childstack = clone_stackframe(childstack, parentstack);
+                       if (!childstack)
+                               return -EFAULT;
+
+#if 0
+                       printk("clone: child stack:\n");
+                       show_stackframe(childstack);
+#endif
+
+                       childregs->u_regs[UREG_FP] = (unsigned long)childstack;
+               }
+       }
+
+       /* Set the return value for the child. */
+       childregs->u_regs[UREG_I0] = current->pid;
+       childregs->u_regs[UREG_I1] = 1;
+
+       /* Set the return value for the parent. */
+       regs->u_regs[UREG_I1] = 0;
+
+       return 0;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+       unsigned long first_stack_page;
+
+       dump->magic = SUNOS_CORE_MAGIC;
+       dump->len = sizeof(struct user);
+       dump->regs.psr = regs->psr;
+       dump->regs.pc = regs->pc;
+       dump->regs.npc = regs->npc;
+       dump->regs.y = regs->y;
+       /* fuck me plenty */
+       memcpy(&dump->regs.regs[0], &regs->u_regs[1], (sizeof(unsigned long) * 15));
+       dump->uexec = current->tss.core_exec;
+       dump->u_tsize = (((unsigned long) current->mm->end_code) -
+               ((unsigned long) current->mm->start_code)) & ~(PAGE_SIZE - 1);
+       dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1)));
+       dump->u_dsize -= dump->u_tsize;
+       dump->u_dsize &= ~(PAGE_SIZE - 1);
+       first_stack_page = (regs->u_regs[UREG_FP] & ~(PAGE_SIZE - 1));
+       dump->u_ssize = (TASK_SIZE - first_stack_page) & ~(PAGE_SIZE - 1);
+       memcpy(&dump->fpu.fpstatus.fregs.regs[0], &current->tss.float_regs[0], (sizeof(unsigned long) * 32));
+       dump->fpu.fpstatus.fsr = current->tss.fsr;
+       dump->fpu.fpstatus.flags = dump->fpu.fpstatus.extra = 0;
+       dump->fpu.fpstatus.fpq_count = current->tss.fpqdepth;
+       memcpy(&dump->fpu.fpstatus.fpq[0], &current->tss.fpqueue[0],
+              ((sizeof(unsigned long) * 2) * 16));
+       dump->sigcode = current->tss.sig_desc;
+}
+
+/*
+ * fill in the fpu structure for a core dump.
+ */
+int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
+{
+       /* Currently we report that we couldn't dump the fpu structure */
+       return 0;
+}
+
+/*
+ * sparc_execve() executes a new program after the asm stub has set
+ * things up for us.  This should basically do what I want it to.
+ */
+asmlinkage int sparc_execve(struct pt_regs *regs)
+{
+       int error, base = 0;
+       char *filename;
+
+       /* Check for indirect call. */
+       if(regs->u_regs[UREG_G1] == 0)
+               base = 1;
+
+       error = getname((char *) regs->u_regs[base + UREG_I0], &filename);
+       if(error)
+               return error;
+       error = do_execve(filename, (char **) regs->u_regs[base + UREG_I1],
+                         (char **) regs->u_regs[base + UREG_I2], regs);
+       putname(filename);
+       return error;
+}
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
new file mode 100644 (file)
index 0000000..2cfd8ab
--- /dev/null
@@ -0,0 +1,714 @@
+/*  $Id: signal32.c,v 1.1 1996/12/26 10:16:41 davem Exp $
+ *  arch/sparc64/kernel/signal32.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/mm.h>
+
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/ptrace.h>
+#include <asm/svr4.h>
+#include <asm/pgtable.h>
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options);
+
+extern void fpsave32(unsigned long *fpregs, unsigned long *fsr,
+                    void *fpqueue, unsigned long *fpqdepth);
+extern void fpload32(unsigned long *fpregs, unsigned long *fsr);
+
+asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
+                        unsigned long orig_o0, int ret_from_syscall);
+
+/* This turned off for production... */
+/* #define DEBUG_SIGNALS 1 */
+
+/* Signal frames: the original one (compatible with SunOS):
+ *
+ * Set up a signal frame... Make the stack look the way SunOS
+ * expects it to look which is basically:
+ *
+ * ---------------------------------- <-- %sp at signal time
+ * Struct sigcontext
+ * Signal address
+ * Ptr to sigcontext area above
+ * Signal code
+ * The signal number itself
+ * One register window
+ * ---------------------------------- <-- New %sp
+ */
+struct signal_sframe32 {
+       struct reg_window_32 sig_window;
+       int sig_num;
+       int sig_code;
+       struct sigcontext_32 *sig_scptr;
+       int sig_address;
+       struct sigcontext_32 sig_context;
+};
+
+/* 
+ * And the new one, intended to be used for Linux applications only
+ * (we have enough in there to work with clone).
+ * All the interesting bits are in the info field.
+ */
+
+struct new_signal_frame32 {
+       struct      sparc_stackf_32 ss;
+       __siginfo32_t info;
+       unsigned    int __pad;
+       unsigned    int insns [2];
+};
+
+/* Align macros */
+#define SF_ALIGNEDSZ  (((sizeof(struct signal_sframe32) + 7) & (~7)))
+#define NF_ALIGNEDSZ  (((sizeof(struct new_signal_frame32) + 7) & (~7)))
+
+/*
+ * atomically swap in the new signal mask, and wait for a signal.
+ * This is really tricky on the Sparc, watch out...
+ */
+asmlinkage inline void _sigpause32_common(unsigned int set, struct pt_regs *regs)
+{
+       unsigned int mask;
+
+       mask = current->blocked;
+       current->blocked = set & _BLOCKABLE;
+       regs->tpc = regs->tnpc;
+       regs->tnpc += 4;
+
+       /* Condition codes and return value where set here for sigpause,
+        * and so got used by setup_frame, which again causes sigreturn()
+        * to return -EINTR.
+        */
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule();
+               /*
+                * Return -EINTR and set condition code here,
+                * so the interrupted system call actually returns
+                * these.
+                */
+               regs->tstate |= TSTATE_ICARRY;
+               regs->u_regs[UREG_I0] = EINTR;
+               if (do_signal32(mask, regs, 0, 0))
+                       return;
+       }
+}
+
+asmlinkage void do_sigpause32(unsigned int set, struct pt_regs *regs)
+{
+       _sigpause32_common(set, regs);
+}
+
+asmlinkage void do_sigsuspend32(struct pt_regs *regs)
+{
+       _sigpause32_common(regs->u_regs[UREG_I0], regs);
+}
+
+void do_new_sigreturn32(struct pt_regs *regs)
+{
+       struct new_signal_frame32 *sf;
+       unsigned long up_tstate;
+       
+       sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP];
+       /* 1. Make sure we are not getting garbage from the user */
+       if (verify_area (VERIFY_READ, sf, sizeof (*sf))){
+               do_exit (SIGSEGV);
+               return;
+       }
+       if (((uint) sf) & 3){
+               do_exit (SIGSEGV);
+               return;
+       }
+       if ((sf->info.si_regs.pc | sf->info.si_regs.npc) & 3){
+               do_exit (SIGSEGV);
+               return;
+       }
+       
+       /* 2. Restore the state */
+       copy_32bit_to_kernel_ptregs (regs, &sf->info.si_regs, sizeof (struct pt_regs));
+
+       /* User can only change condition codes and FPU enabling in the %tstate. */
+       regs->tstate &= ~(TSTATE_ICC | TSTATE_PEF);
+       regs->tstate |= psr_to_tstate_icc(sf->info.si_regs.psr);
+       regs->tstate |= (sf->info.si_regs.psr & PSR_EF);
+
+       if (regs->tstate & TSTATE_PEF) {
+               regs->psr &= ~(TSTATE_PEF);
+#ifndef __SMP__
+               if(current == last_task_used_math)
+                       last_task_used_math = 0;
+#endif
+               current->used_math = 1;
+               current->flags &= ~(PF_USEDFPU);
+
+               /* Copy signal FPU state into thread struct FPU state. */
+               copy_32bit_to_kernel_fpuregs(&current->tss.float_regs[0],
+                                            &sf->info.si_float_regs[0],
+                                            (sizeof(unsigned int) * 64));
+               current->tss.fsr = sf->info.si_fsr;
+               if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+                   memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+                          ((sizeof(unsigned int) + (sizeof(unsigned int *))) * 16));
+       }
+       current->blocked = sf->info.si_mask & _BLOCKABLE;
+}
+
+asmlinkage void do_sigreturn32(struct pt_regs *regs)
+{
+       struct sigcontext *scptr;
+       unsigned long pc, npc, psr;
+
+       synchronize_user_stack();
+       if (current->tss.new_signal)
+               return do_new_sigreturn32(regs);
+
+       scptr = (struct sigcontext *) regs->u_regs[UREG_I0];
+       /* Check sanity of the user arg. */
+       if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
+          (((unsigned long) scptr) & 3)) {
+               printk("%s [%d]: do_sigreturn, scptr is invalid at "
+                      "pc<%08lx> scptr<%p>\n",
+                      current->comm, current->pid, regs->pc, scptr);
+               do_exit(SIGSEGV);
+       }
+       __get_user(pc, &scptr->sigc_pc);
+       __get_user(npc, &scptr->sigc_npc);
+       if((pc | npc) & 3)
+               do_exit(SIGSEGV); /* Nice try. */
+
+       __get_user(current->blocked, &scptr->sigc_mask);
+       current->blocked &= _BLOCKABLE;
+       __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack);
+       current->tss.sstk_info.cur_status &= 1;
+       regs->pc = pc;
+       regs->npc = npc;
+       __get_user(regs->u_regs[UREG_FP], &scptr->sigc_sp);
+       __get_user(regs->u_regs[UREG_I0], &scptr->sigc_o0);
+       __get_user(regs->u_regs[UREG_G1], &scptr->sigc_g1);
+
+       /* User can only change condition codes in %psr. */
+       __get_user(psr, &scptr->sigc_psr);
+       regs->psr &= ~(PSR_ICC);
+       regs->psr |= (psr & PSR_ICC);
+}
+
+/* Checks if the fp is valid */
+static int invalid_frame_pointer(void *fp, int fplen)
+{
+       if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
+               return 1;
+       return 0;
+}
+
+static inline void
+setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
+             struct pt_regs *regs, int signr, unsigned long oldmask)
+{
+       struct signal_sframe32 *sframep;
+       struct sigcontext *sc;
+       int window = 0;
+       int old_status = current->tss.sstk_info.cur_status;
+
+       synchronize_user_stack();
+       sframep = (struct signal_sframe32 *) regs->u_regs[UREG_FP];
+       sframep = (struct signal_sframe32 *) (((unsigned long) sframep)-SF_ALIGNEDSZ);
+       if (invalid_frame_pointer (sframep, sizeof(*sframep))){
+#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
+               printk("%s [%d]: User has trashed signal stack\n",
+                      current->comm, current->pid);
+               printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
+                      sframep, pc, signr);
+#endif
+               /* Don't change signal code and address, so that
+                * post mortem debuggers can have a look.
+                */
+               do_exit(SIGILL);
+               return;
+       }
+
+       sc = &sframep->sig_context;
+
+       /* We've already made sure frame pointer isn't in kernel space... */
+       __put_user(old_status, &sc->sigc_onstack);
+       __put_user(oldmask, &sc->sigc_mask);
+       __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
+       __put_user(pc, &sc->sigc_pc);
+       __put_user(npc, &sc->sigc_npc);
+       __put_user(regs->psr, &sc->sigc_psr);
+       __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
+       __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
+       __put_user(current->tss.w_saved, &sc->sigc_oswins);
+       if(current->tss.w_saved)
+               for(window = 0; window < current->tss.w_saved; window++) {
+                       sc->sigc_spbuf[window] =
+                               (char *)current->tss.rwbuf_stkptrs[window];
+                       copy_to_user(&sc->sigc_wbuf[window],
+                              &current->tss.reg_window[window],
+                              sizeof(struct reg_window));
+               }
+       else
+               copy_to_user(sframep, (char *)regs->u_regs[UREG_FP],
+                      sizeof(struct reg_window));
+
+       current->tss.w_saved = 0; /* So process is allowed to execute. */
+       __put_user(signr, &sframep->sig_num);
+       if(signr == SIGSEGV ||
+          signr == SIGILL ||
+          signr == SIGFPE ||
+          signr == SIGBUS ||
+          signr == SIGEMT) {
+               __put_user(current->tss.sig_desc, &sframep->sig_code);
+               __put_user(current->tss.sig_address, &sframep->sig_address);
+       } else {
+               __put_user(0, &sframep->sig_code);
+               __put_user(0, &sframep->sig_address);
+       }
+       __put_user(sc, &sframep->sig_scptr);
+       regs->u_regs[UREG_FP] = (unsigned long) sframep;
+       regs->pc = (unsigned long) sa->sa_handler;
+       regs->npc = (regs->pc + 4);
+}
+
+/* To align the structure properly. */
+
+static inline void
+new_setup_frame32(struct sigaction *sa, struct pt_regs *regs,
+                 int signo, unsigned long oldmask)
+{
+       struct new_signal_frame32 *sf;
+
+       /* 1. Make sure everything is clean */
+       synchronize_user_stack();
+       sf = (struct new_signal_frame *) regs->u_regs[UREG_FP];
+       sf = (struct new_signal_frame *) (((unsigned long) sf)-NF_ALIGNEDSZ);
+       
+       if (invalid_frame_pointer (sf, sizeof(struct new_signal_frame))){
+               do_exit(SIGILL);
+               return;
+       }
+
+       if (current->tss.w_saved != 0){
+               printk ("%s[%d]: Invalid user stack frame for signal delivery.\n",
+                       current->comm, current->pid);
+               do_exit (SIGILL);
+               return;
+       }
+
+       /* 2. Save the current process state */
+       memcpy (&sf->info.si_regs, regs, sizeof (struct pt_regs));
+#ifdef __SMP__
+       if(current->flags & PF_USEDFPU) {
+               put_psr(get_psr() | PSR_EF);
+               fpsave (&sf->info.si_float_regs [0], &sf->info.si_fsr,
+                       &sf->info.si_fpqueue[0], &sf->info.si_fpqdepth);
+
+               /* Save a copy into thread struct as well. */
+               memcpy(&current->tss.float_regs[0], &sf->info.si_float_regs[0],
+                      (sizeof(unsigned long) * 64));
+               current->tss.fsr = sf->info.si_fsr;
+               if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+                   memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+                          ((sizeof(unsigned long) + (sizeof(unsigned long *))) * 16));
+
+               regs->psr &= ~(PSR_EF);
+               current->flags &= ~(PF_USEDFPU);
+       }
+#else
+       if(current == last_task_used_math) {
+               put_psr(get_psr() | PSR_EF);
+               fpsave (&sf->info.si_float_regs [0], &sf->info.si_fsr,
+                       &sf->info.si_fpqueue[0], &sf->info.si_fpqdepth);
+
+               /* Save a copy into thread struct as well. */
+               memcpy(&current->tss.float_regs[0], &sf->info.si_float_regs[0],
+                      (sizeof(unsigned long) * 64));
+               current->tss.fsr = sf->info.si_fsr;
+               if((current->tss.fpqdepth = sf->info.si_fpqdepth) != 0)
+                   memcpy(&current->tss.fpqueue[0], &sf->info.si_fpqueue[0],
+                          ((sizeof(unsigned long) + (sizeof(unsigned long *))) * 16));
+
+               last_task_used_math = NULL;
+               regs->psr &= ~(PSR_EF);
+       }
+#endif
+
+       /* This new thread of control has not used the FPU. */
+       current->used_math = 0;
+
+       sf->info.si_mask = oldmask;
+       memcpy (sf, (char *) regs->u_regs [UREG_FP], sizeof (struct reg_window));
+       
+       /* 3. return to kernel instructions */
+       sf->insns [0] = 0x821020d8; /* mov __NR_sigreturn,%g1 */
+       sf->insns [1] = 0x91d02010; /* t 0x10 */
+
+       /* 4. signal handler back-trampoline and parameters */
+       regs->u_regs[UREG_FP] = (unsigned long) sf;
+       regs->u_regs[UREG_I0] = signo;
+       regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+       regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
+
+       /* 5. signal handler */
+       regs->pc = (unsigned long) sa->sa_handler;
+       regs->npc = (regs->pc + 4);
+
+       /* Flush instruction space. */
+       flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
+}
+
+/* Setup a Solaris stack frame */
+static inline void
+setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
+                  struct pt_regs *regs, int signr, unsigned long oldmask)
+{
+       svr4_signal_frame_t *sfp;
+       svr4_gregset_t  *gr;
+       svr4_siginfo_t  *si;
+       svr4_mcontext_t *mc;
+       svr4_gwindows_t *gw;
+       svr4_ucontext_t *uc;
+       int window = 0;
+
+       synchronize_user_stack();
+       sfp = (svr4_signal_frame_t *) regs->u_regs[UREG_FP] - REGWIN_SZ;
+       sfp = (svr4_signal_frame_t *) (((unsigned long) sfp)-SVR4_SF_ALIGNED);
+
+       if (invalid_frame_pointer (sfp, sizeof (*sfp))){
+#ifdef DEBUG_SIGNALS
+               printk ("Invalid stack frame\n");
+#endif
+               do_exit(SIGILL);
+               return;
+       }
+
+       /* Start with a clean frame pointer and fill it */
+       clear_user(sfp, sizeof (*sfp));
+
+       /* Setup convenience variables */
+       si = &sfp->si;
+       uc = &sfp->uc;
+       gw = &sfp->gw;
+       mc = &uc->mcontext;
+       gr = &mc->greg;
+       
+       /* FIXME: where am I supposed to put this?
+        * sc->sigc_onstack = old_status;
+        * anyways, it does not look like it is used for anything at all.
+        */
+       __put_user(oldmask, &uc->sigmask.sigbits [0]);
+
+       /* Store registers */
+       __put_user(regs->pc, &((*gr) [SVR4_PC]));
+       __put_user(regs->npc, &((*gr) [SVR4_NPC]));
+       __put_user(regs->psr, &((*gr) [SVR4_PSR]));
+       __put_user(regs->y, &((*gr) [SVR4_Y]));
+       
+       /* Copy g [1..7] and o [0..7] registers */
+       copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (long) * 7);
+       copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (long) * 8);
+
+       /* Setup sigaltstack, FIXME */
+       __put_user(0xdeadbeef, &uc->stack.sp);
+       __put_user(0, &uc->stack.size);
+       __put_user(0, &uc->stack.flags);        /* Possible: ONSTACK, DISABLE */
+
+       /* Save the currently window file: */
+
+       /* 1. Link sfp->uc->gwins to our windows */
+       __put_user(gw, &mc->gwin);
+           
+       /* 2. Number of windows to restore at setcontext (): */
+       __put_user(current->tss.w_saved, &gw->count);
+
+       /* 3. Save each valid window
+        *    Currently, it makes a copy of the windows from the kernel copy.
+        *    David's code for SunOS, makes the copy but keeps the pointer to
+        *    the kernel.  My version makes the pointer point to a userland 
+        *    copy of those.  Mhm, I wonder if I shouldn't just ignore those
+        *    on setcontext and use those that are on the kernel, the signal
+        *    handler should not be modyfing those, mhm.
+        *
+        *    These windows are just used in case synchronize_user_stack failed
+        *    to flush the user windows.
+        */
+       for(window = 0; window < current->tss.w_saved; window++) {
+               __put_user((int *) &(gw->win [window]), &gw->winptr [window]);
+               copy_to_user(&gw->win [window], &current->tss.reg_window [window], sizeof (svr4_rwindow_t));
+               __put_user(0, gw->winptr [window]);
+       }
+
+       /* 4. We just pay attention to the gw->count field on setcontext */
+       current->tss.w_saved = 0; /* So process is allowed to execute. */
+
+       /* Setup the signal information.  Solaris expects a bunch of
+        * information to be passed to the signal handler, we don't provide
+        * that much currently, should use those that David already
+        * is providing with tss.sig_desc
+        */
+       __put_user(signr, &si->siginfo.signo);
+       __put_user(SVR4_SINOINFO, &si->siginfo.code);
+
+       regs->u_regs[UREG_FP] = (unsigned long) sfp;
+       regs->pc = (unsigned long) sa->sa_handler;
+       regs->npc = (regs->pc + 4);
+
+#ifdef DEBUG_SIGNALS
+       printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
+#endif
+       /* Arguments passed to signal handler */
+       if (regs->u_regs [14]){
+               struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
+
+               __put_user(signr, &rw->ins [0]);
+               __put_user(si, &rw->ins [1]);
+               __put_user(uc, &rw->ins [2]);
+               __put_user(sfp, &rw->ins [6]);  /* frame pointer */
+               regs->u_regs[UREG_I0] = signr;
+               regs->u_regs[UREG_I1] = (uint) si;
+               regs->u_regs[UREG_I2] = (uint) uc;
+       }
+}
+
+asmlinkage int
+svr4_getcontext32(svr4_ucontext_t *uc, struct pt_regs *regs)
+{
+       svr4_gregset_t  *gr;
+       svr4_mcontext_t *mc;
+
+       synchronize_user_stack();
+       if (current->tss.w_saved){
+               printk ("Uh oh, w_saved is not zero (%ld)\n", current->tss.w_saved);
+               do_exit (SIGSEGV);
+       }
+       if(clear_user(uc, sizeof (*uc)))
+               return -EFAULT;
+
+       /* Setup convenience variables */
+       mc = &uc->mcontext;
+       gr = &mc->greg;
+       
+       /* We only have < 32 signals, fill the first slot only */
+       __put_user(current->sig->action->sa_mask, &uc->sigmask.sigbits [0]);
+
+       /* Store registers */
+       __put_user(regs->pc, &uc->mcontext.greg [SVR4_PC]);
+       __put_user(regs->npc, &uc->mcontext.greg [SVR4_NPC]);
+       __put_user(regs->psr, &uc->mcontext.greg [SVR4_PSR]);
+        __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
+       
+       /* Copy g [1..7] and o [0..7] registers */
+       copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (uint) * 7);
+       copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (uint) * 8);
+
+       /* Setup sigaltstack, FIXME */
+       __put_user(0xdeadbeef, &uc->stack.sp);
+       __put_user(0, &uc->stack.size);
+       __put_user(0, &uc->stack.flags);        /* Possible: ONSTACK, DISABLE */
+
+       /* The register file is not saved
+        * we have already stuffed all of it with sync_user_stack
+        */
+       return 0;
+}
+
+
+/* Set the context for a svr4 application, this is Solaris way to sigreturn */
+asmlinkage int svr4_setcontext32(svr4_ucontext_t *c, struct pt_regs *regs)
+{
+       struct thread_struct *tp = &current->tss;
+       svr4_gregset_t  *gr;
+       unsigned long pc, npc, psr;
+       
+       /* Fixme: restore windows, or is this already taken care of in
+        * svr4_setup_frame when sync_user_windows is done?
+        */
+       flush_user_windows();
+       
+       if (tp->w_saved){
+               printk ("Uh oh, w_saved is: 0x%lx\n", tp->w_saved);
+               do_exit(SIGSEGV);
+       }
+       if (((uint) c) & 3){
+               printk ("Unaligned structure passed\n");
+               do_exit (SIGSEGV);
+       }
+
+       if(!__access_ok((unsigned long)c, sizeof(*c))) {
+               /* Miguel, add nice debugging msg _here_. ;-) */
+               do_exit(SIGSEGV);
+       }
+
+       /* Check for valid PC and nPC */
+       gr = &c->mcontext.greg;
+       __get_user(pc, &((*gr)[SVR4_PC]));
+       __get_user(npc, &((*gr)[SVR4_NPC]));
+       if((pc | npc) & 3) {
+               printk ("setcontext, PC or nPC were bogus\n");
+               do_exit (SIGSEGV);
+       }
+       /* Retrieve information from passed ucontext */
+           /* note that nPC is ored a 1, this is used to inform entry.S */
+           /* that we don't want it to mess with our PC and nPC */
+       __get_user(current->blocked, &c->sigmask.sigbits [0]);
+       current->blocked &= _BLOCKABLE;
+       regs->pc = pc;
+       regs->npc = npc | 1;
+       __get_user(regs->y, &((*gr) [SVR4_Y]));
+       __get_user(psr, &((*gr) [SVR4_PSR]));
+       regs->psr &= ~(PSR_ICC);
+       regs->psr |= (psr & PSR_ICC);
+
+       /* Restore g[1..7] and o[0..7] registers */
+       copy_from_user(&regs->u_regs [UREG_G1], &(*gr)[SVR4_G1], sizeof (long) * 7);
+       copy_from_user(&regs->u_regs [UREG_I0], &(*gr)[SVR4_O0], sizeof (long) * 8);
+
+       return -EINTR;
+}
+
+static inline void handle_signal32(unsigned long signr, struct sigaction *sa,
+                                  unsigned long oldmask, struct pt_regs *regs,
+                                  int svr4_signal)
+{
+       if(svr4_signal)
+               setup_svr4_frame32(sa, regs->pc, regs->npc, regs, signr, oldmask);
+       else {
+               if (current->tss.new_signal)
+                       new_setup_frame32(sa, regs, signr, oldmask);
+               else
+                       setup_frame32(sa, regs->pc, regs->npc, regs, signr, oldmask);
+       }
+       if(sa->sa_flags & SA_ONESHOT)
+               sa->sa_handler = NULL;
+       if(!(sa->sa_flags & SA_NOMASK))
+               current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+}
+
+static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
+                                    struct sigaction *sa)
+{
+       switch(regs->u_regs[UREG_I0]) {
+               case ERESTARTNOHAND:
+               no_system_call_restart:
+                       regs->u_regs[UREG_I0] = EINTR;
+                       regs->psr |= PSR_C;
+                       break;
+               case ERESTARTSYS:
+                       if(!(sa->sa_flags & SA_RESTART))
+                               goto no_system_call_restart;
+               /* fallthrough */
+               case ERESTARTNOINTR:
+                       regs->u_regs[UREG_I0] = orig_i0;
+                       regs->pc -= 4;
+                       regs->npc -= 4;
+       }
+}
+
+/* Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
+                          unsigned long orig_i0, int restart_syscall)
+{
+       unsigned long signr, mask = ~current->blocked;
+       struct sigaction *sa;
+       int svr4_signal = current->personality == PER_SVR4;
+       
+       while ((signr = current->signal & mask) != 0) {
+               signr = ffz(~signr);
+               clear_bit(signr, &current->signal);
+               sa = current->sig->action + signr;
+               signr++;
+               if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+                       current->exit_code = signr;
+                       current->state = TASK_STOPPED;
+                       notify_parent(current);
+                       schedule();
+                       if (!(signr = current->exit_code))
+                               continue;
+                       current->exit_code = 0;
+                       if (signr == SIGSTOP)
+                               continue;
+                       if (_S(signr) & current->blocked) {
+                               current->signal |= _S(signr);
+                               continue;
+                       }
+                       sa = current->sig->action + signr - 1;
+               }
+               if(sa->sa_handler == SIG_IGN) {
+                       if(signr != SIGCHLD)
+                               continue;
+                       while(sys_waitpid(-1,NULL,WNOHANG) > 0);
+                       continue;
+               }
+               if(sa->sa_handler == SIG_DFL) {
+                       if(current->pid == 1)
+                               continue;
+                       switch(signr) {
+                       case SIGCONT: case SIGCHLD: case SIGWINCH:
+                               continue;
+
+                       case SIGTSTP: case SIGTTIN: case SIGTTOU:
+                               if (is_orphaned_pgrp(current->pgrp))
+                                       continue;
+
+                       case SIGSTOP:
+                               if (current->flags & PF_PTRACED)
+                                       continue;
+                               current->state = TASK_STOPPED;
+                               current->exit_code = signr;
+                               if(!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
+                                    SA_NOCLDSTOP))
+                                       notify_parent(current);
+                               schedule();
+                               continue;
+
+                       case SIGQUIT: case SIGILL: case SIGTRAP:
+                       case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
+                               if(current->binfmt && current->binfmt->core_dump) {
+                                       if(current->binfmt->core_dump(signr, regs))
+                                               signr |= 0x80;
+                               }
+#ifdef DEBUG_SIGNALS
+                               /* Very useful to debug dynamic linker problems */
+                               printk ("Sig ILL going...\n");
+                               show_regs (regs);
+#endif
+                               /* fall through */
+                       default:
+                               current->signal |= _S(signr & 0x7f);
+                               current->flags |= PF_SIGNALED;
+                               do_exit(signr);
+                       }
+               }
+               if(restart_syscall)
+                       syscall_restart32(orig_i0, regs, sa);
+               handle_signal32(signr, sa, oldmask, regs, svr4_signal);
+               return 1;
+       }
+       if(restart_syscall &&
+          (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+           regs->u_regs[UREG_I0] == ERESTARTSYS ||
+           regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+               /* replay the system call when we are done */
+               regs->u_regs[UREG_I0] = orig_i0;
+               regs->tpc -= 4;
+               regs->tnpc -= 4;
+       }
+       return 0;
+}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
new file mode 100644 (file)
index 0000000..ffc2715
--- /dev/null
@@ -0,0 +1,322 @@
+/* $Id: systbls.S,v 1.1 1996/12/28 18:39:36 davem Exp $
+ * systbls.S: System call entry point tables for OS compatibility.
+ *            The native Linux system call table lives here also.
+ *
+ * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * Based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+       .data
+       .align  8
+
+       /* First, the 32-bit Linux native syscall table. */
+
+       .globl C_LABEL(sys_call_table32)
+C_LABEL(sys_call_table32):
+/*0*/  .xword C_LABEL(sys_setup), C_LABEL(sys_exit), C_LABEL(sys_fork)
+       .xword C_LABEL(sys_read), C_LABEL(sys_write)
+/*5*/  .xword C_LABEL(sys_open), C_LABEL(sys_close), C_LABEL(sys_wait4)
+       .xword C_LABEL(sys_creat), C_LABEL(sys_link)
+/*10*/  .xword C_LABEL(sys_unlink), C_LABEL(sunos_execv), C_LABEL(sys_chdir)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_mknod)
+/*15*/ .xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sparc_brk)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_lseek)
+/*20*/ .xword C_LABEL(sys_getpid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setuid), C_LABEL(sys_getuid)
+/*25*/ .xword C_LABEL(sys_time), C_LABEL(sys_ptrace), C_LABEL(sys_alarm)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_pause)
+/*30*/ .xword C_LABEL(sys_utime), C_LABEL(sys_stty), C_LABEL(sys_gtty)
+       .xword C_LABEL(sys_access), C_LABEL(sys_nice), C_LABEL(sys_ftime)
+       .xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+       .xword C_LABEL(sys_pipe), C_LABEL(sys_times), C_LABEL(sys_profil)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setgid), C_LABEL(sys_getgid)
+       .xword C_LABEL(sys_signal), C_LABEL(sys_geteuid)
+/*50*/ .xword C_LABEL(sys_getegid), C_LABEL(sys_acct), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_ioctl), C_LABEL(sys_reboot)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+       .xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+       .xword C_LABEL(sys_newfstat), C_LABEL(sys_nis_syscall), C_LABEL(sys_getpagesize)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_vfork), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mmap), C_LABEL(sys_nis_syscall), C_LABEL(sys_munmap)
+       .xword C_LABEL(sys_mprotect), C_LABEL(sys_nis_syscall), C_LABEL(sys_vhangup)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getgroups)
+       .xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_swapon)
+       .xword C_LABEL(sys_getitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_sethostname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_dup2), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_fcntl), C_LABEL(sys_select), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*100*/        .xword C_LABEL(sys_getpriority), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_readv)
+       .xword C_LABEL(sys_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+       .xword C_LABEL(sys_fchmod), C_LABEL(sys_nis_syscall), C_LABEL(sys_setreuid)
+       .xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+       .xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getrlimit)
+       .xword C_LABEL(sys_setrlimit), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*150*/        .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+       .xword C_LABEL(sys_umount), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setdomainname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_quotactl), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mount), C_LABEL(sys_ustat), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
+       .xword C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
+       .xword C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
+       .xword C_LABEL(sys_lock), C_LABEL(sys_mpx), C_LABEL(sys_ulimit)
+       .xword C_LABEL(sys_getppid), C_LABEL(sparc_sigaction), C_LABEL(sys_sgetmask)
+/*200*/        .xword C_LABEL(sys_ssetmask), C_LABEL(sys_sigsuspend), C_LABEL(sys_newlstat)
+       .xword C_LABEL(sys_uselib), C_LABEL(old_readdir), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_socketcall), C_LABEL(sys_syslog), C_LABEL(sys_olduname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_idle), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_waitpid), C_LABEL(sys_swapoff), C_LABEL(sys_sysinfo)
+       .xword C_LABEL(sys_ipc), C_LABEL(sys_sigreturn), C_LABEL(sys_clone)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_adjtimex), C_LABEL(sys_sigprocmask)
+       .xword C_LABEL(sys_create_module), C_LABEL(sys_delete_module)
+       .xword C_LABEL(sys_get_kernel_syms), C_LABEL(sys_getpgid), C_LABEL(sys_bdflush)
+       .xword C_LABEL(sys_sysfs), C_LABEL(sys_nis_syscall), C_LABEL(sys_setfsuid)
+       .xword C_LABEL(sys_setfsgid), C_LABEL(sys_llseek), C_LABEL(sys_time)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_stime), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_llseek)
+       /* "We are the Knights of the Forest of Ni!!" */
+       .xword C_LABEL(sys_mlock), C_LABEL(sys_munlock), C_LABEL(sys_mlockall)
+       .xword C_LABEL(sys_munlockall), C_LABEL(sys_sched_setparam)
+       .xword C_LABEL(sys_sched_getparam), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_sched_get_priority_max), C_LABEL(sys_sched_get_priority_min)
+       .xword C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep)
+/*250*/        .xword C_LABEL(sys_mremap)
+       .xword C_LABEL(sys_sysctl)
+       .xword C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall)
+
+       /* Now the 64-bit native Linux syscall table. */
+
+       .globl C_LABEL(sys_call_table64)
+C_LABEL(sys_call_table64):
+/*0*/  .xword C_LABEL(sys_setup), C_LABEL(sys_exit), C_LABEL(sys_fork)
+       .xword C_LABEL(sys_read), C_LABEL(sys_write)
+/*5*/  .xword C_LABEL(sys_open), C_LABEL(sys_close), C_LABEL(sys_wait4)
+       .xword C_LABEL(sys_creat), C_LABEL(sys_link)
+/*10*/  .xword C_LABEL(sys_unlink), C_LABEL(sunos_execv), C_LABEL(sys_chdir)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_mknod)
+/*15*/ .xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sparc_brk)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_lseek)
+/*20*/ .xword C_LABEL(sys_getpid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setuid), C_LABEL(sys_getuid)
+/*25*/ .xword C_LABEL(sys_time), C_LABEL(sys_ptrace), C_LABEL(sys_alarm)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_pause)
+/*30*/ .xword C_LABEL(sys_utime), C_LABEL(sys_stty), C_LABEL(sys_gtty)
+       .xword C_LABEL(sys_access), C_LABEL(sys_nice), C_LABEL(sys_ftime)
+       .xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+       .xword C_LABEL(sys_pipe), C_LABEL(sys_times), C_LABEL(sys_profil)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setgid), C_LABEL(sys_getgid)
+       .xword C_LABEL(sys_signal), C_LABEL(sys_geteuid)
+/*50*/ .xword C_LABEL(sys_getegid), C_LABEL(sys_acct), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_ioctl), C_LABEL(sys_reboot)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+       .xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+       .xword C_LABEL(sys_newfstat), C_LABEL(sys_nis_syscall), C_LABEL(sys_getpagesize)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_vfork), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mmap), C_LABEL(sys_nis_syscall), C_LABEL(sys_munmap)
+       .xword C_LABEL(sys_mprotect), C_LABEL(sys_nis_syscall), C_LABEL(sys_vhangup)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getgroups)
+       .xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_swapon)
+       .xword C_LABEL(sys_getitimer), C_LABEL(sys_nis_syscall), C_LABEL(sys_sethostname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_dup2), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_fcntl), C_LABEL(sys_select), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*100*/        .xword C_LABEL(sys_getpriority), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_readv)
+       .xword C_LABEL(sys_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+       .xword C_LABEL(sys_fchmod), C_LABEL(sys_nis_syscall), C_LABEL(sys_setreuid)
+       .xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+       .xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall), C_LABEL(sys_getrlimit)
+       .xword C_LABEL(sys_setrlimit), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+/*150*/        .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+       .xword C_LABEL(sys_umount), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_setdomainname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_quotactl), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_mount), C_LABEL(sys_ustat), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_getdents), C_LABEL(sys_setsid)
+       .xword C_LABEL(sys_fchdir), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_sigpending), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_setpgid), C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_newuname), C_LABEL(sys_init_module)
+       .xword C_LABEL(sys_personality), C_LABEL(sys_prof), C_LABEL(sys_break)
+       .xword C_LABEL(sys_lock), C_LABEL(sys_mpx), C_LABEL(sys_ulimit)
+       .xword C_LABEL(sys_getppid), C_LABEL(sparc_sigaction), C_LABEL(sys_sgetmask)
+/*200*/        .xword C_LABEL(sys_ssetmask), C_LABEL(sys_sigsuspend), C_LABEL(sys_newlstat)
+       .xword C_LABEL(sys_uselib), C_LABEL(old_readdir), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_socketcall), C_LABEL(sys_syslog), C_LABEL(sys_olduname)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_idle), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_waitpid), C_LABEL(sys_swapoff), C_LABEL(sys_sysinfo)
+       .xword C_LABEL(sys_ipc), C_LABEL(sys_sigreturn), C_LABEL(sys_clone)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_adjtimex), C_LABEL(sys_sigprocmask)
+       .xword C_LABEL(sys_create_module), C_LABEL(sys_delete_module)
+       .xword C_LABEL(sys_get_kernel_syms), C_LABEL(sys_getpgid), C_LABEL(sys_bdflush)
+       .xword C_LABEL(sys_sysfs), C_LABEL(sys_nis_syscall), C_LABEL(sys_setfsuid)
+       .xword C_LABEL(sys_setfsgid), C_LABEL(sys_llseek), C_LABEL(sys_time)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_stime), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_llseek)
+       /* "We are the Knights of the Forest of Ni!!" */
+       .xword C_LABEL(sys_mlock), C_LABEL(sys_munlock), C_LABEL(sys_mlockall)
+       .xword C_LABEL(sys_munlockall), C_LABEL(sys_sched_setparam)
+       .xword C_LABEL(sys_sched_getparam), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_nis_syscall), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_sched_get_priority_max), C_LABEL(sys_sched_get_priority_min)
+       .xword C_LABEL(sys_sched_rr_get_interval), C_LABEL(sys_nanosleep)
+/*250*/        .xword C_LABEL(sys_mremap)
+       .xword C_LABEL(sys_sysctl)
+       .xword C_LABEL(sys_getsid), C_LABEL(sys_fdatasync), C_LABEL(sys_nis_syscall)
+       .xword C_LABEL(sys_aplib), C_LABEL(sys_nis_syscall)
+
+       /* Now the 32-bit SunOS syscall table. */
+
+       .align 4
+       .globl C_LABEL(sunos_sys_table)
+C_LABEL(sunos_sys_table):
+/*0*/  .xword C_LABEL(sunos_indir), C_LABEL(sys_exit), C_LABEL(sys_fork)
+       .xword C_LABEL(sunos_read), C_LABEL(sunos_write), C_LABEL(sunos_open)
+       .xword C_LABEL(sys_close), C_LABEL(sunos_wait4), C_LABEL(sys_creat)
+       .xword C_LABEL(sys_link), C_LABEL(sys_unlink), C_LABEL(sunos_execv)
+       .xword C_LABEL(sys_chdir), C_LABEL(sunos_nosys), C_LABEL(sys_mknod)
+       .xword C_LABEL(sys_chmod), C_LABEL(sys_chown), C_LABEL(sunos_brk)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_lseek), C_LABEL(sunos_getpid)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_getuid), C_LABEL(sunos_nosys), C_LABEL(sys_ptrace)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sys_access), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sys_sync), C_LABEL(sys_kill), C_LABEL(sys_newstat)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_newlstat), C_LABEL(sys_dup)
+       .xword C_LABEL(sys_pipe), C_LABEL(sunos_nosys), C_LABEL(sys_profil)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_getgid)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*50*/ .xword C_LABEL(sunos_nosys), C_LABEL(sys_acct), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_mctl), C_LABEL(sunos_ioctl), C_LABEL(sys_reboot)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_symlink), C_LABEL(sys_readlink)
+       .xword C_LABEL(sys_execve), C_LABEL(sys_umask), C_LABEL(sys_chroot)
+       .xword C_LABEL(sys_newfstat), C_LABEL(sunos_nosys), C_LABEL(sys_getpagesize)
+       .xword C_LABEL(sys_msync), C_LABEL(sys_vfork), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_sbrk), C_LABEL(sunos_sstk)
+       .xword C_LABEL(sunos_mmap), C_LABEL(sunos_vadvise), C_LABEL(sys_munmap)
+       .xword C_LABEL(sys_mprotect), C_LABEL(sunos_madvise), C_LABEL(sys_vhangup)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_mincore), C_LABEL(sys_getgroups)
+       .xword C_LABEL(sys_setgroups), C_LABEL(sys_getpgrp), C_LABEL(sunos_setpgrp)
+       .xword C_LABEL(sys_setitimer), C_LABEL(sunos_nosys), C_LABEL(sys_swapon)
+       .xword C_LABEL(sys_getitimer), C_LABEL(sys_gethostname), C_LABEL(sys_sethostname)
+       .xword C_LABEL(sunos_getdtablesize), C_LABEL(sys_dup2), C_LABEL(sunos_nop)
+       .xword C_LABEL(sys_fcntl), C_LABEL(sunos_select), C_LABEL(sunos_nop)
+       .xword C_LABEL(sys_fsync), C_LABEL(sys_setpriority), C_LABEL(sys_socket)
+       .xword C_LABEL(sys_connect), C_LABEL(sunos_accept)
+/*100*/        .xword C_LABEL(sys_getpriority), C_LABEL(sunos_send), C_LABEL(sunos_recv)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_bind), C_LABEL(sunos_setsockopt)
+       .xword C_LABEL(sys_listen), C_LABEL(sunos_nosys), C_LABEL(sunos_sigaction)
+       .xword C_LABEL(sunos_sigblock), C_LABEL(sunos_sigsetmask), C_LABEL(sys_sigpause)
+       .xword C_LABEL(sys_sigstack), C_LABEL(sys_recvmsg), C_LABEL(sys_sendmsg)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_gettimeofday), C_LABEL(sys_getrusage)
+       .xword C_LABEL(sunos_getsockopt), C_LABEL(sunos_nosys), C_LABEL(sunos_readv)
+       .xword C_LABEL(sunos_writev), C_LABEL(sys_settimeofday), C_LABEL(sys_fchown)
+       .xword C_LABEL(sys_fchmod), C_LABEL(sys_recvfrom), C_LABEL(sys_setreuid)
+       .xword C_LABEL(sys_setregid), C_LABEL(sys_rename), C_LABEL(sys_truncate)
+       .xword C_LABEL(sys_ftruncate), C_LABEL(sys_flock), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sys_sendto), C_LABEL(sys_shutdown), C_LABEL(sys_socketpair)
+       .xword C_LABEL(sys_mkdir), C_LABEL(sys_rmdir), C_LABEL(sys_utimes)
+       .xword C_LABEL(sys_sigreturn), C_LABEL(sunos_nosys), C_LABEL(sys_getpeername)
+       .xword C_LABEL(sunos_gethostid), C_LABEL(sunos_nosys), C_LABEL(sys_getrlimit)
+       .xword C_LABEL(sys_setrlimit), C_LABEL(sunos_killpg), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*150*/        .xword C_LABEL(sys_getsockname), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_poll), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_getdirentries), C_LABEL(sys_statfs), C_LABEL(sys_fstatfs)
+       .xword C_LABEL(sys_umount), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_getdomainname), C_LABEL(sys_setdomainname)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_quotactl), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_mount), C_LABEL(sys_ustat), C_LABEL(sunos_semsys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_shmsys), C_LABEL(sunos_audit)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_getdents), C_LABEL(sys_setsid)
+       .xword C_LABEL(sys_fchdir), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sys_sigpending), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sys_setpgid), C_LABEL(sunos_pathconf), C_LABEL(sunos_fpathconf)
+       .xword C_LABEL(sunos_sysconf), C_LABEL(sunos_uname), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*200*/        .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+/*250*/        .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sunos_nosys)
+       .xword C_LABEL(sunos_nosys), C_LABEL(sunos_nosys), C_LABEL(sys_aplib)
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
new file mode 100644 (file)
index 0000000..72b712c
--- /dev/null
@@ -0,0 +1,254 @@
+/* $Id: ttable.S,v 1.3 1996/12/28 18:39:43 davem Exp $
+ * ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+       .globl  start, _start
+       .globl  sparc64_ttable_tl0, sparc64_ttable_tl1
+_start:
+start:
+sparc64_ttable_tl0:
+tl0_resv000:   BOOT_KERNEL BTRAP(0x1) BTRAP(0x2) BTRAP(0x3)
+tl0_resv004:   BTRAP(0x4)  BTRAP(0x5) BTRAP(0x6) BTRAP(0x7)
+tl0_iax:       TRAP(do_iax)
+tl0_resv009:   BTRAP(0x9)
+tl0_iae:       TRAP(do_iae)
+tl0_resv00b:   BTRAP(0xb) BTRAP(0xc) BTRAP(0xd) BTRAP(0xe) BTRAP(0xf)
+tl0_ill:       TRAP(do_ill)
+tl0_privop:    TRAP(do_privop)
+tl0_resv012:   BTRAP(0x12) BTRAP(0x13) BTRAP(0x14) BTRAP(0x15) BTRAP(0x16) BTRAP(0x17)
+tl0_resv018:   BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d)
+tl0_resv01e:   BTRAP(0x1e) BTRAP(0x1f)
+tl0_fpdis:     TRAP(do_fpdis)
+tl0_fpieee:    TRAP(do_fpieee)
+tl0_fpother:   TRAP(do_fpother)
+tl0_tof:       TRAP(do_tof)
+tl0_cwin:      CLEAN_WINDOW
+tl0_div0:      TRAP(do_div0)
+tl0_resv029:   BTRAP(0x29) BTRAP(0x2a) BTRAP(0x2b) BTRAP(0x2c) BTRAP(0x2d) BTRAP(0x2e)
+tl0_resv02f:   BTRAP(0x2f)
+tl0_dax:       TRAP(do_dax)
+tl0_resv031:   BTRAP(0x31)
+tl0_dae:       TRAP(do_dae)
+tl0_resv033:   BTRAP(0x33)
+tl0_mna:       TRAP(do_mna)
+tl0_lddfmna:   TRAP(do_lddfmna)
+tl0_stdfmna:   TRAP(do_stdfmna)
+tl0_privact:   TRAP(do_privact)
+tl0_resv038:   BTRAP(0x38) BTRAP(0x39) BTRAP(0x3a) BTRAP(0x3b) BTRAP(0x3c) BTRAP(0x3d)
+tl0_resv03e:   BTRAP(0x3e) BTRAP(0x3f) BTRAP(0x40)
+tl0_irq1:      TRAP_IRQ(do_irq, 1)  TRAP_IRQ(do_irq, 2)  TRAP_IRQ(do_irq, 3)
+tl0_irq4:      TRAP_IRQ(do_irq, 4)  TRAP_IRQ(do_irq, 5)  TRAP_IRQ(do_irq, 6)
+tl0_irq7:      TRAP_IRQ(do_irq, 7)  TRAP_IRQ(do_irq, 8)  TRAP_IRQ(do_irq, 9)
+tl0_irq10:     TRAP_IRQ(do_irq, 10) TRAP_IRQ(do_irq, 11) TRAP_IRQ(do_irq, 12)
+tl0_irq13:     TRAP_IRQ(do_irq, 13) TRAP_IRQ(do_irq, 14) TRAP_IRQ(do_irq, 15)
+tl0_resv050:   BTRAP(0x50) BTRAP(0x51) BTRAP(0x52) BTRAP(0x53) BTRAP(0x54) BTRAP(0x55)
+tl0_resv056:   BTRAP(0x56) BTRAP(0x57) BTRAP(0x58) BTRAP(0x59) BTRAP(0x5a) BTRAP(0x5b)
+tl0_resv05c:   BTRAP(0x5c) BTRAP(0x5d) BTRAP(0x5e) BTRAP(0x5f)
+tl0_ivec:      TRAP(do_ivec)
+tl0_paw:       TRAP(do_paw)
+tl0_vaw:       TRAP(do_vaw)
+tl0_cee:       TRAP(do_cee)
+tl0_iamiss:
+#include       "itlb_miss.S"
+tl0_damiss:
+#include       "dtlb_miss.S"
+tl0_daprot:
+#include       "dtlb_prot.S"
+tl0_resv070:   BTRAP(0x70) BTRAP(0x71) BTRAP(0x72) BTRAP(0x73) BTRAP(0x74) BTRAP(0x75)
+tl0_resv076:   BTRAP(0x76) BTRAP(0x77) BTRAP(0x78) BTRAP(0x79) BTRAP(0x7a) BTRAP(0x7b)
+tl0_resv07c:   BTRAP(0x7c) BTRAP(0x7d) BTRAP(0x7e) BTRAP(0x7f)
+tl0_s0n:       SPILL_0_NORMAL
+tl0_s1n:       SPILL_1_NORMAL
+tl0_s2n:       SPILL_2_NORMAL
+tl0_s3n:       SPILL_3_NORMAL
+tl0_s4n:       SPILL_4_NORMAL
+tl0_s5n:       SPILL_5_NORMAL
+tl0_s6n:       SPILL_6_NORMAL
+tl0_s7n:       SPILL_7_NORMAL
+tl0_s0o:       SPILL_0_OTHER
+tl0_s1o:       SPILL_1_OTHER
+tl0_s2o:       SPILL_2_OTHER
+tl0_s3o:       SPILL_3_OTHER
+tl0_s4o:       SPILL_4_OTHER
+tl0_s5o:       SPILL_5_OTHER
+tl0_s6o:       SPILL_6_OTHER
+tl0_s7o:       SPILL_7_OTHER
+tl0_f0n:       FILL_0_NORMAL
+tl0_f1n:       FILL_1_NORMAL
+tl0_f2n:       FILL_2_NORMAL
+tl0_f3n:       FILL_3_NORMAL
+tl0_f4n:       FILL_4_NORMAL
+tl0_f5n:       FILL_5_NORMAL
+tl0_f6n:       FILL_6_NORMAL
+tl0_f7n:       FILL_7_NORMAL
+tl0_f0o:       FILL_0_OTHER
+tl0_f1o:       FILL_1_OTHER
+tl0_f2o:       FILL_2_OTHER
+tl0_f3o:       FILL_3_OTHER
+tl0_f4o:       FILL_4_OTHER
+tl0_f5o:       FILL_5_OTHER
+tl0_f6o:       FILL_6_OTHER
+tl0_f7o:       FILL_7_OTHER
+tl0_sunos:     SUNOS_SYSCALL_TRAP
+tl0_bkpt:      BREAKPOINT_TRAP
+tl0_resv102:   BTRAP(0x102)
+tl0_flushw:    FLUSH_WINDOW_TRAP
+tl0_resv103:   BTRAP(0x103) BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107)
+tl0_solaris:   SOLARIS_SYSCALL_TRAP
+tl0_netbsd:    NETBSD_SYSCALL_TRAP
+tl0_resv10a:   BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e)
+tl0_resv10f:   BTRAP(0x10f)
+tl0_linux32:   LINUX_32BIT_SYSCALL_TRAP
+tl0_linux64:   LINUX_64BIT_SYSCALL_TRAP
+tl0_resv112:   BTRAP(0x112) BTRAP(0x113) BTRAP(0x114) BTRAP(0x115) BTRAP(0x116)
+tl0_resv117:   BTRAP(0x117) BTRAP(0x118) BTRAP(0x119) BTRAP(0x11a) BTRAP(0x11b)
+tl0_resv11c:   BTRAP(0x11c) BTRAP(0x11d) BTRAP(0x11e) BTRAP(0x11f)
+tl0_getcc:     GETCC_TRAP
+tl0_setcc:     SETCC_TRAP
+tl0_resv122:   BTRAP(0x122) BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126)
+tl0_solindir:  INDIRECT_SOLARIS_SYSCALL(156)
+tl0_resv128:   BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c)
+tl0_resv12d:   BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131)
+tl0_resv132:   BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136)
+tl0_resv137:   BTRAP(0x137) BTRAP(0x138) BTRAP(0x139) BTRAP(0x13a) BTRAP(0x13b)
+tl0_resv13c:   BTRAP(0x13c) BTRAP(0x13d) BTRAP(0x13e) BTRAP(0x13f) BTRAP(0x140)
+tl0_resv141:   BTRAP(0x141) BTRAP(0x142) BTRAP(0x143) BTRAP(0x144) BTRAP(0x145)
+tl0_resv146:   BTRAP(0x146) BTRAP(0x147) BTRAP(0x148) BTRAP(0x149) BTRAP(0x14a)
+tl0_resv14b:   BTRAP(0x14b) BTRAP(0x14c) BTRAP(0x14d) BTRAP(0x14e) BTRAP(0x14f)
+tl0_resv150:   BTRAP(0x150) BTRAP(0x151) BTRAP(0x152) BTRAP(0x153) BTRAP(0x154)
+tl0_resv155:   BTRAP(0x155) BTRAP(0x156) BTRAP(0x157) BTRAP(0x158) BTRAP(0x159)
+tl0_resv15a:   BTRAP(0x15a) BTRAP(0x15b) BTRAP(0x15c) BTRAP(0x15d) BTRAP(0x15e)
+tl0_resv15f:   BTRAP(0x15f) BTRAP(0x160) BTRAP(0x161) BTRAP(0x162) BTRAP(0x163)
+tl0_resv164:   BTRAP(0x164) BTRAP(0x165) BTRAP(0x166) BTRAP(0x167) BTRAP(0x168)
+tl0_resv169:   BTRAP(0x169) BTRAP(0x16a) BTRAP(0x16b) BTRAP(0x16c) BTRAP(0x16d)
+tl0_resv16e:   BTRAP(0x16e) BTRAP(0x16f) BTRAP(0x170) BTRAP(0x171) BTRAP(0x172)
+tl0_resv173:   BTRAP(0x173) BTRAP(0x174) BTRAP(0x175) BTRAP(0x176) BTRAP(0x177)
+tl0_resv178:   BTRAP(0x178) BTRAP(0x179) BTRAP(0x17a) BTRAP(0x17b) BTRAP(0x17c)
+tl0_resv17d:   BTRAP(0x17d) BTRAP(0x17e) BTRAP(0x17f)
+
+sparc64_ttable_tl1:
+tl1_resv000:   BOOT_KERNEL    BTRAPTL1(0x1) BTRAPTL1(0x2) BTRAPTL1(0x3)
+tl1_resv004:   BTRAPTL1(0x4)  BTRAPTL1(0x5) BTRAPTL1(0x6) BTRAPTL1(0x7)
+tl1_iax:       TRAP(do_iax_tl1)
+tl1_resv009:   BTRAPTL1(0x9)
+tl1_iae:       TRAP(do_iae_tl1)
+tl1_resv00b:   BTRAPTL1(0xb) BTRAPTL1(0xc) BTRAPTL1(0xd) BTRAPTL1(0xe) BTRAPTL1(0xf)
+tl1_ill:       TRAP(do_ill_tl1)
+tl1_privop:    BAD_TRAP(0x11)
+tl1_resv012:   BTRAPTL1(0x12) BTRAPTL1(0x13) BTRAPTL1(0x14) BTRAPTL1(0x15)
+tl1_resv016:   BTRAPTL1(0x16) BTRAPTL1(0x17) BTRAPTL1(0x18) BTRAPTL1(0x19)
+tl1_resv01a:   BTRAPTL1(0x1a) BTRAPTL1(0x1b) BTRAPTL1(0x1c) BTRAPTL1(0x1d)
+tl1_resv01e:   BTRAPTL1(0x1e) BTRAPTL1(0x1f)
+tl1_fpdis:     TRAP(do_fpdis_tl1)
+tl1_fpieee:    TRAP(do_fpieee_tl1)
+tl1_fpother:   TRAP(do_fpother_tl1)
+tl1_tof:       TRAP(do_tof_tl1)
+tl1_cwin:      CLEAN_WINDOW
+tl1_div0:      TRAP(do_div0_tl1)
+tl1_resv029:   BTRAPTL1(0x29) BTRAPTL1(0x2a) BTRAPTL1(0x2b) BTRAPTL1(0x2c)
+tl1_resv02d:   BTRAPTL1(0x2d) BTRAPTL1(0x2e) BTRAPTL1(0x2f)
+tl1_dax:       TRAP(do_dax_tl1)
+tl1_resv031:   BTRAPTL1(0x31)
+tl1_dae:       TRAP(do_dae_tl1)
+tl1_resv033:   BTRAPTL1(0x33)
+tl1_mna:       TRAP(do_mna_tl1)
+tl1_lddfmna:   TRAP(do_lddfmna_tl1)
+tl1_stdfmna:   TRAP(do_stdfmna_tl1)
+tl1_privact:   BTRAPTL1(0x37)
+tl1_resv038:   BTRAPTL1(0x38) BTRAPTL1(0x39) BTRAPTL1(0x3a) BTRAPTL1(0x3b)
+tl1_resv03c:   BTRAPTL1(0x3c) BTRAPTL1(0x3d) BTRAPTL1(0x3e) BTRAPTL1(0x3f)
+tl1_resv040:   BTRAPTL1(0x40)
+tl1_irq1:      TRAP_IRQ(do_irq_tl1, 1)  TRAP_IRQ(do_irq_tl1, 2)  TRAP_IRQ(do_irq_tl1, 3)
+tl1_irq4:      TRAP_IRQ(do_irq_tl1, 4)  TRAP_IRQ(do_irq_tl1, 5)  TRAP_IRQ(do_irq_tl1, 6)
+tl1_irq7:      TRAP_IRQ(do_irq_tl1, 7)  TRAP_IRQ(do_irq_tl1, 8)  TRAP_IRQ(do_irq_tl1, 9)
+tl1_irq10:     TRAP_IRQ(do_irq_tl1, 10) TRAP_IRQ(do_irq_tl1, 11)
+tl1_irq12:     TRAP_IRQ(do_irq_tl1, 12) TRAP_IRQ(do_irq_tl1, 13)
+tl1_irq14:     TRAP_IRQ(do_irq_tl1, 14) TRAP_IRQ(do_irq_tl1, 15)
+tl1_resv050:   BTRAPTL1(0x50) BTRAPTL1(0x51) BTRAPTL1(0x52) BTRAPTL1(0x53)
+tl1_resv054:   BTRAPTL1(0x54) BTRAPTL1(0x55) BTRAPTL1(0x56) BTRAPTL1(0x57)
+tl1_resv058:   BTRAPTL1(0x58) BTRAPTL1(0x59) BTRAPTL1(0x5a) BTRAPTL1(0x5b)
+tl1_resv05c:   BTRAPTL1(0x5c) BTRAPTL1(0x5d) BTRAPTL1(0x5e) BTRAPTL1(0x5f)
+tl1_ivec:      TRAP(do_ivec_tl1)
+tl1_paw:       TRAP(do_paw_tl1)
+tl1_vaw:       TRAP(do_vaw_tl1)
+tl1_cee:       TRAP(do_cee_tl1)
+tl1_iamiss:
+#include       "itlb_miss.S"
+tl1_damiss:
+#include       "dtlb_miss.S"
+tl1_daprot:
+#include       "dtlb_prot.S"
+tl1_resv070:   BTRAPTL1(0x70) BTRAPTL1(0x71) BTRAPTL1(0x72) BTRAPTL1(0x73)
+tl1_resv074:   BTRAPTL1(0x74) BTRAPTL1(0x75) BTRAPTL1(0x76) BTRAPTL1(0x77)
+tl1_resv078:   BTRAPTL1(0x78) BTRAPTL1(0x79) BTRAPTL1(0x7a) BTRAPTL1(0x7b)
+tl1_resv07c:   BTRAPTL1(0x7c) BTRAPTL1(0x7d) BTRAPTL1(0x7e) BTRAPTL1(0x7f)
+tl1_s0n:       SPILL_0_NORMAL_TL1
+tl1_s1n:       SPILL_1_NORMAL_TL1
+tl1_s2n:       SPILL_2_NORMAL_TL1
+tl1_s3n:       SPILL_3_NORMAL_TL1
+tl1_s4n:       SPILL_4_NORMAL_TL1
+tl1_s5n:       SPILL_5_NORMAL_TL1
+tl1_s6n:       SPILL_6_NORMAL_TL1
+tl1_s7n:       SPILL_7_NORMAL_TL1
+tl1_s0o:       SPILL_0_OTHER_TL1
+tl1_s1o:       SPILL_1_OTHER_TL1
+tl1_s2o:       SPILL_2_OTHER_TL1
+tl1_s3o:       SPILL_3_OTHER_TL1
+tl1_s4o:       SPILL_4_OTHER_TL1
+tl1_s5o:       SPILL_5_OTHER_TL1
+tl1_s6o:       SPILL_6_OTHER_TL1
+tl1_s7o:       SPILL_7_OTHER_TL1
+tl1_f0n:       FILL_0_NORMAL_TL1
+tl1_f1n:       FILL_1_NORMAL_TL1
+tl1_f2n:       FILL_2_NORMAL_TL1
+tl1_f3n:       FILL_3_NORMAL_TL1
+tl1_f4n:       FILL_4_NORMAL_TL1
+tl1_f5n:       FILL_5_NORMAL_TL1
+tl1_f6n:       FILL_6_NORMAL_TL1
+tl1_f7n:       FILL_7_NORMAL_TL1
+tl1_f0o:       FILL_0_OTHER_TL1
+tl1_f1o:       FILL_1_OTHER_TL1
+tl1_f2o:       FILL_2_OTHER_TL1
+tl1_f3o:       FILL_3_OTHER_TL1
+tl1_f4o:       FILL_4_OTHER_TL1
+tl1_f5o:       FILL_5_OTHER_TL1
+tl1_f6o:       FILL_6_OTHER_TL1
+tl1_f7o:       FILL_7_OTHER_TL1
+tl1_sunos:     BTRAPTL1(0x100)
+tl1_bkpt:      BREAKPOINT_TRAP
+tl1_resv102:   BTRAPTL1(0x102)
+tl1_flushw:    FLUSH_WINDOW_TRAP
+tl1_resv103:   BTRAPTL1(0x103) BTRAPTL1(0x104) BTRAPTL1(0x105) BTRAPTL1(0x106)
+tl1_resv107:   BTRAPTL1(0x107) BTRAPTL1(0x108) BTRAPTL1(0x109) BTRAPTL1(0x10a)
+tl1_resv10b:   BTRAPTL1(0x10b) BTRAPTL1(0x10c) BTRAPTL1(0x10d) BTRAPTL1(0x10e)
+tl1_resv10f:   BTRAPTL1(0x10f) BTRAPTL1(0x110) BTRAPTL1(0x111) BTRAPTL1(0x112)
+tl1_resv113:   BTRAPTL1(0x113) BTRAPTL1(0x114) BTRAPTL1(0x115) BTRAPTL1(0x116)
+tl1_resv117:   BTRAPTL1(0x117) BTRAPTL1(0x118) BTRAPTL1(0x119) BTRAPTL1(0x11a)
+tl1_resv11b:   BTRAPTL1(0x11b) BTRAPTL1(0x11c) BTRAPTL1(0x11d) BTRAPTL1(0x11e)
+tl1_resv11f:   BTRAPTL1(0x11f) BTRAPTL1(0x120) BTRAPTL1(0x121) BTRAPTL1(0x122)
+tl1_resv123:   BTRAPTL1(0x123) BTRAPTL1(0x124) BTRAPTL1(0x125) BTRAPTL1(0x126)
+tl1_solindir:  BTRAPTL1(0x127) BTRAPTL1(0x128) BTRAPTL1(0x129) BTRAPTL1(0x12a)
+tl1_resv12b:   BTRAPTL1(0x12b) BTRAPTL1(0x12c) BTRAPTL1(0x12d) BTRAPTL1(0x12e)
+tl1_resv12f:   BTRAPTL1(0x12f) BTRAPTL1(0x130) BTRAPTL1(0x131) BTRAPTL1(0x132)
+tl1_resv133:   BTRAPTL1(0x133) BTRAPTL1(0x134) BTRAPTL1(0x135) BTRAPTL1(0x136)
+tl1_resv137:   BTRAPTL1(0x137) BTRAPTL1(0x138) BTRAPTL1(0x139) BTRAPTL1(0x13a)
+tl1_resv13b:   BTRAPTL1(0x13b) BTRAPTL1(0x13c) BTRAPTL1(0x13d) BTRAPTL1(0x13e)
+tl1_resv13f:   BTRAPTL1(0x13f) BTRAPTL1(0x140) BTRAPTL1(0x141) BTRAPTL1(0x142)
+tl1_resv143:   BTRAPTL1(0x143) BTRAPTL1(0x144) BTRAPTL1(0x145) BTRAPTL1(0x146)
+tl1_resv147:   BTRAPTL1(0x147) BTRAPTL1(0x148) BTRAPTL1(0x149) BTRAPTL1(0x14a)
+tl1_resv14b:   BTRAPTL1(0x14b) BTRAPTL1(0x14c) BTRAPTL1(0x14d) BTRAPTL1(0x14e)
+tl1_resv14f:   BTRAPTL1(0x14f) BTRAPTL1(0x150) BTRAPTL1(0x151) BTRAPTL1(0x152)
+tl1_resv153:   BTRAPTL1(0x153) BTRAPTL1(0x154) BTRAPTL1(0x155) BTRAPTL1(0x156)
+tl1_resv157:   BTRAPTL1(0x157) BTRAPTL1(0x158) BTRAPTL1(0x159) BTRAPTL1(0x15a)
+tl1_resv15b:   BTRAPTL1(0x15b) BTRAPTL1(0x15c) BTRAPTL1(0x15d) BTRAPTL1(0x15e)
+tl1_resv15f:   BTRAPTL1(0x15f) BTRAPTL1(0x160) BTRAPTL1(0x161) BTRAPTL1(0x162)
+tl1_resv163:   BTRAPTL1(0x163) BTRAPTL1(0x164) BTRAPTL1(0x165) BTRAPTL1(0x166)
+tl1_resv167:   BTRAPTL1(0x167) BTRAPTL1(0x168) BTRAPTL1(0x169) BTRAPTL1(0x16a)
+tl1_resv16b:   BTRAPTL1(0x16b) BTRAPTL1(0x16c) BTRAPTL1(0x16d) BTRAPTL1(0x16e)
+tl1_resv16f:   BTRAPTL1(0x16f) BTRAPTL1(0x170) BTRAPTL1(0x171) BTRAPTL1(0x172)
+tl1_resv173:   BTRAPTL1(0x173) BTRAPTL1(0x174) BTRAPTL1(0x175) BTRAPTL1(0x176)
+tl1_resv177:   BTRAPTL1(0x177) BTRAPTL1(0x178) BTRAPTL1(0x179) BTRAPTL1(0x17a)
+tl1_resv17b:   BTRAPTL1(0x17b) BTRAPTL1(0x17c) BTRAPTL1(0x17d) BTRAPTL1(0x17e)
+tl1_resv17f:   BTRAPTL1(0x17f)
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
new file mode 100644 (file)
index 0000000..1b92ac1
--- /dev/null
@@ -0,0 +1,21 @@
+# $Id: Makefile,v 1.1 1996/12/27 17:28:35 davem Exp $
+# Makefile for Sparc library files..
+#
+
+CFLAGS := $(CFLAGS) -ansi
+
+OBJS  = memset.o blockops.o
+
+lib.a: $(OBJS)
+       $(AR) rcs lib.a $(OBJS)
+       sync
+
+blockops.o: blockops.S
+       $(CC) -ansi -c -o blockops.o blockops.S
+
+memset.o: memset.S
+       $(CC) -D__ASSEMBLY__ -ansi -c -o memset.o memset.S
+
+dep:
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S
new file mode 100644 (file)
index 0000000..540b6ba
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id: blockops.S,v 1.1 1996/12/22 07:42:15 davem Exp $
+ * arch/sparc64/lib/blockops.S: UltraSparc block zero optimized routines.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/asi.h>
+
+       /* Zero out 64 bytes of memory at (buf + offset). */
+#define BLAST_BLOCK(buf, offset)                               \
+       stx             %g0, [buf + offset + 0x38];             \
+       stx             %g0, [buf + offset + 0x30];             \
+       stx             %g0, [buf + offset + 0x28];             \
+       stx             %g0, [buf + offset + 0x20];             \
+       stx             %g0, [buf + offset + 0x18];             \
+       stx             %g0, [buf + offset + 0x10];             \
+       stx             %g0, [buf + offset + 0x08];             \
+       stx             %g0, [buf + offset + 0x00];
+
+       /* Copy 32 bytes of memory at (src + offset) to
+        * (dst + offset).
+        */
+#define MIRROR_BLOCK(dst, src, offset, t0, t1, t2, t3)         \
+       ldx             [src + offset + 0x18], t0;              \
+       ldx             [src + offset + 0x10], t1;              \
+       ldx             [src + offset + 0x08], t2;              \
+       ldx             [src + offset + 0x00], t3;              \
+       stx             t0, [dst + offset + 0x18];              \
+       stx             t1, [dst + offset + 0x10];              \
+       stx             t2, [dst + offset + 0x08];              \
+       stx             t3, [dst + offset + 0x00];
+
+       .text
+       .align  4
+
+       .globl  C_LABEL(bzero_2page), C_LABEL(bzero_1page)
+C_LABEL(bzero_2page):
+       /* %o0 = buf */
+       or              %o0, %g0, %o1
+       or              %g0, 0x40, %g2
+1:
+       BLAST_BLOCK(%o0, 0x00)
+       BLAST_BLOCK(%o0, 0x40)
+       BLAST_BLOCK(%o0, 0x80)
+       BLAST_BLOCK(%o0, 0xc0)
+       subcc           %g2, 1, %g2
+       bne,pt          %icc, 1b
+        add            %o0, 0x100, %o0
+
+       retl
+        mov            %o1, %o0
+
+C_LABEL(bzero_1page):
+       /* %o0 = buf */
+       or              %o0, %g0, %o1
+       or              %g0, 0x20, %g2
+1:
+       BLAST_BLOCK(%o0, 0x00)
+       BLAST_BLOCK(%o0, 0x40)
+       BLAST_BLOCK(%o0, 0x80)
+       BLAST_BLOCK(%o0, 0xc0)
+       subcc           %g2, 1, %g2
+       bne,pt          %icc, 1b
+        add            %o0, 0x100, %o0
+
+       retl
+        mov            %o1, %o0
+
+       .globl  C_LABEL(__copy_1page)
+C_LABEL(__copy_1page):
+       /* %o0 = dst, %o1 = src */
+       or              %g0, 0x10, %g1
+1:
+       MIRROR_BLOCK(%o0, %o1, 0x00, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0x20, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0x40, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0x60, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0x80, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0xa0, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0xc0, %o2, %o3, %o4, %o5)
+       MIRROR_BLOCK(%o0, %o1, 0xe0, %o2, %o3, %o4, %o5)
+       subcc           %g1, 1, %g1
+       add             %o0, 0x100, %o0
+       bne,pt          %icc, 1b
+        add            %o1, 0x100, %o1
+
+       retl
+        nop
+
diff --git a/arch/sparc64/lib/memset.S b/arch/sparc64/lib/memset.S
new file mode 100644 (file)
index 0000000..69e27d3
--- /dev/null
@@ -0,0 +1,133 @@
+/* $Id: memset.S,v 1.1 1996/12/22 07:42:16 davem Exp $
+ * arch/sparc64/lib/memset.S: UltraSparc optimized memset and bzero code
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <asm/asi.h>
+
+       /* Store 64 bytes at (BASE + OFFSET) using value SOURCE. */
+#define ZERO_BIG_BLOCK(base, offset, source)    \
+       stx     source, [base + offset + 0x00]; \
+       stx     source, [base + offset + 0x08]; \
+       stx     source, [base + offset + 0x10]; \
+       stx     source, [base + offset + 0x18]; \
+       stx     source, [base + offset + 0x20]; \
+       stx     source, [base + offset + 0x28]; \
+       stx     source, [base + offset + 0x30]; \
+       stx     source, [base + offset + 0x38];
+
+#define ZERO_LAST_BLOCKS(base, offset, source) \
+       stx     source, [base - offset - 0x38]; \
+       stx     source, [base - offset - 0x30]; \
+       stx     source, [base - offset - 0x28]; \
+       stx     source, [base - offset - 0x20]; \
+       stx     source, [base - offset - 0x18]; \
+       stx     source, [base - offset - 0x10]; \
+       stx     source, [base - offset - 0x08]; \
+       stx     source, [base - offset - 0x00];
+
+       .text
+       .align 4
+
+       .globl  C_LABEL(__bzero), C_LABEL(__memset), C_LABEL(memset)
+C_LABEL(__memset):
+C_LABEL(memset):
+       and             %o1, 0xff, %g3
+       sll             %g3, 8, %g2
+       or              %g3, %g2, %g3
+       sll             %g3, 16, %g2
+       or              %g3, %g2, %g3
+       sllx            %g3, 32, %g2
+       or              %g3, %g2, %g3
+       b               1f
+        mov            %o2, %o1
+
+3:
+       cmp             %o2, 3
+       be              2f
+        stb            %g3, [%o0]
+
+       cmp             %o2, 2
+       be              2f
+        stb            %g3, [%o0 + 0x01]
+
+       stb             %g3, [%o0 + 0x02]
+2:
+       sub             %o2, 4, %o2
+       add             %o1, %o2, %o1
+       b               4f
+        sub            %o0, %o2, %o0
+
+C_LABEL(__bzero):
+       mov             %g0, %g3
+1:
+       cmp             %o1, 7
+       bleu,pnt        %icc, 7f
+        mov            %o0, %g1
+
+       andcc           %o0, 3, %o2
+       bne,pnt         %icc, 3b
+4:
+        andcc          %o0, 4, %g0
+
+       be,a,pt         %icc, 2f
+        andcc          %o1, 0xffffff80, %o3    ! everything 8 aligned, o1 is len to run
+
+       stw             %g3, [%o0]
+       sub             %o1, 4, %o1
+       add             %o0, 4, %o0
+       andcc           %o1, 0xffffff80, %o3    ! everything 8 aligned, o1 is len to run
+2:
+       be              9f
+        andcc          %o1, 0x78, %o2
+4:
+       ZERO_BIG_BLOCK(%o0, 0x00, %g2)
+       subcc           %o3, 128, %o3
+       ZERO_BIG_BLOCK(%o0, 0x40, %g2)
+       bne,pt          %icc, 4b
+        add            %o0, 128, %o0
+
+       orcc            %o2, %g0, %g0
+9:
+       be,pnt          %icc, 6f
+        andcc          %o1, 7, %o1
+
+       srl             %o2, 1, %o3
+       set             bzero_table + 64, %o4
+       sub             %o4, %o3, %o4
+       jmp             %o4
+        add            %o0, %o2, %o0
+
+bzero_table:
+       ZERO_LAST_BLOCKS(%o0, 0x48, %g2)
+       ZERO_LAST_BLOCKS(%o0, 0x08, %g2)
+
+6:
+       be,pt           %icc, 8f
+        andcc          %o1, 4, %g0
+
+       be,pnt          %icc, 1f
+        andcc          %o1, 2, %g0
+
+       stw             %g3, [%o0]
+       add             %o0, 4, %o0
+1:
+       be,pt           %icc, 1f
+        andcc          %o1, 1, %g0
+
+       sth             %g3, [%o0]
+       add             %o0, 2, %o0
+1:
+       bne,a,pnt       %icc, 8f
+        stb            %g3, [%o0]
+8:
+       retl
+        mov            %g1, %o0
+
+/* Don't care about alignment here. It is highly 
+ * unprobable and at most two traps may happen
+ */
+7:
+       ba,pt           %xcc, 6b
+        orcc           %o1, 0, %g0
diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
new file mode 100644 (file)
index 0000000..c41c7a9
--- /dev/null
@@ -0,0 +1,13 @@
+# $Id: Makefile,v 1.1 1996/12/26 10:24:22 davem Exp $
+# Makefile for the linux Sparc64-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := mm.o
+O_OBJS   := fault.o init.o generic.o asyncd.o extable.o
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/mm/asyncd.c b/arch/sparc64/mm/asyncd.c
new file mode 100644 (file)
index 0000000..4e7de16
--- /dev/null
@@ -0,0 +1,272 @@
+/*  $Id: asyncd.c,v 1.1 1996/12/26 10:24:24 davem Exp $
+ *  The asyncd kernel daemon. This handles paging on behalf of 
+ *  processes that receive page faults due to remote (async) memory
+ *  accesses. 
+ *
+ *  Idea and skeleton code courtesy of David Miller (bless his cotton socks)
+ *
+ *  Implemented by tridge
+ */
+
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/swap.h>
+#include <linux/fs.h>
+#include <linux/config.h>
+#include <linux/interrupt.h>
+
+#include <asm/dma.h>
+#include <asm/system.h> /* for cli()/sti() */
+#include <asm/segment.h> /* for memcpy_to/fromfs */
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
+
+#define DEBUG 0
+
+#define WRITE_LIMIT 100
+#define LOOP_LIMIT 200
+
+static struct {
+       int faults, read, write, success, failure, errors;
+} stats;
+
+/* 
+ * The wait queue for waking up the async daemon:
+ */
+static struct wait_queue * asyncd_wait = NULL;
+
+struct async_job {
+       volatile struct async_job *next;
+       int taskid;
+       struct mm_struct *mm;
+       unsigned long address;
+       int write;
+       void (*callback)(int,unsigned long,int,int);
+};
+
+static volatile struct async_job *async_queue = NULL;
+static volatile struct async_job *async_queue_end = NULL;
+
+static void add_to_async_queue(int taskid,
+                              struct mm_struct *mm,
+                              unsigned long address,
+                              int write,
+                              void (*callback)(int,unsigned long,int,int))
+{
+       struct async_job *a = kmalloc(sizeof(*a),GFP_ATOMIC);
+
+       if (!a) {
+               printk("ERROR: out of memory in asyncd\n");
+               a->callback(taskid,address,write,1);
+               return;
+       }
+
+       if (write)
+               stats.write++;
+       else
+               stats.read++;
+
+       a->next = NULL;
+       a->taskid = taskid;
+       a->mm = mm;
+       a->address = address;
+       a->write = write;
+       a->callback = callback;
+
+       if (!async_queue) {
+               async_queue = a;
+       } else {
+               async_queue_end->next = a;
+       }
+       async_queue_end = a;
+}
+
+
+void async_fault(unsigned long address, int write, int taskid,
+                void (*callback)(int,unsigned long,int,int))
+{
+       struct task_struct *tsk = task[taskid];
+       struct mm_struct *mm = tsk->mm;
+
+       stats.faults++;
+
+#if 0
+       printk("paging in %x for task=%d\n",address,taskid);
+#endif
+
+       add_to_async_queue(taskid, mm, address, write, callback);
+       wake_up(&asyncd_wait);  
+       mark_bh(TQUEUE_BH);
+}
+
+static int fault_in_page(int taskid,
+                        struct vm_area_struct *vma,
+                        unsigned address,int write)
+{
+       static unsigned last_address;
+       static int last_task, loop_counter;
+       struct task_struct *tsk = task[taskid];
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       if (!tsk || !tsk->mm)
+               return 1;
+
+       if (!vma || (write && !(vma->vm_flags & VM_WRITE)))
+         goto bad_area;
+       if (vma->vm_start > address)
+         goto bad_area;
+
+       if (address == last_address && taskid == last_task) {
+               loop_counter++;
+       } else {
+               loop_counter = 0;
+               last_address = address; 
+               last_task = taskid;
+       }
+
+       if (loop_counter == WRITE_LIMIT && !write) {
+               printk("MSC bug? setting write request\n");
+               stats.errors++;
+               write = 1;
+       }
+
+       if (loop_counter == LOOP_LIMIT) {
+               printk("MSC bug? failing request\n");
+               stats.errors++;
+               return 1;
+       }
+
+       pgd = pgd_offset(vma->vm_mm, address);
+       pmd = pmd_alloc(pgd,address);
+       if(!pmd)
+               goto no_memory;
+       pte = pte_alloc(pmd, address);
+       if(!pte)
+               goto no_memory;
+       if(!pte_present(*pte)) {
+               do_no_page(tsk, vma, address, write);
+               goto finish_up;
+       }
+       set_pte(pte, pte_mkyoung(*pte));
+       flush_tlb_page(vma, address);
+       if(!write)
+               goto finish_up;
+       if(pte_write(*pte)) {
+               set_pte(pte, pte_mkdirty(*pte));
+               flush_tlb_page(vma, address);
+               goto finish_up;
+       }
+       do_wp_page(tsk, vma, address, write);
+
+       /* Fall through for do_wp_page */
+finish_up:
+       stats.success++;
+       update_mmu_cache(vma, address, *pte);
+       return 0;
+
+no_memory:
+       stats.failure++;
+       oom(tsk);
+       return 1;
+       
+bad_area:        
+       stats.failure++;
+       tsk->tss.sig_address = address;
+       tsk->tss.sig_desc = SUBSIG_NOMAPPING;
+       send_sig(SIGSEGV, tsk, 1);
+       return 1;
+}
+
+
+/* Note the semaphore operations must be done here, and _not_
+ * in async_fault().
+ */
+static void run_async_queue(void)
+{
+       int ret;
+       unsigned flags;
+
+       while (async_queue) {
+               volatile struct async_job *a;
+               struct mm_struct *mm;
+               struct vm_area_struct *vma;
+
+               save_flags(flags); cli();
+               a = async_queue;
+               async_queue = async_queue->next;
+               restore_flags(flags);
+
+               mm = a->mm;
+
+               down(&mm->mmap_sem);
+               vma = find_vma(mm, a->address);
+               ret = fault_in_page(a->taskid,vma,a->address,a->write);
+#if DEBUG
+               printk("fault_in_page(task=%d addr=%x write=%d) = %d\n",
+                      a->taskid,a->address,a->write,ret);
+#endif
+               a->callback(a->taskid,a->address,a->write,ret);
+               up(&mm->mmap_sem);
+               kfree_s((void *)a,sizeof(*a));
+       }
+}
+
+
+#if CONFIG_AP1000
+static void asyncd_info(void)
+{
+       printk("CID(%d) faults: total=%d  read=%d  write=%d  success=%d fail=%d err=%d\n",
+              mpp_cid(),stats.faults, stats.read, stats.write, stats.success,
+              stats.failure, stats.errors);
+}
+#endif
+
+
+/*
+ * The background async daemon.
+ * Started as a kernel thread from the init process.
+ */
+int asyncd(void *unused)
+{
+       current->session = 1;
+       current->pgrp = 1;
+       sprintf(current->comm, "asyncd");
+       current->blocked = ~0UL; /* block all signals */
+  
+       /* Give asyncd a realtime priority. */
+       current->policy = SCHED_FIFO;
+       current->priority = 32;  /* Fixme --- we need to standardise our
+                                   namings for POSIX.4 realtime scheduling
+                                   priorities.  */
+  
+       printk("Started asyncd\n");
+
+#if CONFIG_AP1000
+       bif_add_debug_key('a',asyncd_info,"stats on asyncd");
+#endif
+
+       while (1) {
+               unsigned flags;
+
+               save_flags(flags); cli();
+
+               while (!async_queue) {
+                       current->signal = 0;
+                       interruptible_sleep_on(&asyncd_wait);
+               }
+
+               restore_flags(flags);
+
+               run_async_queue();
+       }
+}
+
diff --git a/arch/sparc64/mm/extable.c b/arch/sparc64/mm/extable.c
new file mode 100644 (file)
index 0000000..006296f
--- /dev/null
@@ -0,0 +1,70 @@
+/* $Id: extable.c,v 1.1 1996/12/26 10:24:24 davem Exp $
+ * linux/arch/sparc/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static unsigned long
+search_one_table(const struct exception_table_entry *start,
+                const struct exception_table_entry *last,
+                unsigned long value, unsigned long *g2)
+{
+       const struct exception_table_entry *first = start;
+       const struct exception_table_entry *mid;
+       long diff = 0;
+        while (first <= last) {
+               mid = (last - first) / 2 + first;
+               diff = mid->insn - value;
+                if (diff == 0) {
+                       if (!mid->fixup) {
+                               *g2 = 0;
+                               return (mid + 1)->fixup;
+                       } else
+                               return mid->fixup;
+                } else if (diff < 0)
+                        first = mid+1;
+                else
+                        last = mid-1;
+        }
+        if (last->insn < value && !last->fixup && (last + 1)->insn > value) {
+               *g2 = (value - last->insn)/4;
+               return (last + 1)->fixup;
+        }
+        if (first > start && (first-1)->insn < value && !(first-1)->fixup && first->insn < value) {
+               *g2 = (value - (first-1)->insn)/4;
+               return first->fixup;
+        }
+        return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr, unsigned long *g2)
+{
+       unsigned long ret;
+#ifdef CONFIG_MODULES
+       struct module *mp;
+#endif
+
+       /* Search the kernel's table first.  */
+       ret = search_one_table(__start___ex_table,
+                              __stop___ex_table-1, addr, g2);
+       if (ret)
+               return ret;
+
+#ifdef CONFIG_MODULES
+       for (mp = module_list; mp != NULL; mp = mp->next) {
+               if (mp->exceptinfo.start != NULL) {
+                       ret = search_one_table(mp->exceptinfo.start,
+                               mp->exceptinfo.stop-1, addr, g2);
+                       if (ret)
+                               return ret;
+               }
+       }
+#endif
+       return 0;
+}
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
new file mode 100644 (file)
index 0000000..0bcd001
--- /dev/null
@@ -0,0 +1,196 @@
+/* $Id: fault.c,v 1.2 1996/12/26 18:03:04 davem Exp $
+ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
+
+extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+extern int prom_node_root;
+
+/* Nice, simple, prom library does all the sweating for us. ;) */
+unsigned int prom_probe_memory (void)
+{
+       register struct linux_mlist_v0 *mlist;
+       register unsigned int bytes, base_paddr, tally;
+       register int i;
+
+       i = 0;
+       mlist= *prom_meminfo()->v0_available;
+       bytes = tally = mlist->num_bytes;
+       base_paddr = (unsigned int) mlist->start_adr;
+  
+       sp_banks[0].base_addr = base_paddr;
+       sp_banks[0].num_bytes = bytes;
+
+       while (mlist->theres_more != (void *) 0){
+               i++;
+               mlist = mlist->theres_more;
+               bytes = mlist->num_bytes;
+               tally += bytes;
+               if (i >= SPARC_PHYS_BANKS-1) {
+                       printk ("The machine has more banks than "
+                               "this kernel can support\n"
+                               "Increase the SPARC_PHYS_BANKS "
+                               "setting (currently %d)\n",
+                               SPARC_PHYS_BANKS);
+                       i = SPARC_PHYS_BANKS-1;
+                       break;
+               }
+    
+               sp_banks[i].base_addr = (unsigned int) mlist->start_adr;
+               sp_banks[i].num_bytes = mlist->num_bytes;
+       }
+
+       i++;
+       sp_banks[i].base_addr = 0xdeadbeef;
+       sp_banks[i].num_bytes = 0;
+
+       /* Now mask all bank sizes on a page boundary, it is all we can
+        * use anyways.
+        */
+       for(i=0; sp_banks[i].num_bytes != 0; i++)
+               sp_banks[i].num_bytes &= PAGE_MASK;
+
+       return tally;
+}
+
+/* Traverse the memory lists in the prom to see how much physical we
+ * have.
+ */
+unsigned int
+probe_memory(void)
+{
+       unsigned int total;
+
+       total = prom_probe_memory();
+
+       /* Oh man, much nicer, keep the dirt in promlib. */
+       return total;
+}
+
+asmlinkage void do_sparc64_fault(struct pt_regs *regs, int text_fault, int write,
+                                unsigned long address)
+{
+       struct vm_area_struct *vma;
+       struct task_struct *tsk = current;
+       struct mm_struct *mm = tsk->mm;
+       unsigned int fixup;
+       unsigned long g2;
+       int from_user = !(regs->tstate & TSTATE_PRIV);
+
+       down(&mm->mmap_sem);
+       vma = find_vma(mm, address);
+       if(!vma)
+               goto bad_area;
+       if(vma->vm_start <= address)
+               goto good_area;
+       if(!(vma->vm_flags & VM_GROWSDOWN))
+               goto bad_area;
+       if(expand_stack(vma, address))
+               goto bad_area;
+       /*
+        * Ok, we have a good vm_area for this memory access, so
+        * we can handle it..
+        */
+good_area:
+       if(write) {
+               if(!(vma->vm_flags & VM_WRITE))
+                       goto bad_area;
+       } else {
+               /* Allow reads even for write-only mappings */
+               if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       goto bad_area;
+       }
+       handle_mm_fault(vma, address, write);
+       up(&mm->mmap_sem);
+       return;
+
+       vma = find_vma(mm, address);
+       if(!vma)
+               goto bad_area;
+       if(vma->vm_start <= address)
+               goto good_area;
+       if(!(vma->vm_flags & VM_GROWSDOWN))
+               goto bad_area;
+       if(expand_stack(vma, address))
+               goto bad_area;
+       /*
+        * Ok, we have a good vm_area for this memory access, so
+        * we can handle it..
+        */
+good_area:
+       if(write) {
+               if(!(vma->vm_flags & VM_WRITE))
+                       goto bad_area;
+       } else {
+               /* Allow reads even for write-only mappings */
+               if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                       goto bad_area;
+       }
+       handle_mm_fault(vma, address, write);
+       up(&mm->mmap_sem);
+       return;
+       /*
+        * Something tried to access memory that isn't in our memory map..
+        * Fix it, but check if it's kernel or user first..
+        */
+bad_area:
+       up(&mm->mmap_sem);
+       /* Is this in ex_table? */
+       
+       g2 = regs->u_regs[UREG_G2];
+       if (!from_user && (fixup = search_exception_table (regs->pc, &g2))) {
+               printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address);
+               printk("EX_TABLE: insn<%08lx> fixup<%08x> g2<%08lx>\n",
+                       regs->pc, fixup, g2);
+               regs->pc = fixup;
+               regs->npc = regs->pc + 4;
+               regs->u_regs[UREG_G2] = g2;
+               return;
+       }
+       /* Did we have an exception handler installed? */
+       if(current->tss.ex.count == 1) {
+               if(from_user) {
+                       printk("Yieee, exception signalled from user mode.\n");
+               } else {
+                       /* Set pc to %g1, set %g1 to -EFAULT and %g2 to
+                        * the faulting address so we can cleanup.
+                        */
+                       printk("Exception: PC<%08lx> faddr<%08lx>\n", regs->pc, address);
+                       printk("EX: count<%d> pc<%08lx> expc<%08lx> address<%08lx>\n",
+                              (int) current->tss.ex.count, current->tss.ex.pc,
+                              current->tss.ex.expc, current->tss.ex.address);
+                       current->tss.ex.count = 0;
+                       regs->pc = current->tss.ex.expc;
+                       regs->npc = regs->pc + 4;
+                       regs->u_regs[UREG_G1] = -EFAULT;
+                       regs->u_regs[UREG_G2] = address - current->tss.ex.address;
+                       regs->u_regs[UREG_G3] = current->tss.ex.pc;
+                       return;
+               }
+       }
+       if(from_user) {
+#if 0
+               printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n",
+                      tsk->comm, tsk->pid, address, regs->pc);
+#endif
+               tsk->tss.sig_address = address;
+               tsk->tss.sig_desc = SUBSIG_NOMAPPING;
+               send_sig(SIGSEGV, tsk, 1);
+               return;
+       }
+       if((unsigned long) address < PAGE_SIZE) {
+               printk(KERN_ALERT "Unable to handle kernel NULL "
+                      "pointer dereference");
+       } else {
+               printk(KERN_ALERT "Unable to handle kernel paging request "
+                      "at virtual address %08lx\n", address);
+       }
+       printk(KERN_ALERT "tsk->mm->context = %08lx\n",
+              (unsigned long) tsk->mm->context);
+       printk(KERN_ALERT "tsk->mm->pgd = %08lx\n",
+              (unsigned long) tsk->mm->pgd);
+       die_if_kernel("Oops", regs);
+}
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
new file mode 100644 (file)
index 0000000..289ddd4
--- /dev/null
@@ -0,0 +1,124 @@
+/* $Id: generic.c,v 1.1 1996/12/26 10:24:23 davem Exp $
+ * generic.c: Generic Sparc mm routines that are not dependent upon
+ *            MMU type but are Sparc specific.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+
+/* Allocate a block of RAM which is aligned to its size.
+ * This procedure can be used until the call to mem_init().
+ */
+void *sparc_init_alloc(unsigned long *kbrk, unsigned long size)
+{
+        unsigned long mask = size - 1;
+        unsigned long ret;
+
+        if(!size)
+                return 0x0;
+        if(size & mask) {
+                prom_printf("panic: sparc_init_alloc botch\n");
+                prom_halt();
+        }
+        ret = (*kbrk + mask) & ~mask;
+        *kbrk = ret + size;
+        memset((void*) ret, 0, size);
+        return (void*) ret;
+}
+
+static inline void forget_pte(pte_t page)
+{
+       if (pte_none(page))
+               return;
+       if (pte_present(page)) {
+               unsigned long addr = pte_page(page);
+               if (MAP_NR(addr) >= max_mapnr || PageReserved(mem_map+MAP_NR(addr)))
+                       return;
+               free_page(addr);
+               if (current->mm->rss <= 0)
+                       return;
+               current->mm->rss--;
+               return;
+       }
+       swap_free(pte_val(page));
+}
+
+/* Remap IO memory, the same way as remap_page_range(), but use
+ * the obio memory space.
+ *
+ * They use a pgprot that sets PAGE_IO and does not check the
+ * mem_map table as this is independent of normal memory.
+ */
+static inline void io_remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
+       unsigned long offset, pgprot_t prot, int space)
+{
+       unsigned long end;
+
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               pte_t oldpage = *pte;
+               pte_clear(pte);
+               set_pte(pte, mk_pte_io(offset, prot, space));
+               forget_pte(oldpage);
+               address += PAGE_SIZE;
+               offset += PAGE_SIZE;
+               pte++;
+       } while (address < end);
+}
+
+static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size,
+       unsigned long offset, pgprot_t prot, int space)
+{
+       unsigned long end;
+
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       offset -= address;
+       do {
+               pte_t * pte = pte_alloc(pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address < end);
+       return 0;
+}
+
+int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space)
+{
+       int error = 0;
+       pgd_t * dir;
+       unsigned long beg = from;
+       unsigned long end = from + size;
+
+       prot = __pgprot(pg_iobits);
+       offset -= from;
+       dir = pgd_offset(current->mm, from);
+       flush_cache_range(current->mm, beg, end);
+       while (from < end) {
+               pmd_t *pmd = pmd_alloc(dir, from);
+               error = -ENOMEM;
+               if (!pmd)
+                       break;
+               error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space);
+               if (error)
+                       break;
+               from = (from + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       }
+       flush_tlb_range(current->mm, beg, end);
+       return error;
+}
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
new file mode 100644 (file)
index 0000000..0f92ef5
--- /dev/null
@@ -0,0 +1,219 @@
+/*  $Id: init.c,v 1.1 1996/12/26 10:24:23 davem Exp $
+ *  arch/sparc64/mm/init.c
+ *
+ *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+extern void show_net_buffers(void);
+
+struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving an inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+pte_t *__bad_pagetable(void)
+{
+       memset((void *) EMPTY_PGT, 0, PAGE_SIZE);
+       return (pte_t *) EMPTY_PGT;
+}
+
+pte_t __bad_page(void)
+{
+       memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
+       return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
+}
+
+void show_mem(void)
+{
+       int i,free = 0,total = 0,reserved = 0;
+       int shared = 0;
+
+       printk("\nMem-info:\n");
+       show_free_areas();
+       printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+       i = max_mapnr;
+       while (i-- > 0) {
+               total++;
+               if (PageReserved(mem_map + i))
+                       reserved++;
+               else if (!mem_map[i].count)
+                       free++;
+               else
+                       shared += mem_map[i].count-1;
+       }
+       printk("%d pages of RAM\n",total);
+       printk("%d free pages\n",free);
+       printk("%d reserved pages\n",reserved);
+       printk("%d pages shared\n",shared);
+       show_buffers();
+#ifdef CONFIG_NET
+       show_net_buffers();
+#endif
+}
+
+__initfunc(unsigned long sparc_context_init(unsigned long start_mem, int numctx))
+{
+       int ctx;
+
+       ctx_list_pool = (struct ctx_list *) start_mem;
+       start_mem += (numctx * sizeof(struct ctx_list));
+       for(ctx = 0; ctx < numctx; ctx++) {
+               struct ctx_list *clist;
+
+               clist = (ctx_list_pool + ctx);
+               clist->ctx_number = ctx;
+               clist->ctx_mm = 0;
+       }
+       ctx_free.next = ctx_free.prev = &ctx_free;
+       ctx_used.next = ctx_used.prev = &ctx_used;
+       for(ctx = 0; ctx < numctx; ctx++)
+               add_to_free_ctxlist(ctx_list_pool + ctx);
+       return start_mem;
+}
+
+/* paging_init() sets up the page tables */
+
+__initfunc(unsigned long 
+paging_init(unsigned long start_mem, unsigned long end_mem))
+{
+}
+
+extern int min_free_pages;
+extern int free_pages_low;
+extern int free_pages_high;
+
+__initfunc(static void taint_real_pages(unsigned long start_mem, unsigned long end_mem))
+{
+       unsigned long addr, tmp2 = 0;
+
+       for(addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE) {
+               if(addr >= KERNBASE && addr < start_mem)
+                       addr = start_mem;
+               for(tmp2=0; sp_banks[tmp2].num_bytes != 0; tmp2++) {
+                       unsigned long phys_addr = (addr - PAGE_OFFSET);
+                       unsigned long base = sp_banks[tmp2].base_addr;
+                       unsigned long limit = base + sp_banks[tmp2].num_bytes;
+
+                       if((phys_addr >= base) && (phys_addr < limit) &&
+                          ((phys_addr + PAGE_SIZE) < limit))
+                               mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
+               }
+       }
+}
+
+__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+{
+       int codepages = 0;
+       int datapages = 0;
+       unsigned long tmp2, addr;
+       extern char etext;
+
+       /* Saves us work later. */
+       memset((void *) ZERO_PAGE, 0, PAGE_SIZE);
+
+       end_mem &= PAGE_MASK;
+       max_mapnr = MAP_NR(end_mem);
+       high_memory = (void *) end_mem;
+
+       start_mem = PAGE_ALIGN(start_mem);
+       num_physpages = (start_mem - KERNBASE) >> PAGE_SHIFT;
+
+       addr = KERNBASE;
+       while(addr < start_mem) {
+#ifdef CONFIG_BLK_DEV_INITRD
+               if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end)
+                       mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
+               else
+#endif 
+                       mem_map[MAP_NR(addr)].flags |= (1<<PG_reserved);
+               addr += PAGE_SIZE;
+       }
+
+       taint_real_pages(start_mem, end_mem);
+       for (addr = PAGE_OFFSET; addr < end_mem; addr += PAGE_SIZE) {
+               if(PageReserved(mem_map + MAP_NR(addr))) {
+                       if ((addr < (unsigned long) &etext) && (addr >= KERNBASE))
+                               codepages++;
+                       else if((addr < start_mem) && (addr >= KERNBASE))
+                               datapages++;
+                       continue;
+               }
+               mem_map[MAP_NR(addr)].count = 1;
+               num_physpages++;
+#ifdef CONFIG_BLK_DEV_INITRD
+               if (!initrd_start ||
+                   (addr < initrd_start || addr >= initrd_end))
+#endif
+                       free_page(addr);
+       }
+
+       tmp2 = nr_free_pages << PAGE_SHIFT;
+
+       printk("Memory: %luk available (%dk kernel code, %dk data) [%08lx,%08lx]\n",
+              tmp2 >> 10,
+              codepages << (PAGE_SHIFT-10),
+              datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem);
+
+       min_free_pages = nr_free_pages >> 7;
+       if(min_free_pages < 16)
+               min_free_pages = 16;
+       free_pages_low = min_free_pages + (min_free_pages >> 1);
+       free_pages_high = min_free_pages + min_free_pages;
+}
+
+void free_initmem (void)
+{
+       extern int text_init_begin, text_init_end, data_init_begin, data_init_end;
+       unsigned long addr, addrend;
+       int savec, saved;
+       
+       addr = PAGE_ALIGN((unsigned long)(&text_init_begin));
+       addrend = ((unsigned long)(&text_init_end)) & PAGE_MASK;
+       for (savec = addrend - addr; addr < addrend; addr += PAGE_SIZE) {
+               mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+               mem_map[MAP_NR(addr)].count = 1;
+               free_page(addr);
+       }
+       if (savec < 0) savec = 0;
+       addr = PAGE_ALIGN((unsigned long)(&data_init_begin));
+       addrend = ((unsigned long)(&data_init_end)) & PAGE_MASK;
+       for (saved = addrend - addr; addr < addrend; addr += PAGE_SIZE) {
+               mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+               mem_map[MAP_NR(addr)].count = 1;
+               free_page(addr);
+       }
+       if (saved < 0) saved = 0;
+       printk ("Freeing unused kernel memory: %dk code, %dk data\n",
+               savec >> 10, saved >> 10);
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+       int i;
+
+       i = MAP_NR(high_memory);
+       val->totalram = 0;
+       val->sharedram = 0;
+       val->freeram = nr_free_pages << PAGE_SHIFT;
+       val->bufferram = buffermem;
+       while (i-- > 0)  {
+               if (PageReserved(mem_map + i))
+                       continue;
+               val->totalram++;
+               if (!mem_map[i].count)
+                       continue;
+               val->sharedram += mem_map[i].count-1;
+       }
+       val->totalram <<= PAGE_SHIFT;
+       val->sharedram <<= PAGE_SHIFT;
+}
diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile
new file mode 100644 (file)
index 0000000..32af094
--- /dev/null
@@ -0,0 +1,23 @@
+# $Id: Makefile,v 1.1 1996/12/27 08:49:10 jj Exp $
+# Makefile for the Sun Boot PROM interface library under
+# Linux.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+OBJS  = bootstr.o devops.o init.o memory.o misc.o mp.o \
+        ranges.o tree.o console.o printf.o
+
+all: promlib.a
+
+promlib.a: $(OBJS)
+       $(AR) rcs promlib.a $(OBJS)
+       sync
+
+dep:
+       $(CPP) -M *.c > .depend
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/prom/bootstr.c b/arch/sparc64/prom/bootstr.c
new file mode 100644 (file)
index 0000000..f158303
--- /dev/null
@@ -0,0 +1,24 @@
+/* $Id: bootstr.c,v 1.1 1996/12/27 08:49:10 jj Exp $
+ * bootstr.c:  Boot string/argument acquisition from the PROM.
+ *
+ * Copyright(C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright(C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/oplib.h>
+
+#define BARG_LEN  256
+static char barg_buf[BARG_LEN];
+static char fetched = 0;
+
+char *
+prom_getbootargs(void)
+{
+       /* This check saves us from a panic when bootfd patches args. */
+       if (fetched) return barg_buf;
+       prom_getstring(prom_finddevice ("/chosen"), "bootargs", barg_buf, BARG_LEN);
+       fetched = 1;
+       return barg_buf;
+}
diff --git a/arch/sparc64/prom/console.c b/arch/sparc64/prom/console.c
new file mode 100644 (file)
index 0000000..d48246c
--- /dev/null
@@ -0,0 +1,123 @@
+/* $Id: console.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * console.c: Routines that deal with sending and receiving IO
+ *            to/from the current console device using the PROM.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+#include <asm/system.h>
+#include <linux/string.h>
+
+extern int prom_stdin, prom_stdout;
+
+/* Non blocking get character from console input device, returns -1
+ * if no input was taken.  This can be used for polling.
+ */
+__inline__ int
+prom_nbgetchar(void)
+{
+       char inc;
+
+       if ((*prom_command)("read", P1275_ARG(1,P1275_ARG_IN_BUF)|
+                                   P1275_INOUT(3,1),
+                                   prom_stdin, &inc, P1275_SIZE(1)) == 1)
+               return inc;
+       else
+               return -1;
+}
+
+/* Non blocking put character to console device, returns -1 if
+ * unsuccessful.
+ */
+__inline__ int
+prom_nbputchar(char c)
+{
+       char outc;
+       
+       outc = c;
+       if ((*prom_command)("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
+                                    P1275_INOUT(3,1),
+                                    prom_stdin, &inc, P1275_SIZE(1)) == 1)
+               return 0;
+       else
+               return -1;
+}
+
+/* Blocking version of get character routine above. */
+char
+prom_getchar(void)
+{
+       int character;
+       while((character = prom_nbgetchar()) == -1) ;
+       return (char) character;
+}
+
+/* Blocking version of put character routine above. */
+void
+prom_putchar(char c)
+{
+       while(prom_nbputchar(c) == -1) ;
+       return;
+}
+
+/* Query for input device type */
+enum prom_input_device
+prom_query_input_device()
+{
+       int st_p;
+       char propb[64];
+       char *p;
+
+       st_p = prom_inst2pkg(prom_stdin);
+       if(prom_node_has_property(st_p, "keyboard"))
+               return PROMDEV_IKBD;
+       prom_getproperty(st_p, "device_type", propb, sizeof(propb));
+       if(strncmp(propb, "serial", sizeof("serial")))
+               return PROMDEV_I_UNK;
+       /* FIXME: Is there any better way how to find out? */   
+       st_p = prom_finddevice ("/options");
+       prom_getproperty(st_p, "input-device", propb, sizeof(propb));
+       if (strncmp (propb, "tty", 3) || !propb[3] || propb[4])
+               return PROMDEV_I_UNK;
+       switch (propb[3]) {
+               case 'a': return PROMDEV_ITTYA;
+               case 'b': return PROMDEV_ITTYB;
+               default: return PROMDEV_I_UNK;
+       }
+}
+
+/* Query for output device type */
+
+enum prom_output_device
+prom_query_output_device()
+{
+       int st_p;
+       char propb[64];
+       char *p;
+       int propl;
+
+       st_p = prom_inst2pkg(prom_stdout);
+       propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
+       if (propl >= 0 && propl == sizeof("display") &&
+           strncmp("display", propb, sizeof("display")) == 0)
+               return PROMDEV_OSCREEN;
+       if(strncmp("serial", propb, sizeof("serial")))
+               return PROMDEV_O_UNK;
+       /* FIXME: Is there any better way how to find out? */   
+       st_p = prom_finddevice ("/options");
+       prom_getproperty(st_p, "output-device", propb, sizeof(propb));
+       if (strncmp (propb, "tty", 3) || !propb[3] || propb[4])
+               return PROMDEV_O_UNK;
+       switch (propb[3]) {
+               case 'a': return PROMDEV_OTTYA;
+               case 'b': return PROMDEV_OTTYB;
+               default: return PROMDEV_O_UNK;
+       }
+}
diff --git a/arch/sparc64/prom/devops.c b/arch/sparc64/prom/devops.c
new file mode 100644 (file)
index 0000000..0e71c2f
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id: devops.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * devops.c:  Device operations using the PROM.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Open the device described by the string 'dstr'.  Returns the handle
+ * to that device used for subsequent operations on that device.
+ * Returns -1 on failure.
+ */
+int
+prom_devopen(char *dstr)
+{
+       return (*prom_command)("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
+                                      P1275_INOUT(1,1),
+                                      dstr);
+}
+
+/* Close the device described by device handle 'dhandle'. */
+int
+prom_devclose(int dhandle)
+{
+       (*prom_command)("close", P1275_INOUT(1,0), dhandle);
+       return 0;
+}
+
+/* Seek to specified location described by 'seekhi' and 'seeklo'
+ * for device 'dhandle'.
+ */
+void
+prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
+{
+       (*prom_command)("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
+}
diff --git a/arch/sparc64/prom/init.c b/arch/sparc64/prom/init.c
new file mode 100644 (file)
index 0000000..a1d835c
--- /dev/null
@@ -0,0 +1,77 @@
+/* $Id: init.c,v 1.1 1996/12/27 08:49:11 jj Exp $
+ * init.c:  Initialize internal variables used by the PROM
+ *          library functions.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+enum prom_major_version prom_vers;
+unsigned int prom_rev, prom_prev;
+
+/* The root node of the prom device tree. */
+int prom_root_node;
+int prom_stdin, prom_stdout;
+(long)(*prom_command)(char *, long, ...);
+
+/* You must call prom_init() before you attempt to use any of the
+ * routines in the prom library.  It returns 0 on success, 1 on
+ * failure.  It gets passed the pointer to the PROM vector.
+ */
+
+extern void prom_meminit(void);
+extern void prom_ranges_init(void);
+extern void prom_cif_init(void *, void *);
+
+__initfunc(void prom_init(void *cif_handler, void *cif_stack))
+{
+       char buffer[80];
+       int node;
+       
+       prom_vers = PROM_P1275;
+       
+       prom_cif_init(cif_handler, cif_stack);
+
+       prom_root_node = prom_getsibling(0);
+       if((prom_root_node == 0) || (prom_root_node == -1))
+               prom_halt();
+
+       node = prom_finddevice("/chosen");
+       if (!node || node == -1)
+               prom_halt();
+               
+       prom_stdin = prom_getint (node, "stdin");
+       prom_stdout = prom_getint (node, "stdout");
+
+       node = prom_finddevice("/openprom");
+       if (!node || node == -1)
+               prom_halt();
+               
+       prom_getstring (openprom_node, "version", buffer, sizeof (buffer));
+       if (strncmp (buffer, "OPB ", 4) || buffer[5] != '.' || buffer[7] != '.') {
+               prom_printf ("Strange OPB version.\n");
+               prom_halt ();
+       }
+       /* Version field is expected to be 'OPB x.y.z date...' */
+       
+       prom_rev = buffer[6] - '0';
+       prom_prev = ((buffer[4] - '0') << 16) | 
+                   ((buffer[6] - '0') << 8) |
+                   (buffer[8] - '0');
+                   
+       prom_meminit();
+
+       prom_ranges_init();
+
+       printk("PROMLIB: Sun IEEE Boot Prom %s\n",
+              buffer + 4);
+
+       /* Initialization successful. */
+}
diff --git a/arch/sparc64/prom/k1275d.c b/arch/sparc64/prom/k1275d.c
new file mode 100644 (file)
index 0000000..744b979
--- /dev/null
@@ -0,0 +1,123 @@
+/* $Id: k1275d.c,v 1.1 1996/12/27 08:49:12 jj Exp $
+ * k1275d.c: Sun IEEE 1275 PROM kernel daemon
+ *
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+#define p1275sect __attribute__ ((__section__ (".p1275")))
+
+static void prom_doit (void) p1275sect;
+
+static void prom_doit (void)
+{
+       /* FIXME: The PROM stack is grossly misaligned.
+        * It needs some special way of handling spills/fills.
+        * Either using %otherwin or doing flushw; wrpr somevalue, %wstate
+        * should be done here to make difference between PROM stack
+        * saving (32bit, misaligned stack) and kernel fill/spill).
+        */
+       __asm__ __volatile__ ("
+       save    %%sp, -0xc0, %%sp;
+       mov     %%sp, %%l1;
+       mov     %0, %%sp;
+       call    %1;
+        mov    %0, %%o0;
+       mov     %%l1, %%sp;
+       restore;
+       " : : "r" (prom_cif_stack), "r" (prom_cif_handler));
+}
+
+static void (*prom_cif_handler)(long *) p1275sect;
+static void prom_cif_stack;
+static void (*prom_do_it)(void);
+static long prom_args [23] p1275sect;
+static char prom_buffer [4096] p1275sect;
+
+long prom_handle_command(char *service, long fmt, ...)
+{
+       char *p = prom_buffer;
+       unsigned long flags;
+       int nargs, nrets, i;
+       va_list list;
+       long attrs, x;
+       
+       save_and_cli(flags);
+       prom_args[0] = p;                               /* service */
+       strcpy (p, function);
+       p = strchr (p, 0) + 1;
+       prom_args[1] = nargs = (fmt & 0x0f);            /* nargs */
+       prom_args[2] = nrets = ((fmt & 0xf0) >> 4);     /* nrets */
+       attrs = (fmt & (~0xff));
+       va_start(list, fmt);
+       for (i = 0; i < nargs; i++, attrs >>= 3) {
+               switch (attrs & 0x7) {
+               case P1275_ARG_NUMBER:
+                       prom_args[i + 3] = va_arg(list, long); break;
+               case P1275_ARG_IN_STRING:
+                       strcpy (p, va_arg(list, char *));
+                       prom_args[i + 3] = p;
+                       p = strchr (p, 0) + 1;
+                       break;
+               case P1275_ARG_OUT_BUF:
+                       va_arg(list, char *);
+                       prom_args[i + 3] = p;
+                       x = va_arg(list, long);
+                       i++; attrs >>= 3;
+                       p += (int)x;
+                       prom_args[i + 3] = x;
+                       break;
+               case P1275_ARG_OUT_32B:
+                       va_arg(list, char *);
+                       prom_args[i + 3] = p;
+                       p += 32;
+                       break;
+               case P1275_ARG_IN_FUNCTION:
+                       /* FIXME: This should make a function in our <4G
+                        * section, which will call the argument,
+                        * so that PROM can call it.
+                        */
+                       prom_args[i + 3] = va_arg(list, long); break;
+               }
+       }
+       va_end(list);
+       (*prom_do_it)();
+       attrs = fmt & (~0xff);
+       va_start(list, fmt);
+       for (i = 0; i < nargs; i++, attrs >>= 3) {
+               switch (attrs & 0x7) {
+               case P1275_ARG_NUMBER:
+               case P1275_ARG_IN_STRING:
+               case P1275_ARG_IN_FUNCTION:
+                       break;
+               case P1275_ARG_OUT_BUF:
+                       p = va_arg(list, char *);
+                       x = va_arg(list, long);
+                       memcpy (p, (char *)prom_args[i + 3], (int)x);
+                       i++; attrs >>= 3;
+                       break;
+               case P1275_ARG_OUT_32B:
+                       p = va_arg(list, char *);
+                       memcpy (p, (char *)prom_args[i + 3], 32);
+                       break;
+               }
+       }
+       va_end(list);
+       x = prom_args [nargs + 3];
+       restore_flags(flags);
+       return x;
+}
+
+void prom_cif_init(void *cif_handler, void *cif_stack)
+{
+       prom_cif_handler = (void (*)(long *))cif_handler;
+       prom_cif_stack = cif_stack;
+       prom_command = prom_handle_command;
+        prom_do_it = prom_doit;
+}
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
new file mode 100644 (file)
index 0000000..7b3a801
--- /dev/null
@@ -0,0 +1,124 @@
+/* $Id: misc.c,v 1.1 1996/12/27 08:49:12 jj Exp $
+ * misc.c:  Miscellaneous prom functions that don't belong
+ *          anywhere else.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Reset and reboot the machine with the command 'bcommand'. */
+void
+prom_reboot(char *bcommand)
+{
+       (*prom_command)("boot", P1275_ARG(0,P1275_ARG_IN_STRING)|
+                               P1275_INOUT(1,0), bcommand);
+}
+
+/* Forth evaluate the expression contained in 'fstring'. */
+void
+prom_feval(char *fstring)
+{
+       if(!fstring || fstring[0] == 0)
+               return;
+       (*prom_command)("interpret", P1275_ARG(0,P1275_ARG_IN_STRING)|
+                                    P1275_INOUT(1,1), fstring);
+}
+
+/* We want to do this more nicely some day. */
+#ifdef CONFIG_SUN_CONSOLE
+extern void console_restore_palette(void);
+extern void set_palette(void);
+extern int serial_console;
+#endif
+
+/* Drop into the prom, with the chance to continue with the 'go'
+ * prom command.
+ */
+void
+prom_cmdline(void)
+{
+       extern void kernel_enter_debugger(void);
+       extern void install_obp_ticker(void);
+       extern void install_linux_ticker(void);
+       unsigned long flags;
+    
+       kernel_enter_debugger();
+#ifdef CONFIG_SUN_CONSOLE
+       if(!serial_console)
+               console_restore_palette ();
+#endif
+       install_obp_ticker();
+       save_flags(flags); cli();
+       (*prom_command)("enter", P1275_INOUT(0,0));
+       restore_flags(flags);
+       install_linux_ticker();
+#ifdef CONFIG_SUN_CONSOLE
+       if(!serial_console)
+               set_palette ();
+#endif
+}
+
+/* Drop into the prom, but completely terminate the program.
+ * No chance of continuing.
+ */
+void
+prom_halt(void)
+{
+       (*prom_command)("exit", P1275_INOUT(0,0));
+}
+
+typedef void (*sfunc_t)(void);
+
+/* Set prom sync handler to call function 'funcp'. */
+void
+prom_setsync(sfunc_t funcp)
+{
+       if(!funcp) return;
+       (*prom_command)("set-callback", P1275_ARG(0,P1275_IN_FUNCTION)|
+                                       P1275_INOUT(1,1), funcp);
+}
+
+/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
+ * format type.  'num_bytes' is the number of bytes that your idbuf
+ * has space for.  Returns 0xff on error.
+ */
+unsigned char
+prom_get_idprom(char *idbuf, int num_bytes)
+{
+       int len;
+
+       len = prom_getproplen(prom_root_node, "idprom");
+       if((len>num_bytes) || (len==-1)) return 0xff;
+       if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
+               return idbuf[0];
+
+       return 0xff;
+}
+
+/* Get the major prom version number. */
+int
+prom_version(void)
+{
+       return PROM_P1275;
+}
+
+/* Get the prom plugin-revision. */
+int
+prom_getrev(void)
+{
+       return prom_rev;
+}
+
+/* Get the prom firmware print revision. */
+int
+prom_getprev(void)
+{
+       return prom_prev;
+}
diff --git a/arch/sparc64/prom/printf.c b/arch/sparc64/prom/printf.c
new file mode 100644 (file)
index 0000000..f4b78f4
--- /dev/null
@@ -0,0 +1,39 @@
+/* $Id: printf.c,v 1.1 1996/12/27 08:49:13 jj Exp $
+ * printf.c:  Internal prom library printf facility.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* This routine is internal to the prom library, no one else should know
+ * about or use it!  It's simple and smelly anyway....
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+static char ppbuf[1024];
+
+void
+prom_printf(char *fmt, ...)
+{
+       va_list args;
+       char ch, *bptr;
+       int i;
+
+       va_start(args, fmt);
+       i = vsprintf(ppbuf, fmt, args);
+
+       bptr = ppbuf;
+
+       while((ch = *(bptr++)) != 0) {
+               if(ch == '\n')
+                       prom_putchar('\r');
+
+               prom_putchar(ch);
+       }
+       va_end(args);
+       return;
+}
diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c
new file mode 100644 (file)
index 0000000..f3ed1fd
--- /dev/null
@@ -0,0 +1,292 @@
+/* $Id: tree.c,v 1.1 1996/12/27 08:49:13 jj Exp $
+ * tree.c: Basic device tree traversal/scanning for the Linux
+ *         prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/openprom.h>
+#include <asm/oplib.h>
+
+/* Return the child of node 'node' or zero if no this node has no
+ * direct descendent.
+ */
+__inline__ int
+prom_getchild(int node)
+{
+       long cnode;
+
+       if(node == -1) return 0;
+       cnode = (*prom_command)("child", P1275_INOUT(1, 1), node);
+       if(cnode == -1) return 0;
+       return (int)cnode;
+}
+
+/* Return the next sibling of node 'node' or zero if no more siblings
+ * at this level of depth in the tree.
+ */
+__inline__ int
+prom_getsibling(int node)
+{
+       long sibnode;
+
+       if(node == -1) return 0;
+       sibnode = (*prom_command)("peer", P1275_INOUT(1, 1), node);
+       if(cnode == -1) return 0;
+       return (int)sibnode;
+}
+
+/* Return the length in bytes of property 'prop' at node 'node'.
+ * Return -1 on error.
+ */
+__inline__ int
+prom_getproplen(int node, char *prop)
+{
+       if((!node) || (!prop)) return -1;
+       return (*prom_command)("getproplen", 
+                              P1275_ARG(1,P1275_ARG_IN_STRING)|
+                              P1275_INOUT(2, 1), 
+                              node, prop);
+}
+
+/* Acquire a property 'prop' at node 'node' and place it in
+ * 'buffer' which has a size of 'bufsize'.  If the acquisition
+ * was successful the length will be returned, else -1 is returned.
+ */
+__inline__ int
+prom_getproperty(int node, char *prop, char *buffer, int bufsize)
+{
+       int plen;
+
+       plen = prom_getproplen(node, prop);
+       if((plen > bufsize) || (plen == 0) || (plen == -1))
+               return -1;
+       else {
+               /* Ok, things seem all right. */
+               return (*prom_command)("getprop", 
+                                      P1275_ARG(1,P1275_ARG_IN_STRING)|
+                                      P1275_ARG(2,P1275_ARG_OUT_BUF)|
+                                      P1275_INOUT(4, 1), 
+                                      node, prop, buffer, P1275_SIZE(plen));
+       }
+}
+
+/* Acquire an integer property and return its value.  Returns -1
+ * on failure.
+ */
+__inline__ int
+prom_getint(int node, char *prop)
+{
+       int intprop;
+
+       if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
+               return intprop;
+
+       return -1;
+}
+
+/* Acquire an integer property, upon error return the passed default
+ * integer.
+ */
+
+int
+prom_getintdefault(int node, char *property, int deflt)
+{
+       int retval;
+
+       retval = prom_getint(node, property);
+       if(retval == -1) return deflt;
+
+       return retval;
+}
+
+/* Acquire a boolean property, 1=TRUE 0=FALSE. */
+int
+prom_getbool(int node, char *prop)
+{
+       int retval;
+
+       retval = prom_getproplen(node, prop);
+       if(retval == -1) return 0;
+       return 1;
+}
+
+/* Acquire a property whose value is a string, returns a null
+ * string on error.  The char pointer is the user supplied string
+ * buffer.
+ */
+void
+prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
+{
+       int len;
+
+       len = prom_getproperty(node, prop, user_buf, ubuf_size);
+       if(len != -1) return;
+       user_buf[0] = 0;
+       return;
+}
+
+
+/* Does the device at node 'node' have name 'name'?
+ * YES = 1   NO = 0
+ */
+int
+prom_nodematch(int node, char *name)
+{
+       char namebuf[128];
+       prom_getproperty(node, "name", namebuf, sizeof(namebuf));
+       if(strcmp(namebuf, name) == 0) return 1;
+       return 0;
+}
+
+/* Search siblings at 'node_start' for a node with name
+ * 'nodename'.  Return node if successful, zero if not.
+ */
+int
+prom_searchsiblings(int node_start, char *nodename)
+{
+
+       int thisnode, error;
+       char promlib_buf[128];
+
+       for(thisnode = node_start; thisnode;
+           thisnode=prom_getsibling(thisnode)) {
+               error = prom_getproperty(thisnode, "name", promlib_buf,
+                                        sizeof(promlib_buf));
+               /* Should this ever happen? */
+               if(error == -1) continue;
+               if(strcmp(nodename, promlib_buf)==0) return thisnode;
+       }
+
+       return 0;
+}
+
+/* Gets name in the {name@x,yyyyy|name (if no reg)} form */
+int 
+prom_getname (int node, char *buffer, int len)
+{
+       int i;
+       struct linux_prom_registers reg[PROMREG_MAX];
+       
+       i = prom_getproperty (node, "name", buffer, len);
+       if (i <= 0) return -1;
+       buffer [i] = 0;
+       len -= i;
+       i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg));
+       if (i <= 0) return 0;
+       if (len < 11) return -1;
+       buffer = strchr (buffer, 0);
+       sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr);
+       return 0;
+}
+
+/* Return the first property type for node 'node'.
+ * buffer should be at least 32B in length
+ */
+__inline__ char *
+prom_firstprop(int node, char *buffer)
+{
+       if(node == -1) return "";
+       *buffer = 0;
+       (*prom_command)("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
+                                   P1275_INOUT(3, 0), 
+                                   node, (char *) 0x0, buffer);
+       return buffer;
+}
+
+/* Return the property type string after property type 'oprop'
+ * at node 'node' .  Returns NULL string if no more
+ * property types for this node.
+ */
+__inline__ char *
+prom_nextprop(int node, char *oprop, char *buffer)
+{
+       char buf[32];
+
+       if(node == -1) return "";
+       *buffer = 0;
+       (*prom_command)("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+                                   P1275_ARG(2,P1275_ARG_OUT_32B)|
+                                   P1275_INOUT(3, 0), 
+                                   node, oprop, (oprop == buffer) ? 
+                                   buf : buffer);
+       if (oprop == buffer) strcpy (buffer, buf);
+       return buffer;
+}
+
+int
+prom_finddevice(char *name)
+{
+       if(!name) return 0;
+       *buffer = 0;
+       (*prom_command)("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)|
+                                     P1275_INOUT(1, 1), 
+                                     name);
+       return buffer;
+}
+
+int
+prom_node_has_property(int node, char *prop)
+{
+       char buf[32];
+       char *current_property = buf;
+       
+       *buf = 0;
+       do {
+               current_property = prom_nextprop(node, current_property, buf);
+               if(!strcmp(current_property, prop))
+                       return 1;
+       } while (*current_property);
+       return 0;
+}
+
+/* Set property 'pname' at node 'node' to value 'value' which has a length
+ * of 'size' bytes.  Return the number of bytes the prom accepted.
+ */
+int
+prom_setprop(int node, char *pname, char *value, int size)
+{
+       unsigned long flags;
+       int ret;
+
+       if(size == 0) return 0;
+       if((pname == 0) || (value == 0)) return 0;
+       
+       return (*prom_command)("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
+                                         P1275_ARG(2,P1275_ARG_OUT_BUF)|
+                                         P1275_INOUT(4, 1), 
+                                         node, pname, value, P1275_SIZE(size));
+}
+
+__inline__ int
+prom_inst2pkg(int inst)
+{
+       int node;
+       
+       node = (*prom_command)("instance-to-package", P1275_INOUT(1, 1), inst);
+       if (node == -1) return 0;
+       return node;
+}
+
+/* Return 'node' assigned to a particular prom 'path'
+ * FIXME: Should work for v0 as well
+ */
+int
+prom_pathtoinode(char *path)
+{
+       int node, inst;
+       
+       inst = prom_devopen (path);
+       if (inst == -1) return 0;
+       node = prom_inst2pkg (inst);
+       prom_devclose (inst);
+       if (node == -1) return 0;
+       return node;
+}
index 48aaf3fac6922a64ad4bac11a5f47f37fbc9ad9a..74d9d3ca5391bb543b3a228297a0a4dcc0ef648f 100644 (file)
  */
 #include <asm/unaligned.h>
 
-#define SYS_IND(p)     get_unaligned(&p->sys_ind)
-#define NR_SECTS(p)    get_unaligned(&p->nr_sects)
-#define START_SECT(p)  get_unaligned(&p->start_sect)
+#define SYS_IND(p)     (get_unaligned(&p->sys_ind))
+#define NR_SECTS(p)    ({ __typeof__(p->nr_sects) __a =        \
+                               get_unaligned(&p->nr_sects);    \
+                               le32_to_cpu(__a); \
+                       })
 
+#define START_SECT(p)  ({ __typeof__(p->start_sect) __a =      \
+                               get_unaligned(&p->start_sect);  \
+                               le32_to_cpu(__a); \
+                       })
 
 struct gendisk *gendisk_head = NULL;
 
@@ -115,6 +121,8 @@ static inline int is_extended_partition(struct partition *p)
  * only for the actual data partitions.
  */
 
+#define MSDOS_LABEL_MAGIC              0xAA55
+
 static void extended_partition(struct gendisk *hd, kdev_t dev)
 {
        struct buffer_head *bh;
@@ -138,7 +146,7 @@ static void extended_partition(struct gendisk *hd, kdev_t dev)
           */
                bh->b_state = 0;
 
-               if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
+               if (le16_to_cpu(*(unsigned short *) (bh->b_data+510)) != MSDOS_LABEL_MAGIC)
                        goto done;
 
                p = (struct partition *) (0x1BE + bh->b_data);
@@ -263,7 +271,7 @@ read_mbr:
 #ifdef CONFIG_BLK_DEV_IDE
 check_table:
 #endif
-       if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
+       if (le16_to_cpu(*(unsigned short *) (0x1fe + data)) != MSDOS_LABEL_MAGIC) {
                brelse(bh);
                return 0;
        }
@@ -275,7 +283,7 @@ check_table:
                 * Look for various forms of IDE disk geometry translation
                 */
                extern int ide_xlate_1024(kdev_t, int, const char *);
-               unsigned int sig = *(unsigned short *)(data + 2);
+               unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
                if (SYS_IND(p) == EZD_PARTITION) {
                        /*
                         * The remainder of the disk must be accessed using
@@ -305,12 +313,10 @@ check_table:
                                brelse(bh);
                                goto read_mbr;  /* start over with new MBR */
                        }
-               } else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
-                        && (1 & *(unsigned char *)(data + sig + 2)) ) 
-               {
-                       /*
-                        * DM6 signature in MBR, courtesy of OnTrack
-                        */
+               } else if (sig <= 0x1ae &&
+                          le16_to_cpu(*(unsigned short *)(data + sig)) == 0x55AA &&
+                          (1 & *(unsigned char *)(data + sig + 2))) {
+                       /* DM6 signature in MBR, courtesy of OnTrack */
                        (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
                } else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
                        /*
@@ -373,7 +379,7 @@ check_table:
        /*
         *  Check for old-style Disk Manager partition table
         */
-       if (*(unsigned short *) (data+0xfc) == 0x55AA) {
+       if (le16_to_cpu(*(unsigned short *) (data+0xfc)) == MSDOS_LABEL_MAGIC) {
                p = (struct partition *) (0x1be + data);
                for (i = 4 ; i < 16 ; i++, current_minor++) {
                        p--;
@@ -492,20 +498,8 @@ static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec
                unsigned short csum;       /* Label xor'd checksum */
        } * label;              
        struct sun_partition *p;
-       int other_endian;
        unsigned long spc;
 #define SUN_LABEL_MAGIC          0xDABE
-#define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
-/* No need to optimize these macros since they are called only when reading
- * the partition table. This occurs only at each disk change. */
-#define SWAP16(x)  (other_endian ? (((__u16)(x) & 0xFF) << 8) \
-                                | (((__u16)(x) & 0xFF00) >> 8) \
-                                : (__u16)(x))
-#define SWAP32(x)  (other_endian ? (((__u32)(x) & 0xFF) << 24) \
-                                | (((__u32)(x) & 0xFF00) << 8) \
-                                | (((__u32)(x) & 0xFF0000) >> 8) \
-                                | (((__u32)(x) & 0xFF000000) >> 24) \
-                                : (__u32)(x))
 
        if(!(bh = bread(dev, 0, 1024))) {
                printk("Dev %s: unable to read partition table\n",
@@ -514,13 +508,12 @@ static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec
        }
        label = (struct sun_disklabel *) bh->b_data;
        p = label->partitions;
-       if (label->magic != SUN_LABEL_MAGIC && label->magic != SUN_LABEL_MAGIC_SWAPPED) {
+       if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
                printk("Dev %s Sun disklabel: bad magic %04x\n",
-                      kdevname(dev), label->magic);
+                      kdevname(dev), be16_to_cpu(label->magic));
                brelse(bh);
                return 0;
        }
-       other_endian = (label->magic == SUN_LABEL_MAGIC_SWAPPED);
        /* Look at the checksum */
        ush = ((unsigned short *) (label+1)) - 1;
        for(csum = 0; ush >= ((unsigned short *) label);)
@@ -532,22 +525,20 @@ static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sec
                return 0;
        }
        /* All Sun disks have 8 partition entries */
-       spc = SWAP16(label->ntrks) * SWAP16(label->nsect);
+       spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
        for(i=0; i < 8; i++, p++) {
                unsigned long st_sector;
 
                /* We register all partitions, even if zero size, so that
                 * the minor numbers end up ok as per SunOS interpretation.
                 */
-               st_sector = first_sector + SWAP32(p->start_cylinder) * spc;
-               add_partition(hd, current_minor, st_sector, SWAP32(p->num_sectors));
+               st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
+               add_partition(hd, current_minor, st_sector, be32_to_cpu(p->num_sectors));
                current_minor++;
        }
        printk("\n");
        brelse(bh);
        return 1;
-#undef SWAP16
-#undef SWAP32
 }
 
 #endif /* CONFIG_SUN_PARTITION */
index 03a68f5464030019337d83a5b2df67703b6b5bd0..0d424bdafcaec3e5c5c0ba8ed2d707bb9fb41373 100644 (file)
@@ -157,20 +157,16 @@ static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
                return retval;
 
        if (opt & TERMIOS_TERMIO) {
-               struct termio tmp_termio;
                retval = verify_area(VERIFY_READ, (void *) arg, sizeof(struct termio));
                if (retval)
                        return retval;
-               tmp_termios = *tty->termios;
-               copy_from_user(&tmp_termio, (struct termio *) arg,
-                             sizeof (struct termio));
-               trans_from_termio(&tmp_termio, &tmp_termios);
+               memcpy(&tmp_termios, tty->termios, sizeof(struct termios));
+               user_termio_to_kernel_termios(&tmp_termios, (struct termio *) arg);
        } else {
                retval = verify_area(VERIFY_READ, (void *) arg, sizeof(struct termios));
                if (retval)
                        return retval;
-               copy_from_user(&tmp_termios, (struct termios *) arg,
-                             sizeof (struct termios));
+               user_termios_to_kernel_termios(&tmp_termios, (struct termios *) arg);
        }
 
        if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer)
@@ -189,13 +185,11 @@ static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
 static int get_termio(struct tty_struct * tty, struct termio * termio)
 {
        int i;
-       struct termio tmp_termio;
 
        i = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));
        if (i)
                return i;
-       trans_to_termio(tty->termios, &tmp_termio);
-       copy_to_user(termio, &tmp_termio, sizeof (struct termio));
+       kernel_termios_to_user_termio(termio, tty->termios);
        return 0;
 }
 
@@ -437,9 +431,8 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                                             sizeof (struct termios));
                        if (retval)
                                return retval;
-                       copy_to_user((struct termios *) arg,
-                                   real_tty->termios,
-                                   sizeof (struct termios));
+                       kernel_termios_to_user_termios((struct termios *)arg,
+                                                      real_tty->termios);
                        return 0;
                case TCSETSF:
                        opt |= TERMIOS_FLUSH;
@@ -531,9 +524,8 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                                             sizeof (struct termios));
                        if (retval)
                                return retval;
-                       copy_to_user((struct termios *) arg,
-                                   real_tty->termios_locked,
-                                   sizeof (struct termios));
+                       kernel_termios_to_user_termios((struct termios *)arg,
+                                                      real_tty->termios_locked);
                        return 0;
                case TIOCSLCKTRMIOS:
                        if (!suser())
@@ -542,9 +534,8 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
                                             sizeof (struct termios));
                        if (retval)
                                return retval;
-                       copy_from_user(real_tty->termios_locked,
-                                     (struct termios *) arg,
-                                     sizeof (struct termios));
+                       user_termios_to_kernel_termios(real_tty->termios_locked,
+                                                      (struct termios *) arg);
                        return 0;
                case TIOCPKT:
                        if (tty->driver.type != TTY_DRIVER_TYPE_PTY ||
index 200b95c79401a4b17f2c4df31b80b2b28ac606df..85daeef120aa8311517830027bd3154c62f09aa8 100644 (file)
@@ -9,15 +9,15 @@
 
     This is a device driver for the 3Com Etherlink 3c501.
     Do not purchase this card, even as a joke.  It's performance is horrible,
-    and it breaks in many ways.  
+    and it breaks in many ways.
 
     The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
     Center of Excellence in Space Data and Information Sciences
        Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-       
+
     Fixed (again!) the missing interrupt locking on TX/RX shifting.
                Alan Cox <Alan.Cox@linux.org>
-               
+
     Removed calls to init_etherdev since they are no longer needed, and
     cleaned up modularization just a bit. The driver still allows only
     the default address for cards when loaded as a module, but that's
     with a TX-TX optimisation to see if we can touch 180-200K/second as seems
     theoretically maximum.
                19950402 Alan Cox <Alan.Cox@linux.org>
-               
+
     Some notes on this thing if you have to hack it.  [Alan]
-    
+
     1] Some documentation is available from 3Com. Due to the boards age
        standard responses when you ask for this will range from 'be serious'
        to 'give it to a museum'. The documentation is incomplete and mostly
        of historical interest anyway.
-       
+
     2]  The basic system is a single buffer which can be used to receive or
        transmit a packet. A third command mode exists when you are setting
        things up.
-       
-    3] If it's transmitting it's not receiving and vice versa. In fact the 
+
+    3] If it's transmitting it's not receiving and vice versa. In fact the
        time to get the board back into useful state after an operation is
        quite large.
-       
+
     4] The driver works by keeping the board in receive mode waiting for a
        packet to arrive. When one arrives it is copied out of the buffer
        and delivered to the kernel. The card is reloaded and off we go.
-       
+
     5] When transmitting dev->tbusy is set and the card is reset (from
        receive mode) [possibly losing a packet just received] to command
        mode. A packet is loaded and transmit mode triggered. The interrupt
        handler runs different code for transmit interrupts and can handle
        returning to receive mode or retransmissions (yes you have to help
        out with those too).
-       
+
     Problems:
        There are a wide variety of undocumented error returns from the card
-    and you basically have to kick the board and pray if they turn up. Most 
+    and you basically have to kick the board and pray if they turn up. Most
     only occur under extreme load or if you do something the board doesn't
     like (eg touching a register at the wrong time).
-    
+
        The driver is less efficient than it could be. It switches through
     receive mode even if more transmits are queued. If this worries you buy
     a real ethernet card.
-    
+
        The combination of slow receive restart and no real multicast
     filter makes the board unusable with a kernel compiled for IP
-    multicasting in a real multicast environment. That's down to the board, 
+    multicasting in a real multicast environment. That's down to the board,
     but even with no multicast programs running a multicast IP kernel is
     in group 224.0.0.1 and you will therefore be listening to all multicasts.
     One nv conference running over that ethernet and you can give up.
-    
+
 */
 
 static const char *version =
@@ -112,9 +112,9 @@ static unsigned int netcard_portlist[] =
 
 \f
 /*
- *     Index to functions. 
+ *     Index to functions.
  */
+
 int el1_probe(struct device *dev);
 static int  el1_probe1(struct device *dev, int ioaddr);
 static int  el_open(struct device *dev);
@@ -132,12 +132,12 @@ static void set_multicast_list(struct device *dev);
 #define EL_DEBUG  0    /* use 0 for production, 1 for devel., >2 for debug */
 #endif                 /* Anything above 5 is wordy death! */
 static int el_debug = EL_DEBUG;
-/* 
- *     Board-specific info in dev->priv. 
+
+/*
+ *     Board-specific info in dev->priv.
  */
-struct net_local 
+
+struct net_local
 {
     struct enet_statistics stats;
     int tx_pkt_start;          /* The length of the current Tx packet. */
@@ -169,7 +169,7 @@ struct net_local
 /*
  *     Writes to the ax command register.
  */
+
 #define AX_OFF 0x00                    /* Irq off, buffer access on */
 #define AX_SYS  0x40                   /* Load the buffer */
 #define AX_XMIT 0x44                   /* Transmit a packet */
@@ -181,16 +181,16 @@ struct net_local
  *     Normal receive mode written to RX_STATUS.  We must intr on short packets
  *     to avoid bogus rx lockups.
  */
+
 #define RX_NORM 0xA8           /* 0x68 == all addrs, 0xA8 only to me. */
 #define RX_PROM 0x68           /* Senior Prom, uhmm promiscuous mode. */
 #define RX_MULT 0xE8           /* Accept multicast packets. */
 #define TX_NORM 0x0A           /* Interrupt on everything that might hang the chip */
 
 /*
- *     TX_STATUS register. 
+ *     TX_STATUS register.
  */
+
 #define TX_COLLISION 0x02
 #define TX_16COLLISIONS 0x04
 #define TX_READY 0x08
@@ -203,7 +203,7 @@ struct net_local
 /*
  *     The boilerplate probe code.
  */
+
 #ifdef HAVE_DEVLIST
 struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist};
 #else
@@ -218,7 +218,7 @@ int el1_probe(struct device *dev)
        else if (base_addr != 0)        /* Don't probe at all. */
                return ENXIO;
 
-       for (i = 0; netcard_portlist[i]; i++) 
+       for (i = 0; netcard_portlist[i]; i++)
        {
                int ioaddr = netcard_portlist[i];
                if (check_region(ioaddr, EL1_IO_EXTENT))
@@ -232,8 +232,8 @@ int el1_probe(struct device *dev)
 #endif
 
 /*
- *     The actual probe. 
- */ 
+ *     The actual probe.
+ */
 
 static int el1_probe1(struct device *dev, int ioaddr)
 {
@@ -243,25 +243,25 @@ static int el1_probe1(struct device *dev, int ioaddr)
        int i;
 
        /*
-        *      Read the station address PROM data from the special port.  
+        *      Read the station address PROM data from the special port.
         */
-        
-       for (i = 0; i < 6; i++) 
+
+       for (i = 0; i < 6; i++)
        {
                outw(i, ioaddr + EL1_DATAPTR);
                station_addr[i] = inb(ioaddr + EL1_SAPROM);
        }
        /*
         *      Check the first three octets of the S.A. for 3Com's prefix, or
-        *      for the Sager NP943 prefix. 
-        */ 
-        
+        *      for the Sager NP943 prefix.
+        */
+
        if (station_addr[0] == 0x02  &&  station_addr[1] == 0x60
-               && station_addr[2] == 0x8c) 
+               && station_addr[2] == 0x8c)
        {
                mname = "3c501";
        } else if (station_addr[0] == 0x00  &&  station_addr[1] == 0x80
-       && station_addr[2] == 0xC8) 
+       && station_addr[2] == 0xC8)
        {
                mname = "NP943";
        }
@@ -269,17 +269,17 @@ static int el1_probe1(struct device *dev, int ioaddr)
                return ENODEV;
 
        /*
-        *      Grab the region so we can find the another board if autoIRQ fails. 
+        *      Grab the region so we can find the another board if autoIRQ fails.
         */
 
        request_region(ioaddr, EL1_IO_EXTENT,"3c501");
 
-       /*      
+       /*
         *      We auto-IRQ by shutting off the interrupt line and letting it float
         *      high.
         */
 
-       if (dev->irq < 2) 
+       if (dev->irq < 2)
        {
                autoirq_setup(2);
                inb(RX_STATUS);         /* Clear pending interrupts. */
@@ -287,10 +287,10 @@ static int el1_probe1(struct device *dev, int ioaddr)
                outb(AX_LOOP + 1, AX_CMD);
 
                outb(0x00, AX_CMD);
-       
+
                autoirq = autoirq_report(1);
 
-               if (autoirq == 0) 
+               if (autoirq == 0)
                {
                        printk("%s probe at %#x failed to detect IRQ line.\n",
                                mname, ioaddr);
@@ -309,27 +309,27 @@ static int el1_probe1(struct device *dev, int ioaddr)
 
        printk("%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr,
                        autoirq ? "auto":"assigned ", dev->irq);
-          
+
 #ifdef CONFIG_IP_MULTICAST
        printk("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif    
+#endif
 
        if (el_debug)
                printk("%s", version);
 
        /*
-        *      Initialize the device structure. 
+        *      Initialize the device structure.
         */
-        
+
        dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
        if (dev->priv == NULL)
                return -ENOMEM;
        memset(dev->priv, 0, sizeof(struct net_local));
 
        /*
-        *      The EL1-specific entries in the device structure. 
+        *      The EL1-specific entries in the device structure.
         */
-        
+
        dev->open = &el_open;
        dev->hard_start_xmit = &el_start_xmit;
        dev->stop = &el1_close;
@@ -337,7 +337,7 @@ static int el1_probe1(struct device *dev, int ioaddr)
        dev->set_multicast_list = &set_multicast_list;
 
        /*
-        *      Setup the generic properties 
+        *      Setup the generic properties
         */
 
        ether_setup(dev);
@@ -346,9 +346,9 @@ static int el1_probe1(struct device *dev, int ioaddr)
 }
 
 /*
- *     Open/initialize the board. 
+ *     Open/initialize the board.
  */
+
 static int el_open(struct device *dev)
 {
        int ioaddr = dev->base_addr;
@@ -356,7 +356,7 @@ static int el_open(struct device *dev)
        if (el_debug > 2)
                printk("%s: Doing el_open()...", dev->name);
 
-       if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL)) 
+       if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL))
                return -EAGAIN;
 
        irq2dev_map[dev->irq] = dev;
@@ -374,13 +374,13 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
        struct net_local *lp = (struct net_local *)dev->priv;
        int ioaddr = dev->base_addr;
        unsigned long flags;
-       
+
        if(dev->interrupt)              /* May be unloading, don't stamp on */
                return 1;               /* the packet buffer this time      */
 
-       if (dev->tbusy) 
+       if (dev->tbusy)
        {
-               if (jiffies - dev->trans_start < 20) 
+               if (jiffies - dev->trans_start < 20)
                {
                        if (el_debug > 2)
                                printk(" transmitter busy, deferred.\n");
@@ -398,7 +398,7 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
                dev->trans_start = jiffies;
        }
 
-       if (skb == NULL) 
+       if (skb == NULL)
        {
                dev_tint(dev);
                return 0;
@@ -411,13 +411,13 @@ static int el_start_xmit(struct sk_buff *skb, struct device *dev)
         *      mode as the driver assumes tbusy is a faithful indicator of card
         *      state
         */
-        
+
        cli();
-       
+
        /*
-        *      Avoid timer-based retransmission conflicts. 
+        *      Avoid timer-based retransmission conflicts.
         */
-        
+
        if (set_bit(0, (void*)&dev->tbusy) != 0)
        {
                restore_flags(flags);
@@ -436,19 +436,19 @@ load_it_again_sam:
                 *      Command mode with status cleared should [in theory]
                 *      mean no more interrupts can be pending on the card.
                 */
-                
+
 #ifdef BLOCKOUT_1
-               disable_irq(dev->irq);           
-#endif 
+               disable_irq(dev->irq);
+#endif
                outb_p(AX_SYS, AX_CMD);
                inb_p(RX_STATUS);
                inb_p(TX_STATUS);
-       
+
                lp->loading=1;
-       
-               /* 
+
+               /*
                 *      Turn interrupts back on while we spend a pleasant afternoon
-                *      loading bytes into the board 
+                *      loading bytes into the board
                 */
 
                restore_flags(flags);
@@ -456,7 +456,7 @@ load_it_again_sam:
                outw(gp_start, GP_LOW);         /* aim - packet will be loaded into buffer start */
                outsb(DATAPORT,buf,skb->len);   /* load buffer (usual thing each byte increments the pointer) */
                outw(gp_start, GP_LOW);         /* the board reuses the same register */
-#ifndef BLOCKOUT_1             
+#ifndef BLOCKOUT_1
                if(lp->loading==2)              /* A receive upset our load, despite our best efforts */
                {
                        if(el_debug>2)
@@ -466,9 +466,9 @@ load_it_again_sam:
 #endif
                outb(AX_XMIT, AX_CMD);          /* fire ... Trigger xmit.  */
                lp->loading=0;
-#ifdef BLOCKOUT_1              
+#ifdef BLOCKOUT_1
                enable_irq(dev->irq);
-#endif         
+#endif
                dev->trans_start = jiffies;
        }
 
@@ -481,7 +481,7 @@ load_it_again_sam:
 
 /*
  *     The typical workload of the driver:
- *     Handle the ether interface interrupts. 
+ *     Handle the ether interface interrupts.
  */
 
 static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -491,7 +491,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        int ioaddr;
        int axsr;                       /* Aux. status reg. */
 
-       if (dev == NULL  ||  dev->irq != irq) 
+       if (dev == NULL  ||  dev->irq != irq)
        {
                printk ("3c501 driver: irq %d for unknown device.\n", irq);
                return;
@@ -503,7 +503,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /*
         *      What happened ?
         */
-        
+
        axsr = inb(AX_STATUS);
 
        /*
@@ -515,25 +515,25 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        if (dev->interrupt)
                printk("%s: Reentering the interrupt driver!\n", dev->name);
        dev->interrupt = 1;
-#ifndef BLOCKOUT_1    
+#ifndef BLOCKOUT_1
         if(lp->loading==1 && !dev->tbusy)
                printk("%s: Inconsistent state loading while not in tx\n",
                        dev->name);
-#endif                 
+#endif
 #ifdef BLOCKOUT_3
        lp->loading=2;          /* So we can spot loading interruptions */
 #endif
 
-       if (dev->tbusy) 
+       if (dev->tbusy)
        {
-    
+
                /*
                 *      Board in transmit mode. May be loading. If we are
                 *      loading we shouldn't have got this.
                 */
-        
+
                int txsr = inb(TX_STATUS);
-#ifdef BLOCKOUT_2              
+#ifdef BLOCKOUT_2
                if(lp->loading==1)
                {
                        if(el_debug > 2)
@@ -549,7 +549,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (el_debug > 6)
                        printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW));
 
-               if ((axsr & 0x80) && (txsr & TX_READY) == 0) 
+               if ((axsr & 0x80) && (txsr & TX_READY) == 0)
                {
                        /*
                         *      FIXME: is there a logic to whether to keep on trying or
@@ -561,8 +561,8 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
                        dev->tbusy = 0;
                        mark_bh(NET_BH);
-               } 
-               else if (txsr & TX_16COLLISIONS) 
+               }
+               else if (txsr & TX_16COLLISIONS)
                {
                        /*
                         *      Timed out
@@ -572,18 +572,18 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        outb(AX_SYS, AX_CMD);
                        lp->stats.tx_aborted_errors++;
                }
-               else if (txsr & TX_COLLISION) 
-               {       
+               else if (txsr & TX_COLLISION)
+               {
                        /*
-                        *      Retrigger xmit. 
+                        *      Retrigger xmit.
                         */
-                        
+
                        if (el_debug > 6)
                                printk(" retransmitting after a collision.\n");
                        /*
                         *      Poor little chip can't reset its own start pointer
                         */
-                       
+
                        outb(AX_SYS, AX_CMD);
                        outw(lp->tx_pkt_start, GP_LOW);
                        outb(AX_XMIT, AX_CMD);
@@ -613,22 +613,22 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                /*
                 *      In receive mode.
                 */
-        
+
                int rxsr = inb(RX_STATUS);
                if (el_debug > 5)
                        printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
                /*
-                *      Just reading rx_status fixes most errors. 
+                *      Just reading rx_status fixes most errors.
                 */
                if (rxsr & RX_MISSED)
                        lp->stats.rx_missed_errors++;
-               else if (rxsr & RX_RUNT) 
+               else if (rxsr & RX_RUNT)
                {       /* Handled to avoid board lock-up. */
                        lp->stats.rx_length_errors++;
-                       if (el_debug > 5) 
+                       if (el_debug > 5)
                                printk(" runt.\n");
-               } 
-               else if (rxsr & RX_GOOD) 
+               }
+               else if (rxsr & RX_GOOD)
                {
                        /*
                         *      Receive worked.
@@ -650,7 +650,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        }
 
        /*
-        *      Move into receive mode 
+        *      Move into receive mode
         */
 
        outb(AX_RX, AX_CMD);
@@ -664,7 +664,7 @@ static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
 /*
  *     We have a good packet. Well, not really "good", just mostly not broken.
- *     We must check everything to see if it is good. 
+ *     We must check everything to see if it is good.
  */
 
 static void el_receive(struct device *dev)
@@ -679,18 +679,18 @@ static void el_receive(struct device *dev)
        if (el_debug > 4)
                printk(" el_receive %d.\n", pkt_len);
 
-       if ((pkt_len < 60)  ||  (pkt_len > 1536)) 
+       if ((pkt_len < 60)  ||  (pkt_len > 1536))
        {
                if (el_debug)
                        printk("%s: bogus packet, length=%d\n", dev->name, pkt_len);
                lp->stats.rx_over_errors++;
                return;
        }
-    
+
        /*
         *      Command mode so we can empty the buffer
         */
-     
+
        outb(AX_SYS, AX_CMD);
        skb = dev_alloc_skb(pkt_len+2);
 
@@ -699,7 +699,7 @@ static void el_receive(struct device *dev)
         */
 
        outw(0x00, GP_LOW);
-       if (skb == NULL) 
+       if (skb == NULL)
        {
                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
                lp->stats.rx_dropped++;
@@ -711,7 +711,7 @@ static void el_receive(struct device *dev)
                skb->dev = dev;
                /*
                 *      The read increments through the bytes. The interrupt
-                *      handler will fix the pointer when it returns to 
+                *      handler will fix the pointer when it returns to
                 *      receive mode.
                 */
                insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
@@ -735,7 +735,7 @@ static void  el_reset(struct device *dev)
                for (i = 0; i < 6; i++) /* Set the station address. */
                        outb(dev->dev_addr[i], ioaddr + i);
        }
-    
+
        outw(0, RX_BUF_CLR);            /* Set rx packet area to 0. */
        cli();                          /* Avoid glitch on writes to CMD regs */
        outb(TX_NORM, TX_CMD);          /* tx irq on done, collision */
@@ -758,7 +758,7 @@ static int el1_close(struct device *dev)
        dev->start = 0;
 
        /*
-        *      Free and disable the IRQ. 
+        *      Free and disable the IRQ.
         */
 
        free_irq(dev->irq, NULL);
@@ -785,7 +785,7 @@ static void set_multicast_list(struct device *dev)
        int ioaddr = dev->base_addr;
 
        if(dev->flags&IFF_PROMISC)
-       {    
+       {
                outb(RX_PROM, RX_CMD);
                inb(RX_STATUS);
        }
@@ -794,7 +794,7 @@ static void set_multicast_list(struct device *dev)
                outb(RX_MULT, RX_CMD);  /* Multicast or all multicast is the same */
                inb(RX_STATUS);         /* Clear status. */
        }
-       else 
+       else
        {
                outb(RX_NORM, RX_CMD);
                inb(RX_STATUS);
@@ -805,17 +805,19 @@ static void set_multicast_list(struct device *dev)
 
 static char devicename[9] = { 0, };
 
-static struct device dev_3c501 = 
+static struct device dev_3c501 =
 {
        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0x280, 5,
-       0, 0, 0, NULL, el1_probe 
+       0, 0, 0, NULL, el1_probe
 };
 
 static int io=0x280;
 static int irq=5;
-       
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int init_module(void)
 {
        dev_3c501.irq=irq;
@@ -830,18 +832,18 @@ void cleanup_module(void)
        /*
         *      No need to check MOD_IN_USE, as sys_delete_module() checks.
         */
-        
+
        unregister_netdev(&dev_3c501);
 
        /*
-        *      Free up the private structure, or leak memory :-) 
+        *      Free up the private structure, or leak memory :-)
         */
-        
+
        kfree(dev_3c501.priv);
        dev_3c501.priv = NULL;  /* gets re-allocated by el1_probe1 */
 
        /*
-        *      If we don't do this, we can't re-insmod it later. 
+        *      If we don't do this, we can't re-insmod it later.
         */
        release_region(dev_3c501.base_addr, EL1_IO_EXTENT);
 }
index 7c38191e6a56b74fec607af5c0c676574fa76542..d0580f3b46556cafdc4944798344f35895a69dd9 100644 (file)
@@ -19,7 +19,7 @@
     EtherLink II Technical Reference Manual,
     EtherLink II/16 Technical Reference Manual Supplement,
     3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-    
+
     The Crynwr 3c503 packet driver.
 
     Changelog:
@@ -49,7 +49,7 @@ static const char *version =
 
 #include "8390.h"
 #include "3c503.h"
-#define WRD_COUNT 4 
+#define WRD_COUNT 4
 
 int el2_probe(struct device *dev);
 int el2_pio_probe(struct device *dev);
@@ -277,9 +277,9 @@ el2_probe1(struct device *dev, int ioaddr)
     /*
        Divide up the memory on the card. This is the same regardless of
        whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
-       we use the entire 8k of bank1 for an Rx ring. We only use 3k 
+       we use the entire 8k of bank1 for an Rx ring. We only use 3k
        of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
-       (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining 
+       (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
        5kB for an Rx ring.  */
 
     if (wordlength) {
@@ -440,7 +440,7 @@ el2_block_output(struct device *dev, int count,
 
     if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
        outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
-    else 
+    else
        outb(EGACFR_NORM, E33G_GACFR);
 
     if (dev->mem_start) {      /* Shared memory transfer */
@@ -473,7 +473,7 @@ el2_block_output(struct device *dev, int count,
  */
     wrd = (unsigned short int *) buf;
     count  = (count + 1) >> 1;
-    for(;;) 
+    for(;;)
     {
         boguscount = 0x1000;
         while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
@@ -582,14 +582,14 @@ el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off
  *  can read one extra byte without clobbering anything in the kernel because
  *  this would only occur on an odd byte-count and allocation of skb->data
  *  is word-aligned. Variable 'count' is NOT checked. Caller must check
- *  for a valid count. 
+ *  for a valid count.
  *  [This is currently quite safe.... but if one day the 3c503 explodes
  *   you know where to come looking ;)]
  */
 
     buf =  (unsigned short int *) skb->data;
     count =  (count + 1) >> 1;
-    for(;;) 
+    for(;;)
     {
         boguscount = 0x1000;
         while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
@@ -602,7 +602,7 @@ el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off
             }
         }
         if(count > WRD_COUNT)
-        { 
+        {
             insw(E33G_FIFOH, buf, WRD_COUNT);
             buf   += WRD_COUNT;
             count -= WRD_COUNT;
@@ -634,6 +634,9 @@ static struct device dev_el2[MAX_EL2_CARDS] = {
 static int io[MAX_EL2_CARDS] = { 0, };
 static int irq[MAX_EL2_CARDS]  = { 0, };
 static int xcvr[MAX_EL2_CARDS] = { 0, };       /* choose int. or ext. xcvr */
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_EL2_CARDS) "i");
 
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
index fd6f8e99a4d96ed3a1e65a1653cc3d4c3e4ac4ed..975acea327fb7d27af72db56ac7ba7b9985db75a 100644 (file)
@@ -3,7 +3,7 @@
  *      By Craig Southeren, Juha Laiho and Philip Blundell
  *
  * 3c505.c      This module implements an interface to the 3Com
- *              Etherlink Plus (3c505) ethernet card. Linux device 
+ *              Etherlink Plus (3c505) ethernet card. Linux device
  *              driver interface reverse engineered from the Linux 3C509
  *              device drivers. Some 3C505 information gleaned from
  *              the Crynwr packet driver. Still this driver would not
 
 /* This driver may now work with revision 2.x hardware, since all the read
  * operations on the HCR have been removed (we now keep our own softcopy).
- * But I don't have an old card to test it on.  
- * 
+ * But I don't have an old card to test it on.
+ *
  * This has had the bad effect that the autoprobe routine is now a bit
  * less friendly to other devices.  However, it was never very good.
- * before, so I doubt it will hurt anybody.  
+ * before, so I doubt it will hurt anybody.
  */
 
 /* The driver is a mess.  I took Craig's and Juha's code, and hacked it firstly
@@ -378,7 +378,7 @@ static inline void prime_rx(struct device *dev)
 /*****************************************************************
  *
  * send_pcb
- *   Send a PCB to the adapter. 
+ *   Send a PCB to the adapter.
  *
  *     output byte to command reg  --<--+
  *     wait until HCRE is non zero      |
@@ -907,7 +907,7 @@ static int elp_open(struct device *dev)
        dev->interrupt = 0;
 
        /*
-        *  transmitter not busy 
+        *  transmitter not busy
         */
        dev->tbusy = 0;
 
@@ -1362,7 +1362,7 @@ static int elp_sense(struct device *dev)
        if (orig_HSR == 0xff) {
                if (elp_debug > 0)
                        printk(notfound_msg, 1);
-               return -1;      
+               return -1;
        }
        /* Enable interrupts - we need timers! */
        save_flags(flags);
@@ -1594,7 +1594,7 @@ int elplus_probe(struct device *dev)
                        dev->dma = dev->mem_start & 7;
                }
                else {
-                       printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name); 
+                       printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
                        dev->dma = ELP_DMA;
                }
        }
@@ -1669,6 +1669,9 @@ static struct device dev_3c505[ELP_MAX_CARDS] =
 static int io[ELP_MAX_CARDS] = { 0, };
 static int irq[ELP_MAX_CARDS] = { 0, };
 static int dma[ELP_MAX_CARDS] = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
+MODULE_PARM(dma, "1-" __MODULE_STRING(ELP_MAX_CARDS) "i");
 
 int init_module(void)
 {
@@ -1702,7 +1705,7 @@ int init_module(void)
 void cleanup_module(void)
 {
        int this_dev;
-        
+
        for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
                struct device *dev = &dev_3c505[this_dev];
                if (dev->priv != NULL) {
index 60054875bfcb7b45dbcef1f6d22daced9f8a3eea..bfda0499bdd8911c33dcdf7ccb7c5d3c7664f4cd 100644 (file)
@@ -152,15 +152,15 @@ struct net_local {
 
 /*  Since the 3c507 maps the shared memory window so that the last byte is
        at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
-       48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively. 
+       48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
        We can account for this be setting the 'SBC Base' entry in the ISCP table
        below for all the 16 bit offset addresses, and also adding the 'SCB Base'
        value to all 24 bit physical addresses (in the SCP table and the TX and RX
        Buffer Descriptors).
-                                       -Mark   
+                                       -Mark
        */
 #define SCB_BASE               ((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
+
 /*
   What follows in 'init_words[]' is the "program" that is downloaded to the
   82586 memory.         It's mostly tables and command blocks, and starts at the
@@ -200,7 +200,7 @@ struct net_local {
   That's it: only 86 bytes to set up the beast, including every extra
   command available.  The 170 byte buffer at DUMP_DATA is shared between the
   Dump command (called only by the diagnostic program) and the SetMulticastList
-  command. 
+  command.
 
   To complete the memory setup you only have to write the station address at
   SA_OFFSET and create the Tx & Rx buffer lists.
@@ -357,7 +357,7 @@ int el16_probe1(struct device *dev, int ioaddr)
        printk("%s: 3c507 at %#x,", dev->name, ioaddr);
 
        /* We should make a few more checks here, like the first three octets of
-          the S.A. for the manufacturer's code. */ 
+          the S.A. for the manufacturer's code. */
 
        irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
@@ -366,7 +366,7 @@ int el16_probe1(struct device *dev, int ioaddr)
                printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
                return EAGAIN;
        }
-       
+
        /* We've committed to using the board, and can start filling in *dev. */
        request_region(ioaddr, EL16_IO_EXTENT, "3c507");
        dev->base_addr = ioaddr;
@@ -422,7 +422,7 @@ int el16_probe1(struct device *dev, int ioaddr)
        dev->get_stats  = el16_get_stats;
 
        ether_setup(dev);       /* Generic ethernet behaviour */
-       
+
        dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
 
        return 0;
@@ -520,19 +520,19 @@ el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        int ioaddr, status, boguscount = 0;
        ushort ack_cmd = 0;
        ushort *shmem;
-       
+
        if (dev == NULL) {
                printk ("net_interrupt(): irq %d for unknown device.\n", irq);
                return;
        }
        dev->interrupt = 1;
-       
+
        ioaddr = dev->base_addr;
        lp = (struct net_local *)dev->priv;
        shmem = ((ushort*)dev->mem_start);
-       
+
        status = shmem[iSCB_STATUS>>1];
-       
+
        if (net_debug > 4) {
                printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
        }
@@ -661,7 +661,7 @@ init_rx_bufs(struct device *dev)
        unsigned short SCB_base = SCB_BASE;
 
        int cur_rxbuf = lp->rx_head = RX_BUF_START;
-       
+
        /* Initialize each Rx frame + data buffer. */
        do {    /* While there is room for one more. */
 
@@ -678,18 +678,18 @@ init_rx_bufs(struct device *dev)
                *write_ptr++ = 0x0000;
                *write_ptr++ = 0x0000;
                *write_ptr++ = 0x0000;                          /* Pad for protocol. */
-               
+
                *write_ptr++ = 0x0000;                          /* Buffer: Actual count */
                *write_ptr++ = -1;                                      /* Buffer: Next (none). */
                *write_ptr++ = cur_rxbuf + 0x20 + SCB_base;     /* Buffer: Address low */
                *write_ptr++ = 0x0000;
                /* Finally, the number of bytes in the buffer. */
                *write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
-               
+
                lp->rx_tail = cur_rxbuf;
                cur_rxbuf += RX_BUF_SIZE;
        } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-       
+
        /* Terminate the list by setting the EOL bit, and wrap the pointer to make
           the list a ring. */
        write_ptr = (unsigned short *)
@@ -847,13 +847,13 @@ el16_rx(struct device *dev)
                                lp->stats.rx_dropped++;
                                break;
                        }
-                       
+
                        skb_reserve(skb,2);
                        skb->dev = dev;
 
                        /* 'skb->data' points to the start of sk_buff data area. */
                        memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
-               
+
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
                        lp->stats.rx_packets++;
@@ -885,6 +885,8 @@ static struct device dev_3c507 = {
 
 static int io = 0x300;
 static int irq = 0;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
index cad8783939e6a281526b665590568c13f5b82772..9d495711047a7b7180e9183ff8a2df9dedb9e489 100644 (file)
@@ -331,7 +331,7 @@ static ushort id_read_eeprom(int index)
 
        /* Pause for at least 162 us. for the read to take place. */
        udelay (300);
-       
+
        for (bit = 15; bit >= 0; bit--)
                word = (word << 1) + (inb(id_port) & 0x01);
 
@@ -772,6 +772,8 @@ static struct device dev_3c509[MAX_3C_CARDS] = {
 
 static int io[MAX_3C_CARDS] = { 0, };
 static int irq[MAX_3C_CARDS]  = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C_CARDS) "i");
 
 int
 init_module(void)
index b9077ce13064d56758983a06770b91dae2482b9b..8ac249c59348960b4593946595b6796da7a2f85f 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
 net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
 
 
@@ -80,6 +80,10 @@ History:
   $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
 */
 
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -93,11 +97,6 @@ History:
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-#ifdef MODULE
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
-
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -129,9 +128,9 @@ static int shm_table[] = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000};
 
 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12; 
+sizeof(rfd) = 24; sizeof(rbd) = 12;
 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8; 
+sizeof(nop_cmd) = 8;
 
   * if you don't know the driver, better do not change this values: */
 
@@ -251,7 +250,7 @@ elmc_do_reset586( int ioaddr, int ints ) {
 }
 
 /**********************************************
- * close device 
+ * close device
  */
 
 static
@@ -272,7 +271,7 @@ elmc_close(struct device *dev) {
 }
 
 /**********************************************
- * open device 
+ * open device
  */
 
 static
@@ -283,14 +282,14 @@ elmc_open(struct device *dev) {
 
   if(request_irq( dev->irq, &elmc_interrupt, SA_SHIRQ|SA_SAMPLE_RANDOM,
        "3c523", dev )
-  ) {    
+  ) {
     printk( "%s: couldn't get irq %d\n", dev->name, dev->irq );
     elmc_id_reset586();
     return -EAGAIN;
-  }  
+  }
 
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
 
   dev->interrupt = 0;
@@ -305,7 +304,7 @@ elmc_open(struct device *dev) {
 }
 
 /**********************************************
- * Check to see if there's an 82586 out there. 
+ * Check to see if there's an 82586 out there.
  */
 
 static
@@ -320,7 +319,7 @@ check586( struct device *dev, char *where, unsigned size) {
   p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
   memset((char *)p->scp,0, sizeof(struct scp_struct));
   p->scp->sysbus = SYSBUSVAL;        /* 1 = 8Bit-Bus, 0 = 16 Bit */
-  
+
   iscp_addrs[0] = where;
   iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
 
@@ -347,12 +346,12 @@ check586( struct device *dev, char *where, unsigned size) {
 }
 
 /******************************************************************
- * set iscp at the right place, called by elmc_probe and open586. 
+ * set iscp at the right place, called by elmc_probe and open586.
  */
 
 void
 alloc586( struct device *dev ) {
-  struct priv *p =  (struct priv *) dev->priv; 
+  struct priv *p =  (struct priv *) dev->priv;
 
   elmc_id_reset586();
   DELAY(2);
@@ -372,7 +371,7 @@ alloc586( struct device *dev ) {
   elmc_id_reset586();
   elmc_id_attn586();
 
-  DELAY(2); 
+  DELAY(2);
 
   if(p->iscp->busy) {
     printk("%s: Init-Problems (alloc).\n",dev->name);
@@ -424,7 +423,7 @@ elmc_probe(struct device *dev) {
     if( MCA_bus == 0 ) {
        return ENODEV;
     }
-   
+
        /* search through the slots for the 3c523. */
        slot = mca_find_adapter( ELMC_MCA_ID, 0 );
        while( slot != -1 ) {
@@ -468,13 +467,13 @@ elmc_probe(struct device *dev) {
     printk("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
 
     /* Now we extract configuration info from the card.
-       The 3c523 provides information in two of the POS registers, but 
+       The 3c523 provides information in two of the POS registers, but
        the second one is only needed if we want to tell the card what IRQ
        to use.  I suspect that whoever sets the thing up initially would
        prefer we don't screw with those things.
 
        Note we we read the status info when we found the card...
-       
+
        See 3c523.h for more details.
        */
 
@@ -501,13 +500,13 @@ elmc_probe(struct device *dev) {
                mca_write_pos( slot, 3, 0x01 );
                break;
     }
-    
+
     /* Our IO address? */
     dev->base_addr = csr_table[ (status & ELMC_STATUS_CSR_SELECT) >> 1];
 
     request_region( dev->base_addr, ELMC_IO_EXTENT,"3c523");
 
-    dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
+    dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
     if (dev->priv == NULL) {
        return -ENOMEM;
     }
@@ -543,7 +542,7 @@ elmc_probe(struct device *dev) {
        return ENODEV;
   }
   dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-  
+
   ((struct priv *) (dev->priv))->base =  dev->mem_start + size - 0x01000000;
   alloc586(dev);
 
@@ -584,7 +583,7 @@ elmc_probe(struct device *dev) {
   return 0;
 }
 
-/********************************************** 
+/**********************************************
  * init the chip (elmc-interrupt should be disabled?!)
  * needs a correct 'allocated' memory
  */
@@ -625,12 +624,12 @@ init586(struct device *dev) {
        dev->flags|=IFF_PROMISC;
   }
   cfg_cmd->carr_coll  = 0x00;
+
   p->scb->cbl_offset = make16(cfg_cmd);
 
   p->scb->cmd = CUC_START; /* cmd.-unit start */
   elmc_id_attn586();
+
   s = jiffies; /* warning: only active with interrupts on !! */
   while(!(cfg_cmd->cmd_status & STAT_COMPL)) {
     if(jiffies-s > 30) break;
@@ -638,7 +637,7 @@ init586(struct device *dev) {
 
   if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) {
     printk("%s (elmc): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
     /*
@@ -664,11 +663,11 @@ init586(struct device *dev) {
 
   if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
     printk("%s (elmc): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
-   /* 
-    * TDR, wire check .. e.g. no resistor e.t.c 
+   /*
+    * TDR, wire check .. e.g. no resistor e.t.c
     */
   tdr_cmd = (struct tdr_cmd_struct *)ptr;
 
@@ -682,7 +681,7 @@ init586(struct device *dev) {
   p->scb->cmd = CUC_START; /* cmd.-unit start */
   elmc_attn586();
 
-  s = jiffies; 
+  s = jiffies;
   while(!(tdr_cmd->cmd_status & STAT_COMPL)) {
     if(jiffies - s > 30) {
       printk("%s: %d Problems while running the TDR.\n",dev->name,__LINE__);
@@ -711,9 +710,9 @@ init586(struct device *dev) {
       printk("%s: TDR: Unknown status %04x\n",dev->name,result);
     }
   }
-   /* 
-    * ack interrupts 
+
+   /*
+    * ack interrupts
     */
   p->scb->cmd = p->scb->status & STAT_MASK;
   elmc_id_attn586();
@@ -743,12 +742,12 @@ init586(struct device *dev) {
   }
 #endif
 
-  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ 
+  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
 
-  /* 
+  /*
    * Multicast setup
    */
-  
+
   if(dev->mc_count) {
     /* I don't understand this: do we really need memory after the init? */
     int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
@@ -794,7 +793,7 @@ init586(struct device *dev) {
     if((void *)ptr > (void *)p->iscp) {
       printk("%s: not enough shared-mem for your configuration!\n",dev->name);
       return 1;
-    }   
+    }
     memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
     memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
     p->xmit_cmds[i]->cmd_status = STAT_COMPL;
@@ -804,7 +803,7 @@ init586(struct device *dev) {
     p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
   }
 
-  p->xmit_count = 0; 
+  p->xmit_count = 0;
   p->xmit_last  = 0;
 #ifndef NO_NOPCOMMANDS
   p->nop_point  = 0;
@@ -827,7 +826,7 @@ init586(struct device *dev) {
 }
 
 /******************************************************
- * This is a helper routine for elmc_rnr_int() and init586(). 
+ * This is a helper routine for elmc_rnr_int() and init586().
  * It sets up the Receive Frame Area (RFA).
  */
 
@@ -940,7 +939,7 @@ elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) {
         elmc_attn586();
       } else {
         printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
-        elmc_rnr_int(dev); 
+        elmc_rnr_int(dev);
       }
     }
     WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
@@ -1002,7 +1001,7 @@ elmc_rcv_int(struct device *dev) {
 }
 
 /**********************************************************
- * handle 'Receiver went not ready'. 
+ * handle 'Receiver went not ready'.
  */
 
 static
@@ -1014,7 +1013,7 @@ elmc_rnr_int(struct device *dev) {
 
   WAIT_4_SCB_CMD();    /* wait for the last cmd */
   p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
-  elmc_attn586(); 
+  elmc_attn586();
   WAIT_4_SCB_CMD();    /* wait for accept cmd. */
 
   alloc_rfa(dev,(char *)p->rfd_first);
@@ -1058,7 +1057,7 @@ elmc_xmt_int(struct device *dev) {
     } else if(status & TCMD_MAXCOLL) {
       printk("%s: Max. collisions exceeded.\n",dev->name);
       p->stats.collisions += 16;
-    } 
+    }
   }
 
 #if (NUM_XMIT_BUFFS != 1)
@@ -1073,7 +1072,7 @@ elmc_xmt_int(struct device *dev) {
 
 /***********************************************************
  * (re)start the receiver
- */ 
+ */
 
 static
 void
@@ -1088,7 +1087,7 @@ startrecv586(struct device *dev)
 }
 
 /******************************************************
- * send frame 
+ * send frame
  */
 
 static
@@ -1183,7 +1182,7 @@ elmc_send_packet(struct sk_buff *skb, struct device *dev)
     next_nop = (p->nop_point + 1) & 0x1;
     p->xmit_buffs[0]->size = TBD_LAST | len;
 
-    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link
                                 = make16((p->nop_cmds[next_nop]));
     p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
@@ -1199,14 +1198,14 @@ elmc_send_packet(struct sk_buff *skb, struct device *dev)
     }
 
     p->xmit_cmds[p->xmit_count]->cmd_status  = 0;
-    p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
                                           = make16((p->nop_cmds[next_nop]));
     p->nop_cmds[next_nop]->cmd_status = 0;
 
     p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
     dev->trans_start = jiffies;
     p->xmit_count = next_nop;
-  
+
     cli();
     if(p->xmit_count != p->xmit_last) {
       dev->tbusy = 0;
@@ -1219,7 +1218,7 @@ elmc_send_packet(struct sk_buff *skb, struct device *dev)
 }
 
 /*******************************************
- * Someone wanna have the statistics 
+ * Someone wanna have the statistics
  */
 
 static
@@ -1246,7 +1245,7 @@ elmc_get_stats( struct device *dev ) {
 }
 
 /********************************************************
- * Set MC list ..  
+ * Set MC list ..
  */
 
 static
@@ -1259,7 +1258,7 @@ set_multicast_list(struct device *dev) {
 
   dev->start = 0;
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   dev->start = 1;
 }
@@ -1267,13 +1266,13 @@ set_multicast_list(struct device *dev) {
 /*************************************************************************/
 
 #ifdef MODULE
-char kernel_version[] = UTS_RELEASE;
 static struct device dev_elmc = {
        "        " /*"3c523"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe };
-       
 
-int irq=0;
-int io=0;
+static int irq=0;
+static int io=0;
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
 
 int
 init_module(void) {
index 0337bab78a8f9af5446bcea468cca9687d95d804..f70570ddf44d4159251b65dcdbf1246a3b27be3c 100644 (file)
@@ -137,7 +137,7 @@ static int ac_probe1(int ioaddr, struct device *dev)
        for (i = 0; i < 4; i++)
                if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
                        printk("EISA ID mismatch, %8x vs %8x.\n",
-                                  inl(ioaddr + AC_ID_PORT), AC_EISA_ID); 
+                                  inl(ioaddr + AC_ID_PORT), AC_EISA_ID);
                        return ENODEV;
                }
 
@@ -329,6 +329,9 @@ static struct device dev_ac32[MAX_AC32_CARDS] = {
 static int io[MAX_AC32_CARDS] = { 0, };
 static int irq[MAX_AC32_CARDS]  = { 0, };
 static int mem[MAX_AC32_CARDS] = { 0, };
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
 
 int
 init_module(void)
index 023c310e7bf4b6c46a7d9fb517ea4860f8afb523..ad8738fc10530ff6c03b98e6c4608409ff7281ac 100644 (file)
@@ -5,8 +5,8 @@
        This driver is for the Apricot 82596 bus-master interface
 
         Modularised 12/94 Mark Evans
-    
-    Driver skeleton 
+
+    Driver skeleton
        Written 1993 by Donald Becker.
        Copyright 1993 United States Government as represented by the Director,
        National Security Agency.  This software may only be used and distributed
@@ -15,7 +15,7 @@
 
        The author may be reached as becker@super.org or
        C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
-    
+
 
 */
 
@@ -112,7 +112,7 @@ struct i596_rfd {
     unsigned short stat;
     unsigned short cmd;
     struct i596_rfd *next;
-    long rbd; 
+    long rbd;
     unsigned short count;
     unsigned short size;
     char data[1532];
@@ -177,7 +177,7 @@ char init_setup[] = {
        0x00,   /* promiscuous mode */
        0x00,   /* collision detect */
        0x40,   /* minimum frame length */
-       0xff,   
+       0xff,
        0x00,
        0x7f    /*  *multi IA */ };
 
@@ -348,7 +348,7 @@ i596_rx(struct device *dev)
                break;
            }
 
-           skb->dev = dev;             
+           skb->dev = dev;
            memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
 
            skb->protocol=eth_type_trans(skb,dev);
@@ -496,7 +496,7 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
     cli();
     if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
        lp->cmd_tail->next = cmd;
-    else 
+    else
     {
        lp->cmd_head = cmd;
        while (lp->scb.status, lp->scb.command)
@@ -517,7 +517,7 @@ static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
     lp->cmd_head = lp->scb.cmd;
     restore_flags(flags);
 
-    if (lp->cmd_backlog > 16) 
+    if (lp->cmd_backlog > 16)
     {
        int tickssofar = jiffies - lp->last_cmd;
 
@@ -682,7 +682,7 @@ int apricot_probe(struct device *dev)
     int checksum = 0;
     int ioaddr = 0x300;
     char eth_addr[6];
-    
+
     /* this is easy the ethernet interface can only be at 0x300 */
     /* first check nothing is already registered here */
 
@@ -703,7 +703,7 @@ int apricot_probe(struct device *dev)
 
     /* Some other boards trip the checksum.. but then appear as ether
        address 0. Trap these - AC */
-       
+
     if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
        return ENODEV;
 
@@ -953,7 +953,7 @@ i596_get_stats(struct device *dev)
 /*
  *     Set or clear the multicast filter for this adaptor.
  */
+
 static void set_multicast_list(struct device *dev)
 {
        struct i596_private *lp = (struct i596_private *)dev->priv;
@@ -962,7 +962,7 @@ static void set_multicast_list(struct device *dev)
        if (i596_debug > 1)
                printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
 
-       if (dev->mc_count > 0) 
+       if (dev->mc_count > 0)
        {
                struct dev_mc_list *dmi;
                char *cp;
@@ -985,7 +985,7 @@ static void set_multicast_list(struct device *dev)
        }
        else
        {
-               if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL) 
+               if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL)
                        return;
                if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
                {
@@ -1002,7 +1002,7 @@ static void set_multicast_list(struct device *dev)
 
 #ifdef HAVE_DEVLIST
 static unsigned int apricot_portlist[] = {0x300, 0};
-struct netdev_entry apricot_drv = 
+struct netdev_entry apricot_drv =
 {"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
 #endif
 
@@ -1016,6 +1016,7 @@ static struct device dev_apricot = {
 
 static int io = 0x300;
 static int irq = 10;
+MODULE_PARM(irq, "i");
 
 int
 init_module(void)
index 6908a14aa261a6e4974cfbec84d698ed43699c5d..40a1c96f2990ef5ac63d57f9be70f6f1aa98d541 100644 (file)
@@ -4,9 +4,9 @@
 
        Contact Avery at: apenwarr@foxnet.net or
        RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-       
+
        **********************
-       
+
        The original copyright was as follows:
 
        skeleton.c Written 1993 by Donald Becker.
@@ -14,9 +14,9 @@
         Director, National Security Agency.  This software may only be used
         and distributed according to the terms of the GNU Public License as
         modified by SRC, incorporated herein by reference.
-         
+
        **********************
-       
+
        v2.60 ALPHA (96/11/23)
          - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz>
            and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work
        The following has been SUMMARIZED.  The complete ChangeLog is
        available in the full Linux-ARCnet package at
                http://www.foxnet.net/~apenwarr/arcnet
-               
+
        v2.50 (96/02/24)
          - Massively improved autoprobe routines; they now work even as a
            module.  Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
            for his ideas and help in this area.
          - Changed printk's around quite a lot.
-       
+
        v2.22 (95/12/08)
          - Major cleanups, speedups, and better code-sharing.
          - Eliminated/changed many useless/meaningless/scary debug messages
@@ -73,7 +73,7 @@
            send "Ethernet-Encapsulation" packets, which are compatible with
            Windows for Workgroups and LAN Manager, and possibly other
            software.  See the README for more information.
-         
+
        v1.02 (95/06/21)
           - A fix to make "exception" packets sent from Linux receivable
            on other systems.  (The protocol_id byte was sometimes being set
          - Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski
             <motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work
             with dosemu!)
-            
+
        v1.00 (95/02/15)
          - Initial non-alpha release.
-       
-       
+
+
        TO DO: (semi-prioritized)
-       
+
          - Use cleaner "architecture-independent" shared memory access.
            This is half-done in ARCnet 2.60, but still uses some
            undocumented i386 stuff.  (We shouldn't call phys_to_virt,
          - Try to implement promiscuous (receive-all-packets) mode available
            on some newer cards with COM20020 and similar chips.  I don't have
            one, but SMC sent me the specs.
-         - ATA protocol support?? 
+         - ATA protocol support??
          - VINES TCP/IP encapsulation?? (info needed)
 
-           
+
        Sources:
         - Crynwr arcnet.com/arcether.com packet drivers.
         - arcnet.c v0.00 dated 1/1/94 and apparently by
 static const char *version =
  "arcnet.c: v2.60 96/11/23 Avery Pennarun <apenwarr@foxnet.net>\n";
 
+
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -178,7 +178,7 @@ static const char *version =
  */
 #undef RIM_I_MODE
 
-/* Normally, the ARCnet device needs to be assigned a name (default arc0). 
+/* Normally, the ARCnet device needs to be assigned a name (default arc0).
  * Ethernet devices have a function to automatically try eth0, eth1, etc
  * until a free name is found.  To name the ARCnet device using an "eth?"
  * device name, define this option.
@@ -206,9 +206,9 @@ static const char *version =
  * usually happens when a new computer on the network is powered on or when
  * the cable is broken.
  *
- * Define DETECT_RECONFIGS if you want to detect network reconfigurations. 
+ * Define DETECT_RECONFIGS if you want to detect network reconfigurations.
  * Recons may be a real nuisance on a larger ARCnet network; if you are a
- * network administrator you probably would like to count them. 
+ * network administrator you probably would like to count them.
  * Reconfigurations will be recorded in stats.tx_carrier_errors (the last
  * field of the /proc/net/dev file).
  *
@@ -317,7 +317,7 @@ int arcnet_debug = ARCNET_DEBUG;
  * results in the cleanest mess possible.
  */
 #define ADEV lp->adev
+
 #ifdef CONFIG_ARCNET_ETH
  #define EDEV lp->edev
 #else
@@ -481,7 +481,7 @@ struct ClientData
         */
        u_char  saddr,          /* Source address - needed for IPX */
                daddr;          /* Destination address */
-       
+
        /* data that IS part of real packet */
        u_char  protocol_id,    /* ARC_P_IP, ARC_P_ARP, etc */
                split_flag;     /* for use with split packets */
@@ -502,7 +502,7 @@ struct S_ClientData
        u_char  saddr,          /* Source address - needed for IPX */
                daddr,          /* Destination address */
                junk;           /* padding to make an even length */
-       
+
        /* data that IS part of real packet */
        u_char  protocol_id;    /* ARC_P_IP, ARC_P_ARP, etc */
 };
@@ -554,11 +554,11 @@ struct arcnet_local {
        int num_recons,         /* number of RECONs between first and last. */
            network_down;       /* do we think the network is down? */
 #endif
-       
+
        struct timer_list timer; /* the timer interrupt struct */
        struct Incoming incoming[256];  /* one from each address */
        struct Outgoing outgoing; /* packet currently being sent */
-       
+
        struct device *adev;    /* RFC1201 protocol device */
 
 #ifdef CONFIG_ARCNET_ETH
@@ -655,13 +655,13 @@ void cleanup_module(void);
  ****************************************************************************/
 
 /* Dump the contents of an sk_buff
- */ 
+ */
 #if ARCNET_DEBUG_MAX & D_SKB
 void arcnet_dump_skb(struct device *dev,struct sk_buff *skb,char *desc)
 {
        int i;
        long flags;
-       
+
        save_flags(flags);
        cli();
        printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc);
@@ -683,7 +683,7 @@ void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc)
 {
        int i;
        long flags;
-       
+
        save_flags(flags);
        cli();
        printk(KERN_DEBUG "%6s: packet dump (%s) follows:",dev->name,desc);
@@ -696,7 +696,7 @@ void arcnet_dump_packet(struct device *dev,u_char *buffer,int ext,char *desc)
        printk("\n");
        restore_flags(flags);
 }
-#endif 
+#endif
 
 /****************************************************************************
  *                                                                          *
@@ -717,21 +717,21 @@ int arcnet_probe(struct device *dev)
        BUGMSG(D_NORMAL,"Compiled for ARCnet RIM I (autoprobe disabled)\n");
        BUGMSG(D_NORMAL,"Given: node %02lXh, shmem %lXh, irq %d\n",
                dev->base_addr,dev->mem_start,dev->irq);
-       
+
        if (dev->mem_start<=0 || dev->irq<=0)
        {
                BUGMSG(D_NORMAL,"No autoprobe for RIM I; you "
                        "must specify the shmem and irq!\n");
                return -ENODEV;
        }
-       
+
        if (dev->base_addr<=0 || dev->base_addr>255)
        {
                BUGMSG(D_NORMAL,"You need to specify your card's station "
                        "ID!\n");
                return -ENODEV;
        }
-       
+
        return arcnet_found(dev,dev->base_addr,dev->irq,dev->mem_start);
 }
 
@@ -762,7 +762,7 @@ int arcnet_probe(struct device *dev)
        unsigned long airqmask;
        int *port;
        u_long *shmem;
-       
+
        if (!init_once)
        {
                for (count=0x200; count<=0x3f0; count+=16)
@@ -778,7 +778,7 @@ int arcnet_probe(struct device *dev)
                sizeof(ports),sizeof(shmems),
                sizeof(ports)+sizeof(shmems));
 
-       
+
 #if 1
        BUGLVL(D_EXTRA)
        {
@@ -801,13 +801,13 @@ int arcnet_probe(struct device *dev)
        }
        else if (dev->base_addr > 0)    /* Don't probe at all. */
                return -ENXIO;
-               
+
        if (dev->mem_start)
        {
                shmems[0]=dev->mem_start;
                numshmems=1;
        }
-       
+
 
        /* Stage 1: abandon any reserved ports, or ones with status==0xFF
         * (empty), and reset any others by reading the reset port.
@@ -824,9 +824,9 @@ int arcnet_probe(struct device *dev)
                        numprint=1;
                }
                BUGMSG2(D_INIT,"%Xh ",*port);
-               
+
                ioaddr=*port;
-               
+
                if (check_region(*port, ARCNET_TOTAL_SIZE))
                {
                        BUGMSG2(D_INIT_REASONS,"(check_region)\n");
@@ -837,7 +837,7 @@ int arcnet_probe(struct device *dev)
                        port--;
                        continue;
                }
-               
+
                if (ARCSTATUS == 0xFF)
                {
                        BUGMSG2(D_INIT_REASONS,"(empty)\n");
@@ -848,7 +848,7 @@ int arcnet_probe(struct device *dev)
                        port--;
                        continue;
                }
-               
+
                ARCRESET;       /* begin resetting card */
 
                BUGMSG2(D_INIT_REASONS,"\n");
@@ -856,13 +856,13 @@ int arcnet_probe(struct device *dev)
                BUGLVL(D_INIT_REASONS) numprint=0;
        }
        BUGMSG2(D_INIT,"\n");
-       
+
        if (!numports)
        {
                BUGMSG(D_NORMAL,"Stage 1: No ARCnet cards found.\n");
                return -ENODEV;
        }
-       
+
 
        /* Stage 2: we have now reset any possible ARCnet cards, so we can't
         * do anything until they finish.  If D_INIT, print the list of
@@ -883,7 +883,7 @@ int arcnet_probe(struct device *dev)
        }
        BUGMSG2(D_INIT,"\n");
        JIFFER(RESETtime);
-       
+
 
        /* Stage 3: abandon any shmem addresses that don't have the signature
         * 0xD1 byte in the right place, or are read-only.
@@ -902,9 +902,9 @@ int arcnet_probe(struct device *dev)
                        numprint=1;
                }
                BUGMSG2(D_INIT,"%lXh ",*shmem);
-               
+
                ptr=(u_long)(*shmem);
-               
+
                if (readb(ptr) != TESTvalue)
                {
                        BUGMSG2(D_INIT_REASONS,"(mem=%02Xh, not %02Xh)\n",
@@ -916,7 +916,7 @@ int arcnet_probe(struct device *dev)
                        shmem--;
                        continue;
                }
-               
+
                /* By writing 0x42 to the TESTvalue location, we also make
                 * sure no "mirror" shmem areas show up - if they occur
                 * in another pass through this loop, they will be discarded
@@ -932,7 +932,7 @@ int arcnet_probe(struct device *dev)
                        shmem--;
                        continue;
                }
-               
+
                BUGMSG2(D_INIT_REASONS,"\n");
                BUGMSG(D_INIT_REASONS,"Stage 3: ");
                BUGLVL(D_INIT_REASONS) numprint=0;
@@ -962,7 +962,7 @@ int arcnet_probe(struct device *dev)
                BUGMSG2(D_INIT,"%lXh ",*shmem);
        }
        BUGMSG2(D_INIT,"\n");
-       
+
 
        /* Stage 5: for any ports that have the correct status, can disable
         * the RESET flag, and (if no irq is given) generate an autoirq,
@@ -983,10 +983,10 @@ int arcnet_probe(struct device *dev)
                        numprint=1;
                }
                BUGMSG2(D_INIT,"%Xh ",*port);
-               
+
                ioaddr=*port;
                status=ARCSTATUS;
-               
+
                if ((status & 0x9D)
                        != (NORXflag|RECONflag|TXFREEflag|RESETflag))
                {
@@ -1027,7 +1027,7 @@ int arcnet_probe(struct device *dev)
                        udelay(1);
                        AINTMASK(0);
                        airq = probe_irq_off(airqmask);
-       
+
                        if (airq<=0)
                        {
                                BUGMSG2(D_INIT_REASONS,"(airq=%d)\n",airq);
@@ -1043,10 +1043,10 @@ int arcnet_probe(struct device *dev)
                {
                        airq=dev->irq;
                }
-               
+
                BUGMSG2(D_INIT,"(%d,", airq);
                openparen=1;
-               
+
                /* Everything seems okay.  But which shmem, if any, puts
                 * back its signature byte when the card is reset?
                 *
@@ -1074,7 +1074,7 @@ int arcnet_probe(struct device *dev)
                {
                        u_long ptr;
                        ptr=(u_long)(*shmem);
-                       
+
                        if (readb(ptr) == TESTvalue)    /* found one */
                        {
                                BUGMSG2(D_INIT,"%lXh)\n", *shmem);
@@ -1087,7 +1087,7 @@ int arcnet_probe(struct device *dev)
                                /* remove shmem from the list */
                                *shmem=shmems[numshmems-1];
                                numshmems--;
-                               
+
                                break;
                        }
                        else
@@ -1115,7 +1115,7 @@ int arcnet_probe(struct device *dev)
         */
        for (shmem = &shmems[0]; shmem-shmems<numshmems; shmem++)
                writeb(TESTvalue,*shmem);
-               
+
        if (retval) BUGMSG(D_NORMAL,"Stage 5: No ARCnet cards found.\n");
        return retval;
 }
@@ -1131,7 +1131,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
        u_long first_mirror,last_mirror;
        struct arcnet_local *lp;
        int mirror_size;
-       
+
        /* reserve the irq */
        if (request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL))
        {
@@ -1150,9 +1150,9 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
        request_region(port,ARCNET_TOTAL_SIZE,"arcnet");
        dev->base_addr=port;
 #endif
-       
+
        /* find the real shared memory start/end points, including mirrors */
-       
+
        #define BUFFER_SIZE (512)
        #define MIRROR_SIZE (BUFFER_SIZE*4)
 
@@ -1165,7 +1165,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
            && readb(shmem-mirror_size)!=TESTvalue
            && readb(shmem-2*mirror_size)==TESTvalue)
                mirror_size*=2;
-       
+
        first_mirror=last_mirror=shmem;
        while (readb(first_mirror)==TESTvalue) first_mirror-=mirror_size;
        first_mirror+=mirror_size;
@@ -1177,9 +1177,9 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
        dev->mem_end=last_mirror+MIRROR_SIZE-1;
        dev->rmem_start=dev->mem_start+BUFFER_SIZE*0;
        dev->rmem_end=dev->mem_start+BUFFER_SIZE*2-1;
-        
+
        /* Initialize the rest of the device structure. */
-       
+
        dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
        if (dev->priv == NULL)
        {
@@ -1190,7 +1190,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
        }
        memset(dev->priv,0,sizeof(struct arcnet_local));
        lp=(struct arcnet_local *)(dev->priv);
-       
+
        dev->open=arcnet_open;
        dev->stop=arcnet_close;
        dev->hard_start_xmit=arcnetA_send_packet;
@@ -1201,7 +1201,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
         * values.
         */
        arcnet_setup(dev);
-       
+
        /* And now fill particular fields with arcnet values */
        dev->mtu=1500; /* completely arbitrary - agrees with ether, though */
        dev->hard_header_len=sizeof(struct ClientData);
@@ -1230,7 +1230,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem)
                lp->stationid,
                dev->base_addr,dev->irq,dev->mem_start,
                (dev->mem_end-dev->mem_start+1)/mirror_size,mirror_size);
-               
+
        return 0;
 }
 
@@ -1247,11 +1247,11 @@ int arcnet_reset(struct device *dev,int reset_delay)
        struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
        short ioaddr=IOADDR;
        int delayval,recbuf=lp->recbuf;
-       
+
        /* no IRQ's, please! */
        lp->intmask=0;
        SETMASK;
-       
+
        BUGMSG(D_INIT,"Resetting %s (status=%Xh)\n",
                        dev->name,ARCSTATUS);
 
@@ -1271,7 +1271,7 @@ int arcnet_reset(struct device *dev,int reset_delay)
                BUGMSG(D_NORMAL,"reset failed: TESTvalue not present.\n");
                return 1;
        }
-       
+
        /* clear out status variables */
        recbuf=lp->recbuf=0;
        lp->txbuf=2;
@@ -1284,7 +1284,7 @@ int arcnet_reset(struct device *dev,int reset_delay)
        BUGLVL(D_DURING)
                memset_io(dev->mem_start,0x42,2048);
 #endif
-       
+
        /* and enable receive of our first packet to the first buffer */
        EnableReceiver();
 
@@ -1294,7 +1294,7 @@ int arcnet_reset(struct device *dev,int reset_delay)
        lp->intmask|=RECONflag;
 #endif
        SETMASK;
-       
+
        /* done!  return success. */
        return 0;
 }
@@ -1336,7 +1336,7 @@ void arcnet_setup(struct device *dev)
  * Open and close the driver                                                *
  *                                                                          *
  ****************************************************************************/
+
 
 /* Open/initialize the board.  This is called sometime after booting when
  * the 'ifconfig' program is run.
@@ -1350,7 +1350,7 @@ arcnet_open(struct device *dev)
 {
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        int ioaddr=IOADDR;
-       
+
        if (dev->metric>=1000)
        {
                arcnet_debug=dev->metric-1000;
@@ -1359,7 +1359,7 @@ arcnet_open(struct device *dev)
        }
 
        BUGMSG(D_INIT,"arcnet_open: resetting card.\n");
-       
+
 #ifdef FAST_IFCONFIG
        /* try to put the card in a defined state - if it fails the first
         * time, actually reset it.
@@ -1372,17 +1372,17 @@ arcnet_open(struct device *dev)
        if (arcnet_reset(dev,1) && arcnet_reset(dev,1))
                return -ENODEV;
 #endif
-       
+
        dev->tbusy=0;
        dev->interrupt=0;
        lp->intx=0;
        lp->in_txhandler=0;
-       
+
        /* The RFC1201 driver is the default - just store */
        lp->adev=dev;
        BUGMSG(D_NORMAL,"ARCnet RFC1201 protocol initialized.\n");
 
-#ifdef CONFIG_ARCNET_ETH       
+#ifdef CONFIG_ARCNET_ETH
        /* Initialize the ethernet-encap protocol driver */
        lp->edev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL);
        if (lp->edev == NULL)
@@ -1415,7 +1415,7 @@ arcnet_open(struct device *dev)
 
        /* we're started */
        START=1;
-       
+
        /* make sure we're ready to receive IRQ's.
         * arcnet_reset sets this for us, but if we receive one before
         * START is set to 1, it could be ignored.  So, we turn IRQ's
@@ -1427,7 +1427,7 @@ arcnet_open(struct device *dev)
                         * necessary)
                         */
        SETMASK;
-       
+
        MOD_INC_USE_COUNT;
        return 0;
 }
@@ -1440,7 +1440,7 @@ arcnet_close(struct device *dev)
 {
        int ioaddr=IOADDR;
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
-       
+
        TBUSY=1;
        START=0;
 
@@ -1456,10 +1456,10 @@ arcnet_close(struct device *dev)
 
        /* reset more flags */
        INTERRUPT=0;
-       
+
        /* do NOT free lp->adev!!  It's static! */
        lp->adev=NULL;
-       
+
 #ifdef CONFIG_ARCNET_ETH
        /* free the ethernet-encap protocol device */
        lp->edev->priv=NULL;
@@ -1501,10 +1501,10 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
 {
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        int ioaddr=IOADDR;
-       
+
        BUGMSG(D_DURING,"transmit requested (status=%Xh, inTX=%d)\n",
                        ARCSTATUS,lp->intx);
-                       
+
        if (lp->in_txhandler)
        {
                BUGMSG(D_NORMAL,"send_packet called while in txhandler!\n");
@@ -1526,8 +1526,8 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
                int tickssofar = jiffies - dev->trans_start;
                /*int recbuf=lp->recbuf;*/
                int status=ARCSTATUS;
-               
-               if (tickssofar < TX_TIMEOUT) 
+
+               if (tickssofar < TX_TIMEOUT)
                {
                        BUGMSG(D_DURING,"premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n",
                                        status,tickssofar,lp->outgoing.skb,
@@ -1538,7 +1538,7 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
 
                lp->intmask &= ~TXFREEflag;
                SETMASK;
-               
+
                if (status&TXFREEflag)  /* transmit _DID_ finish */
                {
                        BUGMSG(D_NORMAL,"tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n",
@@ -1561,7 +1561,7 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
                        lp->stats.tx_dropped++;
                }
                lp->outgoing.skb=NULL;
-               
+
                TBUSY=0;
                lp->txready=0;
                lp->sending=0;
@@ -1579,7 +1579,7 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
                dev_tint(dev);
                return 0;
        }
-       
+
        if (lp->txready)        /* transmit already in progress! */
        {
                BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n",
@@ -1591,7 +1591,7 @@ arcnet_send_packet_bad(struct sk_buff *skb, struct device *dev)
                lp->stats.tx_errors++;
                lp->stats.tx_fifo_errors++;
                lp->txready=0;  /* we definitely need this line! */
-               
+
                return 1;
        }
 
@@ -1620,24 +1620,24 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
        struct Outgoing *out=&(lp->outgoing);
 
        lp->intx++;
-       
+
        bad=arcnet_send_packet_bad(skb,dev);
        if (bad)
        {
                lp->intx--;
                return bad;
        }
-       
+
        TBUSY=1;
-       
+
        out->length = 1 < skb->len ? skb->len : 1;
        out->hdr=(struct ClientData*)skb->data;
        out->skb=skb;
-               
+
        BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx");
 
        out->hdr->sequence=(lp->sequence++);
-       
+
        /* fits in one packet? */
        if (out->length-EXTRA_CLIENTDATA<=XMTU)
        {
@@ -1658,7 +1658,7 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
                /* done right away */
                dev_kfree_skb(out->skb,FREE_WRITE);
                out->skb=NULL;
-                                       
+
                if (arcnet_go_tx(dev,1))
                {
                        /* inform upper layers */
@@ -1675,7 +1675,7 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
                out->dataleft=out->length-sizeof(struct ClientData);
                out->numsegs=(out->dataleft+maxsegsize-1)/maxsegsize;
                out->segnum=0;
-               
+
                BUGMSG(D_TX,"packet (%d bytes) split into %d fragments:\n",
                        out->length,out->numsegs);
 
@@ -1694,7 +1694,7 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
                                arcnet_go_tx(dev,1);
                        }
                }
-               
+
                /* if segnum==numsegs, the transmission is finished;
                 * free the skb right away.
                 */
@@ -1710,7 +1710,7 @@ arcnetA_send_packet(struct sk_buff *skb, struct device *dev)
 
        dev->trans_start=jiffies;
        lp->intx--;
-       
+
        /* make sure we didn't ignore a TX IRQ while we were in here */
        lp->intmask |= TXFREEflag;
        SETMASK;
@@ -1728,16 +1728,16 @@ static void arcnetA_continue_tx(struct device *dev)
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        int ioaddr=IOADDR,maxsegsize=XMTU-4;
        struct Outgoing *out=&(lp->outgoing);
-       
+
        BUGMSG(D_DURING,"continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n",
                ARCSTATUS,lp->intx,lp->in_txhandler,lp->intmask);
-       
+
        if (lp->txready)
        {
                BUGMSG(D_NORMAL,"continue_tx: called with packet in buffer!\n");
                return;
        }
-       
+
        if (out->segnum>=out->numsegs)
        {
                BUGMSG(D_NORMAL,"continue_tx: building segment %d of %d!\n",
@@ -1751,7 +1751,7 @@ static void arcnetA_continue_tx(struct device *dev)
 
        out->seglen=maxsegsize;
        if (out->seglen>out->dataleft) out->seglen=out->dataleft;
-                       
+
        BUGMSG(D_TX,"building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n",
                out->segnum+1,out->seglen,out->numsegs,
                out->length,out->hdr->split_flag);
@@ -1759,7 +1759,7 @@ static void arcnetA_continue_tx(struct device *dev)
        arcnetAS_prepare_tx(dev,((char *)out->hdr)+EXTRA_CLIENTDATA,
                sizeof(struct ClientData)-EXTRA_CLIENTDATA,
                out->data,out->seglen,out->hdr->daddr,1);
-               
+
        out->dataleft-=out->seglen;
        out->data+=out->seglen;
        out->segnum++;
@@ -1775,16 +1775,16 @@ arcnetAS_prepare_tx(struct device *dev,u_char *hdr,int hdrlen,
 {
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        struct ClientData *arcsoft;
-       union ArcPacket *arcpacket = 
+       union ArcPacket *arcpacket =
                (union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
        int offset;
-       
+
 #ifdef SLOW_XMIT_COPY
        char *iptr,*iend,*optr;
 #endif
-       
+
        lp->txbuf=lp->txbuf^1;  /* XOR with 1 to alternate between 2 and 3 */
-       
+
        length+=hdrlen;
 
        BUGMSG(D_TX,"arcnetAS_prep_tx: hdr:%ph, length:%d, data:%ph\n",
@@ -1809,7 +1809,7 @@ arcnetAS_prepare_tx(struct device *dev,u_char *hdr,int hdrlen,
        {
                arcpacket->hardheader.offset1=0;
                arcpacket->hardheader.offset2=offset=512-length;
-               
+
                arcsoft=(struct ClientData *)
                        (&arcpacket->raw[offset]);
        }
@@ -1819,7 +1819,7 @@ arcnetAS_prepare_tx(struct device *dev,u_char *hdr,int hdrlen,
                arcpacket->hardheader.offset2=offset=512-length-4;
                arcsoft=(struct ClientData *)
                        (&arcpacket->raw[offset+4]);
-               
+
                /* exception-specific stuff - these four bytes
                 * make the packet long enough to fit in a 512-byte
                 * frame.
@@ -1857,10 +1857,10 @@ arcnetAS_prepare_tx(struct device *dev,u_char *hdr,int hdrlen,
        memcpy((u_char*)arcsoft+hdrlen,
                data,length-hdrlen);
 #endif
-               
+
        BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
                        daddr,length);
-                       
+
        BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>MTU,"tx");
        lp->lastload_dest=daddr;
        lp->txready=lp->txbuf;  /* packet is ready for sending */
@@ -1894,7 +1894,7 @@ arcnet_go_tx(struct device *dev,int enable_irq)
                }
                return 0;
        }
-       
+
        /* start sending */
        ACOMMAND(TXcmd|(lp->txready<<3));
 
@@ -1930,14 +1930,14 @@ arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs)
 {
        struct device *dev = (struct device *)(irq2dev_map[irq]);
        int ioaddr;
-       
+
        if (dev==NULL)
        {
                BUGLVL(D_DURING)
                        printk(KERN_DEBUG "arcnet: irq %d for unknown device.\n", irq);
                return;
        }
-       
+
        BUGMSG(D_DURING,"in arcnet_interrupt\n");
 
        /* RESET flag was enabled - if !dev->start, we must clear it right
@@ -1961,7 +1961,7 @@ arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs)
  */
 static void
 arcnet_inthandler(struct device *dev)
-{      
+{
        struct arcnet_local *lp=(struct arcnet_local *)dev->priv;
        int ioaddr=IOADDR, status, boguscount = 3, didsomething;
 
@@ -1970,7 +1970,7 @@ arcnet_inthandler(struct device *dev)
                BUGMSG(D_NORMAL,"DRIVER PROBLEM!  Nested arcnet interrupts!\n");
                return; /* don't even try. */
        }
-       
+
        AINTMASK(0);
        INTERRUPT = 1;
 
@@ -1981,7 +1981,7 @@ arcnet_inthandler(struct device *dev)
        {
                status = ARCSTATUS;
                didsomething=0;
-       
+
 
                /* RESET flag was enabled - card is resetting and if RX
                 * is disabled, it's NOT because we just got a packet.
@@ -1991,12 +1991,12 @@ arcnet_inthandler(struct device *dev)
                        BUGMSG(D_NORMAL,"spurious reset (status=%Xh)\n",
                                        status);
                        arcnet_reset(dev,0);
-                       
+
                        /* all other flag values are just garbage */
                        break;
                }
-               
-               
+
+
                /* RX is inhibited - we must have received something. */
                if (status & lp->intmask & NORXflag)
                {
@@ -2012,14 +2012,14 @@ arcnet_inthandler(struct device *dev)
                        arcnet_rx(dev,!recbuf);
                        didsomething++;
                }
-               
+
                /* it can only be an xmit-done irq if we're xmitting :) */
                /*if (status&TXFREEflag && !lp->in_txhandler && lp->sending)*/
                if (status & lp->intmask & TXFREEflag)
                {
                        struct Outgoing *out=&(lp->outgoing);
                        int was_sending=lp->sending;
-                       
+
                        lp->intmask &= ~TXFREEflag;
 
                        lp->in_txhandler++;
@@ -2027,7 +2027,7 @@ arcnet_inthandler(struct device *dev)
 
                        BUGMSG(D_DURING,"TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)\n",
                                        status,out->numsegs,out->segnum,out->skb);
-                                       
+
                        if (was_sending && !(status&TXACKflag))
                        {
                                if (lp->lasttrans_dest != 0)
@@ -2048,7 +2048,7 @@ arcnet_inthandler(struct device *dev)
                        /* send packet if there is one */
                        arcnet_go_tx(dev,0);
                        didsomething++;
-                       
+
                        if (lp->intx)
                        {
                                BUGMSG(D_DURING,"TXDONE while intx! (status=%Xh, intx=%d)\n",
@@ -2060,7 +2060,7 @@ arcnet_inthandler(struct device *dev)
                        if (!lp->outgoing.skb)
                        {
                                BUGMSG(D_DURING,"TX IRQ done: no split to continue.\n");
-                               
+
                                /* inform upper layers */
                                if (!lp->txready && IF_TBUSY)
                                {
@@ -2070,7 +2070,7 @@ arcnet_inthandler(struct device *dev)
                                lp->in_txhandler--;
                                continue;
                        }
-                       
+
                        /* if more than one segment, and not all segments
                         * are done, then continue xmit.
                         */
@@ -2113,29 +2113,29 @@ arcnet_inthandler(struct device *dev)
                {
                        ACOMMAND(CFLAGScmd|CONFIGclear);
                        lp->stats.tx_carrier_errors++;
-                       
+
                        #ifdef SHOW_RECONFIGS
                        BUGMSG(D_NORMAL,"Network reconfiguration detected (status=%Xh)\n",
                                        status);
                        #endif /* SHOW_RECONFIGS */
-                       
+
                        #ifdef RECON_THRESHOLD
                        /* is the RECON info empty or old? */
-                       if (!lp->first_recon || !lp->last_recon || 
+                       if (!lp->first_recon || !lp->last_recon ||
                                jiffies-lp->last_recon > HZ*10)
                        {
                                if (lp->network_down)
                                        BUGMSG(D_NORMAL,"reconfiguration detected: cabling restored?\n");
                                lp->first_recon=lp->last_recon=jiffies;
                                lp->num_recons=lp->network_down=0;
-                               
+
                                BUGMSG(D_DURING,"recon: clearing counters.\n");
                        }
                        else /* add to current RECON counter */
                        {
                                lp->last_recon=jiffies;
                                lp->num_recons++;
-                               
+
                                BUGMSG(D_DURING,"recon: counter=%d, time=%lds, net=%d\n",
                                        lp->num_recons,
                                        (lp->last_recon-lp->first_recon)/HZ,
@@ -2174,7 +2174,7 @@ arcnet_inthandler(struct device *dev)
                                BUGMSG(D_NORMAL,"cabling restored?\n");
                        lp->first_recon=lp->last_recon=0;
                        lp->num_recons=lp->network_down=0;
-                       
+
                        BUGMSG(D_DURING,"not recon: clearing counters anyway.\n");
                }
                #endif
@@ -2212,12 +2212,12 @@ arcnet_rx(struct device *dev,int recbuf)
        u_char *arcsoft;
        short length,offset;
        u_char daddr,saddr;
-       
+
        lp->stats.rx_packets++;
 
        saddr=arcpacket->hardheader.source;
        daddr=arcpacket->hardheader.destination;
-       
+
        /* if source is 0, it's a "used" packet! */
        if (saddr==0)
        {
@@ -2227,7 +2227,7 @@ arcnet_rx(struct device *dev,int recbuf)
                return;
        }
        arcpacket->hardheader.source=0;
-       
+
        if (arcpacket->hardheader.offset1) /* Normal Packet */
        {
                offset=arcpacket->hardheader.offset1;
@@ -2241,7 +2241,7 @@ arcnet_rx(struct device *dev,int recbuf)
 
                length=512-offset;
        }
-       
+
                BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n",
                                saddr,daddr,length);
 
@@ -2307,10 +2307,10 @@ arcnetA_rx(struct device *dev,u_char *buf,
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        struct sk_buff *skb;
        struct ClientData *arcsoft,*soft;
-       
+
        BUGMSG(D_DURING,"it's an RFC1201 packet (length=%d)\n",
                        length);
-                       
+
        /* compensate for EXTRA_CLIENTDATA (which isn't actually in the
         * packet)
         */
@@ -2326,14 +2326,14 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        ((u_char *)arcsoft + 4);
                length-=4;
        }
-       
+
        if (!arcsoft->split_flag)               /* not split */
        {
                struct Incoming *in=&lp->incoming[saddr];
 
                BUGMSG(D_RX,"incoming is not split (splitflag=%d)\n",
                        arcsoft->split_flag);
-                       
+
                if (in->skb)    /* already assembling one! */
                {
                        BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
@@ -2344,7 +2344,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        lp->stats.rx_missed_errors++;
                        in->skb=NULL;
                }
-               
+
                in->sequence=arcsoft->sequence;
 
                skb = alloc_skb(length, GFP_ATOMIC);
@@ -2354,16 +2354,16 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        return;
                }
                soft=(struct ClientData *)skb->data;
-               
+
                skb->len = length;
                skb->dev = dev;
-               
+
                memcpy((u_char *)soft+EXTRA_CLIENTDATA,
                        (u_char *)arcsoft+EXTRA_CLIENTDATA,
                        length-EXTRA_CLIENTDATA);
                soft->daddr=daddr;
                soft->saddr=saddr;
-               
+
                /* ARP packets have problems when sent from DOS.
                 * source address is always 0 on some systems!  So we take
                 * the hardware source addr (which is impossible to fumble)
@@ -2378,7 +2378,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        if (arp->ar_hln==1 && arp->ar_pln==4)
                        {
                                char *cptr=(char *)(arp)+sizeof(struct arphdr);
-                               
+
                                if (!*cptr)     /* is saddr = 00? */
                                {
                                        BUGMSG(D_EXTRA,"ARP source address was 00h, set to %02Xh.\n",
@@ -2400,7 +2400,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                                lp->stats.rx_crc_errors++;
                        }
                }
-               
+
                BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
                skb->protocol=arcnetA_type_trans(skb,dev);
@@ -2425,9 +2425,9 @@ arcnetA_rx(struct device *dev,u_char *buf,
                  * ARCnet card possible on the network.  Seems rather like
                  * a waste of memory.  Necessary?
                  */
-                 
+
                struct Incoming *in=&lp->incoming[saddr];
-               
+
                BUGMSG(D_RX,"packet is split (splitflag=%d, seq=%d)\n",
                        arcsoft->split_flag,in->sequence);
 
@@ -2442,7 +2442,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        lp->stats.rx_missed_errors++;
                        in->lastpacket=in->numpackets=0;
                }
-                 
+
                if (arcsoft->split_flag & 1)    /* first packet in split */
                {
                        BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n",
@@ -2460,7 +2460,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        in->sequence=arcsoft->sequence;
                        in->numpackets=((unsigned)arcsoft->split_flag>>1)+2;
                        in->lastpacket=1;
-                       
+
                        if (in->numpackets>16)
                        {
                                BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
@@ -2469,7 +2469,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                                lp->stats.rx_length_errors++;
                                return;
                        }
-               
+
                        in->skb=skb=alloc_skb(508*in->numpackets
                                        + sizeof(struct ClientData),
                                        GFP_ATOMIC);
@@ -2478,9 +2478,9 @@ arcnetA_rx(struct device *dev,u_char *buf,
                                lp->stats.rx_dropped++;
                                return;
                        }
-                                       
+
                        soft=(struct ClientData *)skb->data;
-                       
+
                        skb->len=sizeof(struct ClientData);
                        skb->dev=dev;
 
@@ -2495,7 +2495,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
 
                        /* if we're not assembling, there's no point
                         * trying to continue.
-                        */                     
+                        */
                        if (!in->skb)
                        {
                                BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d)\n",
@@ -2517,7 +2517,7 @@ arcnetA_rx(struct device *dev,u_char *buf,
                                        lp->stats.rx_frame_errors++;
                                        return;
                                }
-                               
+
                                /* "bad" duplicate, kill reassembly */
                                BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
                                        in->sequence,arcsoft->split_flag,
@@ -2532,18 +2532,18 @@ arcnetA_rx(struct device *dev,u_char *buf,
 
                        soft=(struct ClientData *)in->skb->data;
                }
-               
+
                skb=in->skb;
-               
+
                memcpy(skb->data+skb->len,
                       (u_char *)arcsoft+sizeof(struct ClientData),
                       length-sizeof(struct ClientData));
 
                skb->len+=length-sizeof(struct ClientData);
-               
+
                soft->daddr=daddr;
                soft->saddr=saddr;
-               
+
                /* are we done? */
                if (in->lastpacket == in->numpackets)
                {
@@ -2556,11 +2556,11 @@ arcnetA_rx(struct device *dev,u_char *buf,
                        {
                                in->skb=NULL;
                                in->lastpacket=in->numpackets=0;
-                       
+
                                BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
-                       
+
                                skb->protocol=arcnetA_type_trans(skb,dev);
-                               
+
                                netif_rx(skb);
                        }
                }
@@ -2649,7 +2649,7 @@ int arcnetA_header(struct sk_buff *skb,struct device *dev,
                lp->stats.tx_errors++;
                lp->stats.tx_aborted_errors++;
                return 0;
-       }       
+       }
 
        /*
         * Set the source hardware address.
@@ -2675,7 +2675,7 @@ int arcnetA_header(struct sk_buff *skb,struct device *dev,
        }
        else
                head->daddr=0;  /* better fill one in anyway */
-               
+
        return -dev->hard_header_len;
 }
 
@@ -2697,8 +2697,8 @@ int arcnetA_rebuild_header(struct sk_buff *skb)
         *
         * FIXME: Anyone want to spec IPv6 over ARCnet ?
         */
-        
-       if(head->protocol_id != ARC_P_IP) 
+
+       if(head->protocol_id != ARC_P_IP)
        {
                BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
                        head->protocol_id,head->protocol_id);
@@ -2712,7 +2712,7 @@ int arcnetA_rebuild_header(struct sk_buff *skb)
        /*
         * Try to get ARP to resolve the header.
         */
-#ifdef CONFIG_INET      
+#ifdef CONFIG_INET
        BUGMSG(D_DURING,"rebuild header from %d to %d; protocol %Xh\n",
                        head->saddr,head->daddr,head->protocol_id);
        status=arp_find(&(head->daddr),skb)? 1 : 0;
@@ -2720,8 +2720,8 @@ int arcnetA_rebuild_header(struct sk_buff *skb)
                        head->saddr,head->daddr,head->protocol_id);
        return status;
 #else
-       return 0;       
-#endif 
+       return 0;
+#endif
 }
 
 
@@ -2738,7 +2738,7 @@ unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev)
        skb->mac.raw=skb->data;
        skb_pull(skb,dev->hard_header_len);
        head=(struct ClientData *)skb->mac.raw;
-       
+
        if (head->daddr==0)
                skb->pkt_type=PACKET_BROADCAST;
        else if (dev->flags&IFF_PROMISC)
@@ -2747,7 +2747,7 @@ unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev)
                if (head->daddr != dev->dev_addr[0])
                        skb->pkt_type=PACKET_OTHERHOST;
        }
-       
+
        /* now return the protocol number */
        switch (head->protocol_id)
        {
@@ -2790,7 +2790,7 @@ static int arcnetE_init(struct device *dev)
        dev->hard_start_xmit=arcnetE_send_packet;
 
        BUGMSG(D_NORMAL,"ARCnet Ethernet-Encap protocol initialized.\n");
-                       
+
        return 0;
 }
 
@@ -2811,13 +2811,13 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
 {
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        int ioaddr=IOADDR,bad;
-       union ArcPacket *arcpacket = 
+       union ArcPacket *arcpacket =
                (union ArcPacket *)phys_to_virt(dev->mem_start+512*(lp->txbuf^1));
        u_char *arcsoft,daddr;
        short offset,length=skb->len+1;
 
        lp->intx++;
-       
+
        bad=arcnet_send_packet_bad(skb,dev);
        if (bad)
        {
@@ -2826,7 +2826,7 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
        }
 
        TBUSY=1;
-               
+
        if (length>XMTU)
        {
                BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n",
@@ -2837,7 +2837,7 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
                lp->intx--;
                return 0;
        }
-               
+
        BUGMSG(D_DURING,"starting tx sequence...\n");
 
        lp->txbuf=lp->txbuf^1; /* XOR with 1 to alternate btw 2 & 3 */
@@ -2867,25 +2867,25 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
        {
                arcpacket->hardheader.offset1=(offset-=256);
        }
-       
+
        BUGMSG(D_DURING," length=%Xh, offset=%Xh, offset1=%Xh, offset2=%Xh\n",
                        length,offset,arcpacket->hardheader.offset1,
                        arcpacket->hardheader.offset2);
-       
+
        arcsoft=&arcpacket->raw[offset];
        arcsoft[0]=ARC_P_ETHER;
        arcsoft++;
-               
+
        /* copy the packet into ARCnet shmem
         *  - the first bytes of ClientData header are skipped
         */
        BUGMSG(D_DURING,"ready to memcpy\n");
-       
+
        memcpy(arcsoft,skb->data,skb->len);
-               
+
        BUGMSG(D_DURING,"transmitting packet to station %02Xh (%d bytes)\n",
                        daddr,length);
-                               
+
        BUGLVL(D_TX) arcnet_dump_packet(dev,arcpacket->raw,length>=240,"tx");
 
        lp->lastload_dest=daddr;
@@ -2902,7 +2902,7 @@ arcnetE_send_packet(struct sk_buff *skb, struct device *dev)
 
        dev->trans_start=jiffies;
        lp->intx--;
-       
+
        /* make sure we didn't ignore a TX IRQ while we were in here */
        lp->intmask |= TXFREEflag;
        SETMASK;
@@ -2919,7 +2919,7 @@ arcnetE_rx(struct device *dev,u_char *arcsoft,
 {
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        struct sk_buff *skb;
-       
+
        BUGMSG(D_DURING,"it's an ethernet-encap packet (length=%d)\n",
                        length);
 
@@ -2929,16 +2929,16 @@ arcnetE_rx(struct device *dev,u_char *arcsoft,
                        lp->stats.rx_dropped++;
                        return;
                }
-               
+
                skb->len = length;
                skb->dev = dev;
-               
+
                memcpy(skb->data,(u_char *)arcsoft+1,length-1);
 
         BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
        skb->protocol=eth_type_trans(skb,dev);
-        
+
         netif_rx(skb);
 }
 
@@ -2958,7 +2958,7 @@ static int arcnetS_init(struct device *dev)
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
 
        arcnet_setup(dev);
-       
+
        /* And now fill particular fields with arcnet values */
        dev->dev_addr[0]=lp->stationid;
        dev->hard_header_len=sizeof(struct S_ClientData);
@@ -2994,14 +2994,14 @@ arcnetS_send_packet(struct sk_buff *skb, struct device *dev)
        struct S_ClientData *hdr=(struct S_ClientData *)skb->data;
 
        lp->intx++;
-       
+
        bad=arcnet_send_packet_bad(skb,dev);
        if (bad)
        {
                lp->intx--;
                return bad;
        }
-       
+
        TBUSY=1;
 
        length = 1 < skb->len ? skb->len : 1;
@@ -3020,7 +3020,7 @@ arcnetS_send_packet(struct sk_buff *skb, struct device *dev)
 
                /* done right away */
                dev_kfree_skb(skb,FREE_WRITE);
-                               
+
                if (arcnet_go_tx(dev,1))
                {
                        /* inform upper layers */
@@ -3035,7 +3035,7 @@ arcnetS_send_packet(struct sk_buff *skb, struct device *dev)
                dev_kfree_skb(skb,FREE_WRITE);
                lp->stats.tx_dropped++;
                TBUSY=0;
-               mark_bh(NET_BH);        
+               mark_bh(NET_BH);
        }
 
        dev->trans_start=jiffies;
@@ -3049,7 +3049,7 @@ arcnetS_send_packet(struct sk_buff *skb, struct device *dev)
 }
 
 
-/* Packet receiver for RFC1051 packets; 
+/* Packet receiver for RFC1051 packets;
  */
 static void
 arcnetS_rx(struct device *dev,u_char *buf,
@@ -3058,16 +3058,16 @@ arcnetS_rx(struct device *dev,u_char *buf,
        struct arcnet_local *lp = (struct arcnet_local *)dev->priv;
        struct sk_buff *skb;
        struct S_ClientData *arcsoft,*soft;
-       
+
        arcsoft=(struct S_ClientData *)(buf-S_EXTRA_CLIENTDATA);
        length+=S_EXTRA_CLIENTDATA;
-       
+
        BUGMSG(D_DURING,"it's an RFC1051 packet (length=%d)\n",
                        length);
-                       
-       
-                       
-       {    /* was "if not split" in A protocol, S is never split */   
+
+
+
+       {    /* was "if not split" in A protocol, S is never split */
 
                skb = alloc_skb(length, GFP_ATOMIC);
                if (skb == NULL) {
@@ -3080,14 +3080,14 @@ arcnetS_rx(struct device *dev,u_char *buf,
                memcpy((u_char *)soft + sizeof(struct S_ClientData)
                                - S_EXTRA_CLIENTDATA,
                        (u_char *)arcsoft + sizeof(struct S_ClientData)
-                               - S_EXTRA_CLIENTDATA, 
+                               - S_EXTRA_CLIENTDATA,
                        length - sizeof(struct S_ClientData)
                                + S_EXTRA_CLIENTDATA);
                soft->protocol_id=arcsoft->protocol_id;
                soft->daddr=daddr;
                soft->saddr=saddr;
                skb->dev = dev;  /* is already lp->sdev */
-               
+
                BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx");
 
                skb->protocol=arcnetS_type_trans(skb,dev);
@@ -3126,7 +3126,7 @@ int arcnetS_header(struct sk_buff *skb,struct device *dev,
                lp->stats.tx_errors++;
                lp->stats.tx_aborted_errors++;
                return 0;
-       }       
+       }
 
        /*
         * Set the source hardware address.
@@ -3149,7 +3149,7 @@ int arcnetS_header(struct sk_buff *skb,struct device *dev,
        }
        else
                head->daddr=0;  /* better fill one in anyway */
-               
+
        return -dev->hard_header_len;
 }
 
@@ -3167,8 +3167,8 @@ int arcnetS_rebuild_header(struct sk_buff *skb)
        /*
         * Only ARP and IP are currently supported
         */
-        
-       if(head->protocol_id != ARC_P_IP_RFC1051) 
+
+       if(head->protocol_id != ARC_P_IP_RFC1051)
        {
                BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n",
                        head->protocol_id,head->protocol_id);
@@ -3182,14 +3182,14 @@ int arcnetS_rebuild_header(struct sk_buff *skb)
        /*
         * Try to get ARP to resolve the header.
         */
-#ifdef CONFIG_INET      
+#ifdef CONFIG_INET
        return arp_find(&(head->daddr),skb)? 1 : 0;
 #else
-       return 0;       
-#endif 
+       return 0;
+#endif
 }
 
-               
+
 /* Determine a packet's protocol ID.
  *
  * With ARCnet we have to convert everything to Ethernet-style stuff.
@@ -3203,7 +3203,7 @@ unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev)
        skb->mac.raw=skb->data;
        skb_pull(skb,dev->hard_header_len);
        head=(struct S_ClientData *)skb->mac.raw;
-       
+
        if (head->daddr==0)
                skb->pkt_type=PACKET_BROADCAST;
        else if (dev->flags&IFF_PROMISC)
@@ -3212,7 +3212,7 @@ unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev)
                if (head->daddr != dev->dev_addr[0])
                        skb->pkt_type=PACKET_OTHERHOST;
        }
-       
+
        /* now return the protocol number */
        switch (head->protocol_id)
        {
@@ -3246,14 +3246,18 @@ static struct device thiscard = {
   0, 0,  /* I/O address, IRQ */
   0, 0, 0, NULL, arcnet_probe
 };
-       
-       
+
+
 static int io=0x0;     /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
 static int irqnum=0;   /* or use the insmod io= irq= shmem= options */
 static int irq=0;
 static int shmem=0;
 static char *device = NULL;    /* use eg. device="arc1" to change name */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irqnum, "i");
+MODULE_PARM(shmem, "i");
+
 #ifdef RIM_I_MODE
   static int node=0;   /* you must specify the node ID for RIM I cards */
 #endif
@@ -3272,7 +3276,7 @@ int init_module(void)
        #endif
 
        dev->base_addr=io;
-       
+
        if (irq) irqnum=irq;
        dev->irq=irqnum;
        if (dev->irq==2) dev->irq=9;
@@ -3310,7 +3314,7 @@ void cleanup_module(void)
                irq2dev_map[dev->irq] = NULL;
                free_irq(dev->irq,NULL);
        }
-       
+
        if (dev->base_addr) RELEASE_REGION(dev->base_addr,ARCNET_TOTAL_SIZE);
        unregister_netdev(dev);
        kfree(dev->priv);
index 73efdfd5945e2a18dd45d732aa8c893aa9c9815b..b7e715a8f761599e663f740a517971d92d0cc8ac 100644 (file)
@@ -270,7 +270,7 @@ int at1700_probe1(struct device *dev, short ioaddr)
        dev->set_multicast_list = &set_multicast_list;
 
        /* Fill in the fields of 'dev' with ethernet-generic values. */
-          
+
        ether_setup(dev);
        return 0;
 }
@@ -283,9 +283,9 @@ static int read_eeprom(int ioaddr, int location)
        short ee_daddr = ioaddr + EEPROM_Data;
        int read_cmd = location | EE_READ_CMD;
        short ctrl_val = EE_CS;
-       
+
        outb(ctrl_val, ee_addr);
-       
+
        /* Shift the read command bits out. */
        for (i = 9; i >= 0; i--) {
                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
@@ -296,7 +296,7 @@ static int read_eeprom(int ioaddr, int location)
                eeprom_delay();
        }
        outb(EE_CS, ee_addr);
-       
+
        for (i = 16; i > 0; i--) {
                outb(EE_CS | EE_SHIFT_CLK, ee_addr);
                eeprom_delay();
@@ -410,7 +410,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
 
                /* Turn off the possible Tx interrupts. */
                outb(0x00, ioaddr + TX_INTR);
-               
+
                outw(length, ioaddr + DATAPORT);
                outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
 
@@ -563,7 +563,7 @@ net_rx(struct device *dev)
                }
 
                if (net_debug > 5)
-                       printk("%s: Exint Rx packet with mode %02x after %d ticks.\n", 
+                       printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
                                   dev->name, inb(ioaddr + RX_MODE), i);
        }
        return;
@@ -614,17 +614,17 @@ static void
 set_multicast_list(struct device *dev)
 {
        short ioaddr = dev->base_addr;
-       if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) 
+       if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
        {
                /*
                 *      We must make the kernel realise we had to move
                 *      into promisc mode or we start all out war on
                 *      the cable. - AC
                 */
-               dev->flags|=IFF_PROMISC;                
-       
+               dev->flags|=IFF_PROMISC;
+
                outb(3, ioaddr + RX_MODE);      /* Enable promiscuous mode */
-       } 
+       }
        else
                outb(2, ioaddr + RX_MODE);      /* Disable promiscuous, use normal mode */
 }
@@ -638,6 +638,8 @@ static struct device dev_at1700 = {
 
 static int io = 0x260;
 static int irq = 0;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
index 34771b9fc9a5d2e0b087b682ecc15744e9ecc69c..7dbbfffbdd4e3cdb1db347b75ae92029befadce4 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Version:    @(#)bionet.c    1.0     02/06/96
  *
- * Author:     Hartmut Laue <laue@ifk-mp.uni-kiel.de> 
+ * Author:     Hartmut Laue <laue@ifk-mp.uni-kiel.de>
  * and         Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
  *
  * Little adaptions for integration into pl7 by Roman Hodek
@@ -116,7 +116,7 @@ static char *version =
 #include <asm/atari_acsi.h>
 #include <asm/atari_stdma.h>
 
-  
+
 extern struct device *init_etherdev(struct device *dev, int sizeof_private);
 
 /* use 0 for production, 1 for verification, >2 for debug
@@ -128,6 +128,8 @@ extern struct device *init_etherdev(struct device *dev, int sizeof_private);
  * Global variable 'bionet_debug'. Can be set at load time by 'insmod'
  */
 unsigned int bionet_debug = NET_DEBUG;
+MODULE_PARM(bionet_debug, "i");
+
 static unsigned int bionet_min_poll_time = 2;
 
 
@@ -177,7 +179,7 @@ sendcmd(unsigned int a0, unsigned int mod, unsigned int cmd) {
        unsigned int c;
 
        dma_wd.dma_mode_status = (mod | ((a0) ? 2 : 0) | 0x88);
-       dma_wd.fdc_acces_seccount = cmd; 
+       dma_wd.fdc_acces_seccount = cmd;
        dma_wd.dma_mode_status = (mod | 0x8a);
 
        if( !acsi_wait_for_IRQ(HZ/2) )  /* wait for cmd ack */
@@ -268,7 +270,7 @@ get_frame(unsigned long paddr, int odd) {
        dma_wd.dma_mode_status  = 0x88;
        c = dma_wd.fdc_acces_seccount;
        c = 1;
-  
+
 rend:
        dma_wd.dma_mode_status  = 0x80;
        udelay(40);
@@ -333,7 +335,7 @@ bionet_probe(struct device *dev) {
 
        if (!MACH_IS_ATARI || no_more_found)
                return ENODEV;
-       
+
        printk("Probing for BioNet 100 Adapter...\n");
 
        stdma_lock(bionet_intr, NULL);
@@ -342,7 +344,7 @@ bionet_probe(struct device *dev) {
        stdma_release();
 
        /* Check the first three octets of the S.A. for the manufactor's code.
-        */ 
+        */
 
        if( i < 0
        ||  station_addr[0] != 'B'
@@ -508,7 +510,7 @@ bionet_poll_rx(struct device *dev) {
 
        while(boguscount--) {
                status = get_frame((unsigned long)phys_nic_packet, 0);
-         
+
                if( status != 1 ) break;
 
                /* Good packet... */
@@ -610,7 +612,7 @@ static char kernel_version[] = UTS_RELEASE;
 #undef NEXT_DEV
 #define NEXT_DEV       (&bio_dev)
 
-static struct device bio_dev =  
+static struct device bio_dev =
        {
                "        ",     /* filled in by register_netdev() */
                0, 0, 0, 0,     /* memory */
@@ -621,7 +623,7 @@ static struct device bio_dev =
 int
 init_module(void) {
        int err;
-       
+
        if ((err = register_netdev(&bio_dev))) {
                if (err == -EEXIST)  {
                        printk("BIONET: devices already present. Module not loaded.\n");
@@ -629,13 +631,13 @@ init_module(void) {
                return err;
        }
        return 0;
-}  
+}
 
 void
 cleanup_module(void) {
        unregister_netdev(&bio_dev);
 }
-                      
+
 #endif /* MODULE */
 
 /* Local variables:
index c4fae64feec5fa973556a79721c1bf8ab7253def..d6de47007d979350e3d110ee96c2f00ac6f3f2d9 100644 (file)
@@ -2,12 +2,12 @@
  *
  * Version:    @(#)PAMsNet.c   0.2ß    03/31/96
  *
- * Author:  Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de> 
+ * Author:  Torsten Lang <Torsten.Lang@ap.physik.uni-giessen.de>
  *                       <Torsten.Lang@jung.de>
  *
  * This driver is based on my driver PAMSDMA.c for MiNT-Net and
  * on the driver bionet.c written by
- *          Hartmut Laue <laue@ifk-mp.uni-kiel.de> 
+ *          Hartmut Laue <laue@ifk-mp.uni-kiel.de>
  * and      Torsten Narjes <narjes@ifk-mp.uni-kiel.de>
  *
  * Little adaptions for integration into pl7 by Roman Hodek
@@ -114,7 +114,7 @@ static char *version =
 
 #undef READ
 #undef WRITE
-  
+
 extern struct device *init_etherdev(struct device *dev, int sizeof_private);
 
 /* use 0 for production, 1 for verification, >2 for debug
@@ -126,6 +126,8 @@ extern struct device *init_etherdev(struct device *dev, int sizeof_private);
  * Global variable 'pamsnet_debug'. Can be set at load time by 'insmod'
  */
 unsigned int pamsnet_debug = NET_DEBUG;
+MODULE_PARM(pamsnet_debug, "i");
+
 static unsigned int pamsnet_min_poll_time = 2;
 
 
@@ -195,7 +197,7 @@ typedef struct
  * LUN 7 lets you send and receive packets.
  *
  * Some commands like the INQUIRY command work identical on all used LUNs.
- * 
+ *
  * UNKNOWN1 seems to read some data.
  *          Command length is 6 bytes.
  * UNKNOWN2 seems to read some data (command byte 1 must be !=0). The
@@ -229,7 +231,7 @@ typedef struct
  *          Command length is 6 byte.
  */
 
-enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START, 
+enum {UNKNOWN1=3, READPKT=8, UNKNOWN2, WRITEPKT=10, INQUIRY=18, START,
       NUMPKTS=22, UNKNOWN3, UNKNOWN4, UNKNOWN5, DESELECT, STOP};
 
 #define READSECTOR  READPKT
@@ -292,14 +294,14 @@ int if_up = 0;
  */
 
 /* The following lowlevel routines work on physical addresses only and assume
- * that eventually needed buffers are 
+ * that eventually needed buffers are
  * - completely located in ST RAM
  * - are contigous in the physical address space
  */
 
 /* Setup the DMA counter */
 
-static void 
+static void
 setup_dma (address, rw_flag, num_blocks)
        void *address;
        unsigned rw_flag;
@@ -321,7 +323,7 @@ setup_dma (address, rw_flag, num_blocks)
 
 /* Send the first byte of an command block */
 
-static int 
+static int
 send_first (target, byte)
        int target;
        unsigned char byte;
@@ -342,14 +344,14 @@ send_first (target, byte)
 
 /* Send the rest of an command block */
 
-static int 
+static int
 send_1_5 (lun, command, dma)
        int lun;
        unsigned char *command;
        int dma;
 {
        int i, j;
-       
+
        for (i=0; i<5; i++) {
                WRITEBOTH((!i ? (((lun & 0x7) << 5) | (command[i] & 0x1F))
                              : command[i]),
@@ -365,7 +367,7 @@ send_1_5 (lun, command, dma)
 
 /* Read a status byte */
 
-static int 
+static int
 get_status (void)
 {
        WRITEMODE(DMA_FDC | DMA_WINDOW | REG_ACSI | A1);
@@ -375,7 +377,7 @@ get_status (void)
 
 /* Calculate the number of received bytes */
 
-static int 
+static int
 calc_received (start_address)
        void *start_address;
 {
@@ -435,7 +437,7 @@ bad:
 /* inquiry() returns 0 when PAM's DMA found, -1 when timeout, -2 otherwise */
 /* Please note: The buffer is for internal use only but must be defined!   */
 
-static int 
+static int
 inquiry (target, buffer)
        int target;
        unsigned char *buffer;
@@ -443,7 +445,7 @@ inquiry (target, buffer)
        int ret = -1;
        unsigned char *vbuffer = (unsigned char *)PTOV(buffer);
        unsigned char cmd_buffer[5];
-       
+
        if (send_first(target, INQUIRY))
                goto bad;
        setup_dma(buffer, READ, 1);
@@ -467,12 +469,12 @@ bad:
        return (ret);
 }
 
-/* 
+/*
  * read_hw_addr() reads the sector containing the hwaddr and returns
  * a pointer to it (virtual address!) or 0 in case of an error
  */
 
-static HADDR 
+static HADDR
 *read_hw_addr(target, buffer)
        int target;
        unsigned char *buffer;
@@ -569,7 +571,7 @@ pamsnet_probe (dev)
 {
        int i;
        HADDR *hwaddr;
-       
+
        unsigned char station_addr[6];
        static unsigned version_printed = 0;
        /* avoid "Probing for..." printed 4 times - the driver is supporting only one adapter now! */
@@ -579,7 +581,7 @@ pamsnet_probe (dev)
                return ENODEV;
 
        no_more_found = 1;
-       
+
        printk("Probing for PAM's Net/GK Adapter...\n");
 
        /* Allocate the DMA buffer here since we need it for probing! */
@@ -613,7 +615,7 @@ pamsnet_probe (dev)
                else
                        memcpy (station_addr, hwaddr, ETH_ALEN);
        }
-       
+
        ENABLE_IRQ();
        stdma_release();
 
@@ -775,7 +777,7 @@ pamsnet_poll_rx(struct device *dev) {
 
        while(boguscount--) {
                pkt_len = receivepkt(lance_target, phys_nic_packet);
-         
+
                if( pkt_len < 60 ) break;
 
                /* Good packet... */
@@ -882,7 +884,7 @@ static char kernel_version[] = UTS_RELEASE;
 #undef NEXT_DEV
 #define NEXT_DEV       (&pam_dev)
 
-static struct device pam_dev =  
+static struct device pam_dev =
        {
                "        ",     /* filled in by register_netdev() */
                0, 0, 0, 0,     /* memory */
@@ -893,7 +895,7 @@ static struct device pam_dev =
 int
 init_module(void) {
        int err;
-       
+
        if ((err = register_netdev(&pam_dev))) {
                if (err == -EEXIST)  {
                        printk("PAM's Net/GK: devices already present. Module not loaded.\n");
@@ -901,13 +903,13 @@ init_module(void) {
                return err;
        }
        return 0;
-}  
+}
 
 void
 cleanup_module(void) {
        unregister_netdev(&pam_dev);
 }
-                      
+
 #endif /* MODULE */
 
 /* Local variables:
index 1ed5571254be11b03aca680d23d2c6435a42c18c..afab3432ef38aed04f56219e393f59e1fb3dc88d 100644 (file)
@@ -81,6 +81,7 @@ static int lance_debug = LANCE_DEBUG;
 #else
 static int lance_debug = 1;
 #endif
+MODULE_PARM(lance_debug, "i");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
@@ -94,7 +95,7 @@ static int lance_debug = 1;
 #ifdef LANCE_DEBUG_PROBE
 # define PROBE_PRINT(a)        printk a
 #else
-# define PROBE_PRINT(a)        
+# define PROBE_PRINT(a)
 #endif
 
 /* These define the number of Rx and Tx buffers as log2. (Only powers
@@ -372,12 +373,12 @@ int atarilance_probe( struct device *dev )
 
 {      int i;
        static int found = 0;
-       
+
        if (!MACH_IS_ATARI || found)
                /* Assume there's only one board possible... That seems true, since
                 * the Riebl/PAM board's address cannot be changed. */
                return( ENODEV );
-       
+
        for( i = 0; i < N_LANCE_ADDR; ++i ) {
                if (lance_probe1( dev, &lance_addr_list[i] )) {
                        found = 1;
@@ -402,7 +403,7 @@ static int addr_accessible( volatile void *regp, int wordflag, int writeflag )
 
        __asm__ __volatile__ ( "movec   %/vbr,%0" : "=r" (vbr) : );
        save_berr = vbr[2];
-       
+
        __asm__ __volatile__
        (       "movel  %/sp,%/d1\n\t"
                "movel  #Lberr,%2@\n\t"
@@ -436,7 +437,7 @@ static int addr_accessible( volatile void *regp, int wordflag, int writeflag )
 
        vbr[2] = save_berr;
        restore_flags(flags);
-       
+
        return( ret );
 }
 
@@ -453,7 +454,7 @@ static unsigned long lance_probe1( struct device *dev,
        int                                     i;
        static int                              did_version = 0;
        unsigned short                  save1, save2;
-       
+
        PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
                                  (long)memaddr, (long)ioaddr ));
 
@@ -470,7 +471,7 @@ static unsigned long lance_probe1( struct device *dev,
        *memaddr = 0x0000;
        if (*memaddr != 0x0000) goto probe_fail;
        *memaddr = save1;
-       
+
        /* First port should be readable and writable */
        PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
        if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
@@ -505,7 +506,7 @@ static unsigned long lance_probe1( struct device *dev,
 
   probe_fail:
        return( 0 );
-       
+
   probe_ok:
        init_etherdev( dev, sizeof(struct lance_private) );
        if (!dev->priv)
@@ -515,7 +516,7 @@ static unsigned long lance_probe1( struct device *dev,
        IO = lp->iobase = (struct lance_ioreg *)ioaddr;
        dev->base_addr = (unsigned long)ioaddr; /* informational only */
        lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
-       
+
        REGA( CSR0 ) = CSR0_STOP;
 
        /* Now test for type: If the eeprom I/O port is readable, it is a
@@ -530,7 +531,7 @@ static unsigned long lance_probe1( struct device *dev,
        }
        else
                lp->cardtype = OLD_RIEBL;
-               
+
        if (lp->cardtype == PAM_CARD ||
                memaddr == (unsigned short *)0xffe00000) {
                /* PAMs card and Riebl on ST use level 5 autovector */
@@ -572,7 +573,7 @@ static unsigned long lance_probe1( struct device *dev,
          case PAM_CARD:
                i = IO->eeprom;
                for( i = 0; i < 6; ++i )
-                       dev->dev_addr[i] = 
+                       dev->dev_addr[i] =
                                ((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
                                ((((unsigned short *)MEM)[i*2+1] & 0x0f));
                i = IO->mem;
@@ -585,7 +586,7 @@ static unsigned long lance_probe1( struct device *dev,
                                dev->name );
                printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
        }
-       
+
        MEM->init.mode = 0x0000;                /* Disable Rx and Tx. */
        for( i = 0; i < 6; i++ )
                MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
@@ -602,7 +603,7 @@ static unsigned long lance_probe1( struct device *dev,
                IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
        else
                *RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
-       
+
        if (did_version++ == 0)
                DPRINTK( 1, ( version ));
 
@@ -616,7 +617,7 @@ static unsigned long lance_probe1( struct device *dev,
        dev->start = 0;
 
        memset( &lp->stats, 0, sizeof(lp->stats) );
-       
+
        return( 1 );
 }
 
@@ -632,12 +633,12 @@ static int lance_open( struct device *dev )
        lance_init_ring(dev);
        /* Re-initialize the LANCE, and start it when done. */
 
-       REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+       REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
        REGA( CSR2 ) = 0;
        REGA( CSR1 ) = 0;
        REGA( CSR0 ) = CSR0_INIT;
        /* From now on, AREG is kept to point to CSR0 */
-       
+
        i = 1000000;
        while (--i > 0)
                if (DREG & CSR0_IDON)
@@ -670,7 +671,7 @@ static void lance_init_ring( struct device *dev )
 {      struct lance_private *lp = (struct lance_private *)dev->priv;
        int i;
        unsigned offset;
-       
+
        lp->lock = 0;
        lp->tx_full = 0;
        lp->cur_rx = lp->cur_tx = 0;
@@ -718,7 +719,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct device *dev )
        int entry, len;
        struct lance_tx_head *head;
        unsigned long flags;
-       
+
        /* Transmitter timeout, serious problems. */
        if (dev->tbusy) {
                int tickssofar = jiffies - dev->trans_start;
@@ -732,7 +733,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct device *dev )
                 * Always set BSWP after a STOP as STOP puts it back into
                 * little endian mode.
                 */
-               REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+               REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
                lp->stats.tx_errors++;
 #ifndef final_version
                {       int i;
@@ -808,7 +809,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct device *dev )
        /* Mask to ring buffer boundary. */
        entry = lp->cur_tx & TX_RING_MOD_MASK;
        head  = &(MEM->tx_head[entry]);
-       
+
        /* Caution: the write order is important here, set the "ownership" bits
         * last.
         */
@@ -885,7 +886,7 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
                        while( dirty_tx < lp->cur_tx) {
                                int entry = dirty_tx & TX_RING_MOD_MASK;
                                int status = MEM->tx_head[entry].flag;
-                       
+
                                if (status & TMD1_OWN_CHIP)
                                        break;                  /* It still hasn't been Txed */
 
@@ -965,12 +966,12 @@ static int lance_rx( struct device *dev )
 
        DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
                                  MEM->rx_head[entry].flag ));
-       
+
        /* If we own the next entry, it's a new packet. Send it up. */
        while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
                struct lance_rx_head *head = &(MEM->rx_head[entry]);
                int status = head->flag;
-               
+
                if (status != (RMD1_ENP|RMD1_STP)) {            /* There was an error. */
                        /* There is a tricky error noted by John Murphy,
                           <murf@perftech.com> to Russ Nelson: Even with full-sized
@@ -1001,7 +1002,7 @@ static int lance_rx( struct device *dev )
                                                if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
                                                        RMD1_OWN_CHIP)
                                                        break;
-                                       
+
                                        if (i > RX_RING_SIZE - 2) {
                                                lp->stats.rx_dropped++;
                                                head->flag |= RMD1_OWN_CHIP;
@@ -1025,7 +1026,7 @@ static int lance_rx( struct device *dev )
                                                   data[19], data[20], data[21], data[22],
                                                   pkt_len );
                                }
-                               
+
                                skb->dev = dev;
                                skb_reserve( skb, 2 );  /* 16 byte align */
                                skb_put( skb, pkt_len );        /* Make room */
@@ -1094,7 +1095,7 @@ static void set_multicast_list( struct device *dev )
        if (!dev->start)
                /* Only possible if board is already started */
                return;
-       
+
        /* We take the simple way out and always enable promiscuous mode. */
        DREG = CSR0_STOP; /* Temporarily stop the lance. */
 
@@ -1119,7 +1120,7 @@ static void set_multicast_list( struct device *dev )
         * Always set BSWP after a STOP as STOP puts it back into
         * little endian mode.
         */
-       REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 
+       REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
 
        /* Resume normal operation and reset AREG to CSR0 */
        REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
@@ -1133,7 +1134,7 @@ static int lance_set_mac_address( struct device *dev, void *addr )
 {      struct lance_private *lp = (struct lance_private *)dev->priv;
        struct sockaddr *saddr = addr;
        int i;
-       
+
        if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
                return( -EOPNOTSUPP );
 
@@ -1150,7 +1151,7 @@ static int lance_set_mac_address( struct device *dev, void *addr )
        lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
        /* set also the magic for future sessions */
        *RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
-       
+
        return( 0 );
 }
 
@@ -1158,7 +1159,7 @@ static int lance_set_mac_address( struct device *dev, void *addr )
 #ifdef MODULE
 static char devicename[9] = { 0, };
 
-static struct device atarilance_dev =  
+static struct device atarilance_dev =
 {
        devicename,     /* filled in by register_netdev() */
        0, 0, 0, 0,     /* memory */
@@ -1169,7 +1170,7 @@ static struct device atarilance_dev =
 int init_module(void)
 
 {      int err;
-       
+
        if ((err = register_netdev( &atarilance_dev ))) {
                if (err == -EIO)  {
                        printk( "No Atari Lance board found. Module not loaded.\n");
@@ -1177,14 +1178,14 @@ int init_module(void)
                return( err );
        }
        return( 0 );
-}  
+}
 
 void cleanup_module(void)
 
 {
        unregister_netdev( &atarilance_dev );
 }
-                      
+
 #endif /* MODULE */
 \f
 
index 6d749fb334ff93019800ac23e45abbd5b253b953..e9d67d31615804c6d38eac358ea6e5421a3d4d12 100644 (file)
@@ -33,7 +33,7 @@
  *          hence the name. Since the serial port is not used as an async serial
  *          port, the kernel driver for serial ports cannot be used, and this
  *          driver only supports standard serial hardware (8250, 16450, 16550)
- *  
+ *
  *  par96:  This is a modem for 9600 baud FSK compatible to the G3RUH standard.
  *          The modem does all the filtering and regenerates the receiver clock.
  *          Data is transferred from and to the PC via a shift register.
@@ -45,7 +45,7 @@
  *          from Baycom) and has been replaced by the PICPAR modem (see below).
  *          You may however still build one from the schematics published in
  *          cq-DL :-).
- *  
+ *
  *  picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
  *          modem is protocol compatible to par96, but uses only three low
  *          power ICs and can therefore be fed from the parallel port and
@@ -55,7 +55,7 @@
  *
  *
  *  Command line options (insmod command line)
- * 
+ *
  *  mode     driver mode string. Valid choices are ser12 and par96. An
  *           optional * enables software DCD.
  *           2=par96/par97, any other value invalid
@@ -63,7 +63,7 @@
  *           0x2f8, 0x3e8, 0x2e8 and for par96/par97 0x378, 0x278, 0x3bc
  *  irq      interrupt line of the port; common values are for ser12 3,4
  *           and for par96/par97 7
- * 
+ *
  *
  *  History:
  *   0.1  26.06.96  Adapted from baycom.c and made network driver interface
@@ -153,7 +153,7 @@ static struct {
 
 /* ---------------------------------------------------------------------- */
 /*
- * Information that need to be kept for each board. 
+ * Information that need to be kept for each board.
  */
 
 struct baycom_state {
@@ -182,7 +182,7 @@ struct baycom_state {
                        unsigned long scram;
                } par96;
        } modem;
-       
+
 #ifdef BAYCOM_DEBUG
        struct debug_vals {
                unsigned long last_jiffies;
@@ -205,7 +205,7 @@ static void inline baycom_int_freq(struct baycom_state *bc)
 {
 #ifdef BAYCOM_DEBUG
        unsigned long cur_jiffies = jiffies;
-       /* 
+       /*
         * measure the interrupt frequency
         */
        bc->debug_vals.cur_intcnt++;
@@ -224,7 +224,7 @@ static void inline baycom_int_freq(struct baycom_state *bc)
  * ===================== SER12 specific routines =========================
  */
 
-static void inline ser12_set_divisor(struct device *dev, 
+static void inline ser12_set_divisor(struct device *dev,
                                     unsigned char divisor)
 {
        outb(0x81, LCR(dev->base_addr));        /* DLAB = 1 */
@@ -235,7 +235,7 @@ static void inline ser12_set_divisor(struct device *dev,
         * make sure the next interrupt is generated;
         * 0 must be used to power the modem; the modem draws its
         * power from the TxD line
-        */     
+        */
        outb(0x00, THR(dev->base_addr));
        /*
         * it is important not to set the divider while transmitting;
@@ -258,7 +258,7 @@ static void inline ser12_set_divisor(struct device *dev,
 static inline void ser12_tx(struct device *dev, struct baycom_state *bc)
 {
        /* one interrupt per channel bit */
-       ser12_set_divisor(dev, 12); 
+       ser12_set_divisor(dev, 12);
        /*
         * first output the last bit (!) then call HDLC transmitter,
         * since this may take quite long
@@ -266,7 +266,7 @@ static inline void ser12_tx(struct device *dev, struct baycom_state *bc)
        outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
        if (bc->modem.shreg <= 1)
                bc->modem.shreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
-       bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^ 
+       bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^
                                   (bc->modem.shreg & 1));
        bc->modem.shreg >>= 1;
 }
@@ -280,7 +280,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
         * do demodulator
         */
        cur_s = inb(MSR(dev->base_addr)) & 0x10;        /* the CTS line */
-       hdlcdrv_channelbit(&bc->hdrv, cur_s); 
+       hdlcdrv_channelbit(&bc->hdrv, cur_s);
        bc->modem.ser12.dcd_shreg = (bc->modem.ser12.dcd_shreg << 1) |
                (cur_s != bc->modem.ser12.last_sample);
        bc->modem.ser12.last_sample = cur_s;
@@ -301,7 +301,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
                        bc->modem.ser12.dcd_sum0--;
        }
        if(!bc->modem.ser12.dcd_time) {
-               hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + 
+               hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
                                           bc->modem.ser12.dcd_sum1 +
                                           bc->modem.ser12.dcd_sum2) < 0);
                bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
@@ -342,14 +342,14 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
                                break;
                        }
                        bc->modem.shreg >>= 1;
-                       if (bc->modem.ser12.last_sample == 
+                       if (bc->modem.ser12.last_sample ==
                            bc->modem.ser12.last_rxbit)
                                bc->modem.shreg |= 0x10000;
-                       bc->modem.ser12.last_rxbit = 
+                       bc->modem.ser12.last_rxbit =
                                bc->modem.ser12.last_sample;
                }
                if (++bc->modem.ser12.interm_sample >= 3)
-                       bc->modem.ser12.interm_sample = 0;      
+                       bc->modem.ser12.interm_sample = 0;
                /*
                 * DCD stuff
                 */
@@ -365,7 +365,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
                        dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
 
                        bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
-               } 
+               }
        } else {
                /*
                 * PLL algorithm for the hardware squelch DCD algorithm
@@ -397,10 +397,10 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
                                break;
                        }
                        bc->modem.shreg >>= 1;
-                       if (bc->modem.ser12.last_sample == 
+                       if (bc->modem.ser12.last_sample ==
                            bc->modem.ser12.last_rxbit)
                                bc->modem.shreg |= 0x10000;
-                       bc->modem.ser12.last_rxbit = 
+                       bc->modem.ser12.last_rxbit =
                                bc->modem.ser12.last_sample;
                }
                bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
@@ -415,7 +415,7 @@ static inline void ser12_rx(struct device *dev, struct baycom_state *bc)
                bc->modem.shreg = 0x10000;
        }
        if(!bc->modem.ser12.dcd_time) {
-               hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 + 
+               hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
                                           bc->modem.ser12.dcd_sum1 +
                                           bc->modem.ser12.dcd_sum2) < 0);
                bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
@@ -433,7 +433,7 @@ static void ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct device *dev = (struct device *)dev_id;
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
-       
+
        if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
                return;
 
@@ -477,7 +477,7 @@ static enum uart ser12_check_uart(unsigned int iobase)
        b3 = inb(MSR(iobase)) & 0xf0;
        outb(b1, MCR(iobase));                  /* restore old values */
        outb(b2, MSR(iobase));
-       if (b3 != 0x90) 
+       if (b3 != 0x90)
                return c_uart_unknown;
        inb(RBR(iobase));
        inb(RBR(iobase));
@@ -488,7 +488,7 @@ static enum uart ser12_check_uart(unsigned int iobase)
                b1 = inb(SCR(iobase));
                outb(0xa5, SCR(iobase));
                b2 = inb(SCR(iobase));
-               if ((b1 != 0x5a) || (b2 != 0xa5)) 
+               if ((b1 != 0x5a) || (b2 != 0xa5))
                        u = c_uart_8250;
        }
        return u;
@@ -496,14 +496,14 @@ static enum uart ser12_check_uart(unsigned int iobase)
 
 /* --------------------------------------------------------------------- */
 
-static int ser12_open(struct device *dev) 
+static int ser12_open(struct device *dev)
 {
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
        enum uart u;
 
        if (!dev || !bc)
                return -ENXIO;
-       if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT || 
+       if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
            dev->irq < 2 || dev->irq > 15)
                return -ENXIO;
        if (check_region(dev->base_addr, SER12_EXTENT))
@@ -516,14 +516,14 @@ static int ser12_open(struct device *dev)
        outb(0x0d, MCR(dev->base_addr));
        outb(0x0d, MCR(dev->base_addr));
        outb(0, IER(dev->base_addr));
-       if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT, 
+       if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT,
                        "baycom_ser12", dev))
                return -EBUSY;
        request_region(dev->base_addr, SER12_EXTENT, "baycom_ser12");
        /*
         * enable transmitter empty interrupt
         */
-       outb(2, IER(dev->base_addr));  
+       outb(2, IER(dev->base_addr));
        /*
         * set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
         * we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
@@ -531,7 +531,7 @@ static int ser12_open(struct device *dev)
         */
        ser12_set_divisor(dev, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6);
        printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u options "
-              "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq, 
+              "0x%x uart %s\n", bc_drvname, dev->base_addr, dev->irq,
               bc->options, uart_str[u]);
        MOD_INC_USE_COUNT;
        return 0;
@@ -539,7 +539,7 @@ static int ser12_open(struct device *dev)
 
 /* --------------------------------------------------------------------- */
 
-static int ser12_close(struct device *dev) 
+static int ser12_close(struct device *dev)
 {
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
@@ -550,7 +550,7 @@ static int ser12_close(struct device *dev)
         */
        outb(0, IER(dev->base_addr));
        outb(1, MCR(dev->base_addr));
-       free_irq(dev->irq, dev);        
+       free_irq(dev->irq, dev);
        release_region(dev->base_addr, SER12_EXTENT);
        printk(KERN_INFO "%s: close ser12 at iobase 0x%lx irq %u\n",
               bc_drvname, dev->base_addr, dev->irq);
@@ -588,7 +588,7 @@ static inline void par96_tx(struct device *dev, struct baycom_state *bc)
                if (!(data & 1))
                        bc->modem.par96.scram ^= 1;
                if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
-                       bc->modem.par96.scram ^= 
+                       bc->modem.par96.scram ^=
                                (PAR96_SCRAM_TAPN << 1);
                if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
                        val |= PAR96_TXBIT;
@@ -611,7 +611,7 @@ static inline void par96_rx(struct device *dev, struct baycom_state *bc)
                bc->modem.par96.descram = (bc->modem.par96.descram << 1);
                if (inb(LPT_STATUS(dev->base_addr)) & PAR96_RXBIT)
                        bc->modem.par96.descram |= 1;
-               descx = bc->modem.par96.descram ^ 
+               descx = bc->modem.par96.descram ^
                        (bc->modem.par96.descram >> 1);
                /* now the diff decoded data is inverted in descram */
                outb(PAR97_POWER | PAR96_PTT, LPT_DATA(dev->base_addr));
@@ -620,7 +620,7 @@ static inline void par96_rx(struct device *dev, struct baycom_state *bc)
                data >>= 1;
                if (!(descx & 1))
                        data |= 0x8000;
-               outb(PAR97_POWER | PAR96_PTT | PAR96_BURST, 
+               outb(PAR97_POWER | PAR96_PTT | PAR96_BURST,
                     LPT_DATA(dev->base_addr));
        }
        hdlcdrv_putbits(&bc->hdrv, data);
@@ -631,12 +631,12 @@ static inline void par96_rx(struct device *dev, struct baycom_state *bc)
                bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
                        | (data << 16);
                /* search for flags and set the dcd counter appropriately */
-               for(mask = 0x1fe00, mask2 = 0xfc00, i = 0; 
+               for(mask = 0x1fe00, mask2 = 0xfc00, i = 0;
                    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
                        if ((bc->modem.par96.dcd_shreg & mask) == mask2)
                                bc->modem.par96.dcd_count = HDLCDRV_MAXFLEN+4;
                /* check for abort/noise sequences */
-               for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0; 
+               for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0;
                    i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
                        if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
                            (bc->modem.par96.dcd_count >= 0))
@@ -657,7 +657,7 @@ static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct device *dev = (struct device *)dev_id;
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
-       
+
        if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
                return;
 
@@ -704,13 +704,13 @@ static int par96_check_lpt(unsigned int iobase)
 
 /* --------------------------------------------------------------------- */
 
-static int par96_open(struct device *dev) 
+static int par96_open(struct device *dev)
 {
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
        if (!dev || !bc)
                return -ENXIO;
-       if (!dev->base_addr || dev->base_addr > 0x1000-PAR96_EXTENT || 
+       if (!dev->base_addr || dev->base_addr > 0x1000-PAR96_EXTENT ||
            dev->irq < 2 || dev->irq > 15)
                return -ENXIO;
        if (check_region(dev->base_addr, PAR96_EXTENT))
@@ -720,34 +720,34 @@ static int par96_open(struct device *dev)
        if (par96_check_lpt(dev->base_addr))
                return -EIO;
        /* disable interrupt */
-       outb(0, LPT_CONTROL(dev->base_addr));          
+       outb(0, LPT_CONTROL(dev->base_addr));
         /* switch off PTT */
        outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
        printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
               bc_drvname, dev->base_addr, dev->irq, bc->options);
-       if (request_irq(dev->irq, par96_interrupt, SA_INTERRUPT, 
+       if (request_irq(dev->irq, par96_interrupt, SA_INTERRUPT,
                        "baycom_par96", dev))
                return -EBUSY;
        request_region(dev->base_addr, PAR96_EXTENT, "baycom_par96");
        /* enable interrupt */
-       outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev->base_addr)); 
+       outb(LPT_IRQ_ENABLE, LPT_CONTROL(dev->base_addr));
        MOD_INC_USE_COUNT;
        return 0;
 }
 
 /* --------------------------------------------------------------------- */
 
-static int par96_close(struct device *dev) 
+static int par96_close(struct device *dev)
 {
        struct baycom_state *bc = (struct baycom_state *)dev->priv;
 
        if (!dev || !bc)
                return -EINVAL;
        /* disable interrupt */
-       outb(0, LPT_CONTROL(dev->base_addr));  
+       outb(0, LPT_CONTROL(dev->base_addr));
        /* switch off PTT */
        outb(PAR96_PTT | PAR97_POWER, LPT_DATA(dev->base_addr));
-       free_irq(dev->irq, dev);        
+       free_irq(dev->irq, dev);
        release_region(dev->base_addr, PAR96_EXTENT);
        printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
               bc_drvname, dev->base_addr, dev->irq);
@@ -762,7 +762,7 @@ static int par96_close(struct device *dev)
 
 /* --------------------------------------------------------------------- */
 
-static int baycom_ioctl(struct device *dev, struct ifreq *ifr, 
+static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
                        struct hdlcdrv_ioctl *hi, int cmd);
 
 /* --------------------------------------------------------------------- */
@@ -801,7 +801,7 @@ static int baycom_setmode(struct baycom_state *bc, char *modestr)
 {
        struct hdlcdrv_ops *newops = NULL;
        unsigned long flags;
-       
+
        if (!strncmp(modestr, "off", 3))
                newops = &dummy_ops;
        else if (!strncmp(modestr, "ser12", 5))
@@ -820,14 +820,14 @@ static int baycom_setmode(struct baycom_state *bc, char *modestr)
 
 /* --------------------------------------------------------------------- */
 
-static int baycom_ioctl(struct device *dev, struct ifreq *ifr, 
+static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
                        struct hdlcdrv_ioctl *hi, int cmd)
 {
        struct baycom_state *bc;
        struct baycom_ioctl bi;
        int cmd2;
-               
-       if (!dev || !dev->priv || 
+
+       if (!dev || !dev->priv ||
            ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
                printk(KERN_ERR "bc_ioctl: invalid device struct\n");
                return -EINVAL;
@@ -841,7 +841,7 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
        switch (hi->cmd) {
        default:
                break;
-               
+
        case HDLCDRVCTL_GETMODE:
                if (bc->hdrv.ops == &ser12_ops)
                        strcpy(hi->data.modename, "ser12");
@@ -868,7 +868,7 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
                if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
                        return -EFAULT;
                return 0;
-               
+
        case HDLCDRVCTL_MODEMPARMASK:
                return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
 
@@ -900,14 +900,14 @@ static int baycom_ioctl(struct device *dev, struct ifreq *ifr,
 #ifdef MODULE
 static
 #endif /* MODULE */
-int baycom_init(void) 
+int baycom_init(void)
 {
        int i, j, found = 0;
        char set_hw = 1;
        struct baycom_state *bc;
        char ifname[HDLCDRV_IFNAMELEN];
 
-       
+
        printk(bc_drvinfo);
        /*
         * register net devices
@@ -920,8 +920,8 @@ int baycom_init(void)
                        set_hw = 0;
                if (!set_hw)
                        baycom_ports[i].iobase = baycom_ports[i].irq = 0;
-               j = hdlcdrv_register_hdlcdrv(dev, &dummy_ops, 
-                                            sizeof(struct baycom_state), 
+               j = hdlcdrv_register_hdlcdrv(dev, &dummy_ops,
+                                            sizeof(struct baycom_state),
                                             ifname, baycom_ports[i].iobase,
                                             baycom_ports[i].irq, 0);
                if (!j) {
@@ -949,6 +949,9 @@ int baycom_init(void)
 char *mode = NULL;
 int iobase = 0x3f8;
 int irq = 4;
+MODULE_PARM(mode, "s");
+MODULE_PARM(iobase, "i");
+MODULE_PARM(irq, "i");
 
 int init_module(void)
 {
@@ -974,7 +977,7 @@ void cleanup_module(void)
                        if (bc->hdrv.magic != HDLCDRV_MAGIC)
                                printk(KERN_ERR "baycom: invalid magic in "
                                       "cleanup_module\n");
-                       else 
+                       else
                                hdlcdrv_unregister_hdlcdrv(dev);
                }
        }
index b989b8ff77c846ed354511f9e1e551ddf9a72336..7e8f51ce7175dbcfd5fdea8bcbb9624246ef51d1 100644 (file)
@@ -54,7 +54,7 @@
     no great  consequence except do make sure  you're not sharing interrupts
     with  anything that cannot  accommodate  interrupt sharing! The existing
     register_netdevice() code will only allow one device to be registered at
-    a time. 
+    a time.
 
     ************************************************************************
     For now, please only use the 'io=??' assignment (see  2. below, ?? != 0)
@@ -64,7 +64,7 @@
     Essentially, the I/O address and IRQ information  are ignored and filled
     in later by  the PCI BIOS   during the PCI  probe.  Note  that the board
     should be in the system at boot time so that its I/O address and IRQ are
-    allocated by the PCI BIOS automatically. 
+    allocated by the PCI BIOS automatically.
 
     To utilise this ability, you have to do 8 things:
 
     when loading by:
 
                    insmod de4x5.o io=0xghh         where g = bus number
-                                                       hh = device number   
+                                                       hh = device number
 
     3) compile  de4x5.c, but include -DMODULE in  the command line to ensure
     that the correct bits are compiled (see end of source code).
     4) if you are wanting to add a new  card, goto 5. Otherwise, recompile a
     kernel with the de4x5 configuration turned off and reboot.
     5) insmod de4x5.o [io=0xghh]
-    6) run the net startup bits for your new eth?? interface(s) manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your new eth?? interface(s) manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
-    To unload a module, turn off the associated interface(s) 
+    To unload a module, turn off the associated interface(s)
     'ifconfig eth?? down' then 'rmmod de4x5'.
 
     Automedia detection is included so that in  principal you can disconnect
     ----------------
 
     Version   Date        Description
-  
+
       0.1     17-Nov-94   Initial writing. ALPHA code release.
       0.2     13-Jan-95   Added PCI support for DE435's.
       0.21    19-Jan-95   Added auto media detection.
                          Add request/release_region code.
                          Add loadable modules support for PCI.
                          Clean up loadable modules support.
-      0.23    28-Feb-95   Added DC21041 and DC21140 support. 
+      0.23    28-Feb-95   Added DC21041 and DC21140 support.
                           Fix missed frame counter value and initialisation.
                          Fixed EISA probe.
       0.24    11-Apr-95   Change delay routine to use <linux/udelay>.
                           Add kernel timer code (h/w is too flaky).
                          Add MII based PHY autosense.
                          Add new multicasting code.
-                         Add new autosense algorithms for media/mode 
+                         Add new autosense algorithms for media/mode
                          selection using kernel scheduling/timing.
                          Re-formatted.
                          Made changes suggested by <jeff@router.patch.net>:
                           Add Accton to the list of broken cards.
                          Fix TX under-run bug for non DC21140 chips.
                          Fix boot command probe bug in alloc_device() as
-                          reported by <koen.gadeyne@barco.com> and 
+                          reported by <koen.gadeyne@barco.com> and
                           <orava@nether.tky.hut.fi>.
                          Add cache locks to prevent a race condition as
-                          reported by <csd@microplex.com> and 
+                          reported by <csd@microplex.com> and
                           <baba@beckman.uiuc.edu>.
                          Upgraded alloc_device() code.
       0.431  28-Jun-96    Fix potential bug in queue_pkt() from discussion
                            with a loopback packet.
       0.442   9-Sep-96    Include AUI in dc21041 media printout. Bug reported
                            by <bhat@mundook.cs.mu.OZ.AU>
-      0.45    8-Dec-96    Include endian functions for PPC use, from work 
+      0.45    8-Dec-96    Include endian functions for PPC use, from work
                            by <cort@cs.nmt.edu>.
 
     =========================================================================
@@ -371,7 +371,7 @@ static s32 de4x5_full_duplex = 0;
 ** Memory Alignment. Each descriptor is 4 longwords long. To force a
 ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
 ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry. 
+** and hence the RX descriptor ring's first entry.
 */
 #define ALIGN4      ((u_long)4 - 1)     /* 1 longword align */
 #define ALIGN8      ((u_long)8 - 1)     /* 2 longword align */
@@ -720,9 +720,9 @@ de4x5_probe(struct device *dev)
 
     eisa_probe(dev, iobase);
     pci_probe(dev, iobase);
-    
+
     if ((tmp == num_de4x5s) && (iobase != 0) && loading_module) {
-       printk("%s: de4x5_probe() cannot find device at 0x%04lx.\n", dev->name, 
+       printk("%s: de4x5_probe() cannot find device at 0x%04lx.\n", dev->name,
               iobase);
     }
 
@@ -731,10 +731,10 @@ de4x5_probe(struct device *dev)
     ** initialised OK
     */
     for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-    
+
     if (dev->priv) status = 0;
     if (iobase == 0) autoprobed = 1;
-    
+
     return status;
 }
 
@@ -745,20 +745,20 @@ de4x5_hw_init(struct device *dev, u_long iobase)
     int tmpbus, tmpchs, status=0;
     int i, media = *((char *)&(lp->srom) + *((char *)&(lp->srom) + 19) * 3);
     char *tmp;
-    
+
     /* Ensure we're not sleeping */
     if (lp->chipset == DC21041) {
        outl(0, PCI_CFDA);
        de4x5_ms_delay(10);
     }
-    
+
     RESET_DE4X5;
-    
+
     if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0) {
        return -ENXIO;                       /* Hardware could not reset */
     }
-    
-    /* 
+
+    /*
     ** Now find out what kind of DC21040/DC21041/DC21140 board we have.
     */
     if (lp->bus == PCI) {
@@ -766,46 +766,46 @@ de4x5_hw_init(struct device *dev, u_long iobase)
     } else {
        EISA_signature(name, EISA_ID0);
     }
-    
+
     if (*name == '\0') {                     /* Not found a board signature */
        return -ENXIO;
     }
-    
+
     dev->base_addr = iobase;
     if (lp->bus == EISA) {
-       printk("%s: %s at 0x%04lx (EISA slot %ld)", 
+       printk("%s: %s at 0x%04lx (EISA slot %ld)",
               dev->name, name, iobase, ((iobase>>12)&0x0f));
     } else {                                 /* PCI port address */
        printk("%s: %s at 0x%04lx (PCI bus %d, device %d)", dev->name, name,
               iobase, lp->bus_num, lp->device);
     }
-    
+
     printk(", h/w address ");
     status = get_hw_addr(dev);
     for (i = 0; i < ETH_ALEN - 1; i++) {     /* get the ethernet addr. */
        printk("%2.2x:", dev->dev_addr[i]);
     }
     printk("%2.2x,\n", dev->dev_addr[i]);
-    
+
     tmpbus = lp->bus;
     tmpchs = lp->chipset;
-    
+
     if (status != 0) {
        printk("      which has an Ethernet PROM CRC error.\n");
        return -ENXIO;
     } else {
        struct de4x5_private *lp;
-       
-       /* 
+
+       /*
        ** Reserve a section of kernel memory for the adapter
        ** private area and the TX/RX descriptor rings.
        */
-       dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN, 
+       dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN,
                                     GFP_KERNEL);
        if (dev->priv == NULL) {
            return -ENOMEM;
        }
-       
+
        /*
        ** Align to a longword boundary
        */
@@ -828,7 +828,7 @@ de4x5_hw_init(struct device *dev, u_long iobase)
        } else {
            mii_get_phy(dev);                      /* Search the MII anyway! */
        }
-       
+
        /*
        ** Choose correct autosensing in case someone messed up
        */
@@ -847,12 +847,12 @@ de4x5_hw_init(struct device *dev, u_long iobase)
                lp->autosense = de4x5_autosense & 0x00c0;
            }
        }
-       
+
        sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
-       
+
        /*
        ** Set up the RX descriptor ring (Intels)
-       ** Allocate contiguous receive buffers, long word aligned (Alphas) 
+       ** Allocate contiguous receive buffers, long word aligned (Alphas)
        */
 #if !defined(__alpha__) && !defined(__powerpc__) && !defined(DE4X5_DO_MEMCPY)
        for (i=0; i<NUM_RX_DESC; i++) {
@@ -864,7 +864,7 @@ de4x5_hw_init(struct device *dev, u_long iobase)
        }
 
 #else
-       if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, 
+       if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN,
                                   GFP_KERNEL)) == NULL) {
            kfree(lp->cache.priv);
            return -ENOMEM;
@@ -882,22 +882,22 @@ de4x5_hw_init(struct device *dev, u_long iobase)
 #endif
 
        barrier();
-           
+
        request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE :
-                               DE4X5_EISA_TOTAL_SIZE), 
+                               DE4X5_EISA_TOTAL_SIZE),
                       lp->adapter_name);
-           
+
        lp->rxRingSize = NUM_RX_DESC;
        lp->txRingSize = NUM_TX_DESC;
-           
+
        /* Write the end of list marker to the descriptor lists */
        lp->rx_ring[lp->rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
        lp->tx_ring[lp->txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
-           
+
        /* Tell the adapter where the TX/RX rings are located. */
        outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
        outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-           
+
        /* Initialise the IRQ mask and Enable/Disable */
        lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM | IMR_UNM;
        lp->irq_en   = IMR_NIM | IMR_AIM;
@@ -918,11 +918,11 @@ de4x5_hw_init(struct device *dev, u_long iobase)
               ((lp->bus == PCI) ? "PCI BIOS" : "EISA CNFG"));
 
     }
-    
+
     if (de4x5_debug > 1) {
        printk(version);
     }
-    
+
     /* The DE4X5-specific entries in the device structure. */
     dev->open = &de4x5_open;
     dev->hard_start_xmit = &de4x5_queue_pkt;
@@ -930,18 +930,18 @@ de4x5_hw_init(struct device *dev, u_long iobase)
     dev->get_stats = &de4x5_get_stats;
     dev->set_multicast_list = &set_multicast_list;
     dev->do_ioctl = &de4x5_ioctl;
-    
+
     dev->mem_start = 0;
-    
+
     /* Fill in the generic field of the device structure. */
     ether_setup(dev);
-    
+
     /* Let the adapter sleep to save power */
     if (lp->chipset == DC21041) {
        outl(0, DE4X5_SICR);
        outl(CFDA_PSM, PCI_CFDA);
     }
-    
+
     return status;
 }
 
@@ -953,7 +953,7 @@ de4x5_open(struct device *dev)
     u_long iobase = dev->base_addr;
     int i, status = 0;
     s32 omr;
-    
+
     /* Allocate the RX buffers */
     for (i=0; i<lp->rxRingSize; i++) {
        if (de4x5_alloc_rx_buff(dev, i, 0) == NULL) {
@@ -970,29 +970,29 @@ de4x5_open(struct device *dev)
        de4x5_ms_delay(10);
     }
 
-    /* 
-    ** Re-initialize the DE4X5... 
+    /*
+    ** Re-initialize the DE4X5...
     */
     status = de4x5_init(dev);
-    
+
     lp->state = OPEN;
     de4x5_dbg_open(dev);
-    
-    if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, 
+
+    if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ,
                                                     lp->adapter_name, dev)) {
        printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
        status = -EAGAIN;
     } else {
-       dev->tbusy = 0;                         
+       dev->tbusy = 0;
        dev->start = 1;
        dev->interrupt = UNMASK_INTERRUPTS;
        dev->trans_start = jiffies;
-       
+
        START_DE4X5;
-       
+
        de4x5_setup_intr(dev);
     }
-    
+
     if (de4x5_debug > 1) {
        printk("\tsts:  0x%08x\n", inl(DE4X5_STS));
        printk("\tbmr:  0x%08x\n", inl(DE4X5_BMR));
@@ -1003,9 +1003,9 @@ de4x5_open(struct device *dev)
        printk("\tstrr: 0x%08x\n", inl(DE4X5_STRR));
        printk("\tsigr: 0x%08x\n", inl(DE4X5_SIGR));
     }
-    
+
     MOD_INC_USE_COUNT;
-    
+
     return status;
 }
 
@@ -1019,15 +1019,15 @@ de4x5_open(struct device *dev)
 */
 static int
 de4x5_init(struct device *dev)
-{  
+{
     /* Lock out other processes whilst setting up the hardware */
     set_bit(0, (void *)&dev->tbusy);
-    
+
     de4x5_sw_reset(dev);
-    
+
     /* Autoconfigure the connected port */
     autoconf_media(dev);
-    
+
     return 0;
 }
 
@@ -1038,22 +1038,22 @@ de4x5_sw_reset(struct device *dev)
     u_long iobase = dev->base_addr;
     int i, j, status = 0;
     s32 bmr, omr;
-    
+
     /* Select the MII or SRL port now and RESET the MAC */
     if (lp->phy[lp->active].id == 0) {
        de4x5_switch_to_srl(dev);
     } else {
        de4x5_switch_to_mii(dev);
     }
-    
-    /* 
+
+    /*
     ** Set the programmable burst length to 8 longwords for all the DC21140
     ** Fasternet chips and 4 longwords for all others: DMA errors result
     ** without these values. Cache align 16 long.
     */
     bmr = (lp->chipset==DC21140 ? PBL_8 : PBL_4) | DESC_SKIP_LEN | CACHE_ALIGN;
     outl(bmr, DE4X5_BMR);
-    
+
     omr = inl(DE4X5_OMR) & ~OMR_PR;             /* Turn off promiscuous mode */
     if (lp->chipset == DC21140) {
        omr |= (OMR_SDP | OMR_SB);
@@ -1061,26 +1061,26 @@ de4x5_sw_reset(struct device *dev)
     lp->setup_f = PERFECT;
     outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
     outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-    
+
     lp->rx_new = lp->rx_old = 0;
     lp->tx_new = lp->tx_old = 0;
-    
+
     for (i = 0; i < lp->rxRingSize; i++) {
        lp->rx_ring[i].status = cpu_to_le32(R_OWN);
     }
-    
+
     for (i = 0; i < lp->txRingSize; i++) {
        lp->tx_ring[i].status = cpu_to_le32(0);
     }
-    
+
     barrier();
-    
+
     /* Build the setup frame depending on filtering mode */
     SetMulticastFilter(dev);
-    
+
     load_packet(dev, lp->setup_frame, PERFECT_F|TD_SET|SETUP_FRAME_LEN, NULL);
     outl(omr|OMR_ST, DE4X5_OMR);
-    
+
     /* Poll for setup frame completion (adapter interrupts are disabled now) */
     sti();                                       /* Ensure timer interrupts */
     for (j=0, i=0;(i<500) && (j==0);i++) {       /* Upto 500ms delay */
@@ -1088,20 +1088,20 @@ de4x5_sw_reset(struct device *dev)
        if ((s32)le32_to_cpu(lp->tx_ring[lp->tx_new].status) >= 0) j=1;
     }
     outl(omr, DE4X5_OMR);                        /* Stop everything! */
-    
+
     if (j == 0) {
-       printk("%s: Setup frame timed out, status %08x\n", dev->name, 
+       printk("%s: Setup frame timed out, status %08x\n", dev->name,
               inl(DE4X5_STS));
        status = -EIO;
     }
-    
+
     lp->tx_new = (++lp->tx_new) % lp->txRingSize;
     lp->tx_old = lp->tx_new;
-    
+
     return status;
 }
 
-/* 
+/*
 ** Writes a socket buffer address to the next available transmit descriptor
 */
 static int
@@ -1118,9 +1118,9 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
 
     set_bit(0, (void*)&dev->tbusy);              /* Stop send re-tries */
     if (lp->tx_enable == NO) {                   /* Cannot send for now */
-       return -1;                                
+       return -1;
     }
-    
+
     /*
     ** Clean out the TX ring asynchronously to interrupts - sometimes the
     ** interrupts are lost by delayed descriptor status updates relative to
@@ -1155,10 +1155,10 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
            set_bit(0, (void*)&dev->tbusy);
            load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb);
            outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */
-               
+
            lp->tx_new = (++lp->tx_new) % lp->txRingSize;
            dev->trans_start = jiffies;
-                   
+
            if (TX_BUFFS_AVAIL) {
                dev->tbusy = 0;         /* Another pkt may be queued */
            }
@@ -1167,15 +1167,15 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
        }
        if (skb) de4x5_putb_cache(dev, skb);
     }
-    
+
     lp->cache.lock = 0;
 
     return status;
 }
 
 /*
-** The DE4X5 interrupt handler. 
-** 
+** The DE4X5 interrupt handler.
+**
 ** I/O Read/Writes through intermediate PCI bridges are never 'posted',
 ** so that the asserted interrupt always has some real data to work with -
 ** if these I/O accesses are ever changed to memory accesses, ensure the
@@ -1191,41 +1191,41 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     struct de4x5_private *lp;
     s32 imr, omr, sts, limit;
     u_long iobase;
-    
+
     if (dev == NULL) {
        printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq);
        return;
     }
     lp = (struct de4x5_private *)dev->priv;
     iobase = dev->base_addr;
-       
+
     if (dev->interrupt)
       printk("%s: Re-entering the interrupt handler.\n", dev->name);
-       
+
     DISABLE_IRQs;                        /* Ensure non re-entrancy */
     dev->interrupt = MASK_INTERRUPTS;
-       
+
     for (limit=0; limit<8; limit++) {
        sts = inl(DE4X5_STS);            /* Read IRQ status */
        outl(sts, DE4X5_STS);            /* Reset the board interrupts */
-           
+
        if (!(sts & lp->irq_mask)) break;/* All done */
-           
+
        if (sts & (STS_RI | STS_RU))     /* Rx interrupt (packet[s] arrived) */
          de4x5_rx(dev);
-           
+
        if (sts & (STS_TI | STS_TU))     /* Tx interrupt (packet sent) */
-         de4x5_tx(dev); 
-           
+         de4x5_tx(dev);
+
        if (sts & STS_LNF) {             /* TP Link has failed */
            lp->lostMedia = LOST_MEDIA_THRESHOLD + 1;
            lp->irq_mask &= ~IMR_LFM;
        }
-           
+
        if (sts & STS_UNF) {             /* Transmit underrun */
            de4x5_txur(dev);
        }
-           
+
        if (sts & STS_SE) {              /* Bus Error */
            STOP_DE4X5;
            printk("%s: Fatal bus error occurred, sts=%#8x, device stopped.\n",
@@ -1244,7 +1244,7 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
     dev->interrupt = UNMASK_INTERRUPTS;
     ENABLE_IRQs;
-    
+
     return;
 }
 
@@ -1255,11 +1255,11 @@ de4x5_rx(struct device *dev)
     u_long iobase = dev->base_addr;
     int entry;
     s32 status;
-    
+
     for (entry=lp->rx_new; (s32)le32_to_cpu(lp->rx_ring[entry].status)>=0;
                                                            entry=lp->rx_new) {
        status = (s32)le32_to_cpu(lp->rx_ring[entry].status);
-       
+
        if (lp->rx_ovf) {
            if (inl(DE4X5_MFC) & MFC_FOCM) {
                de4x5_rx_ovfc(dev);
@@ -1270,7 +1270,7 @@ de4x5_rx(struct device *dev)
        if (status & RD_FS) {                 /* Remember the start of frame */
            lp->rx_old = entry;
        }
-       
+
        if (status & RD_LS) {                 /* Valid frame status */
            lp->linkOK++;
            if (status & RD_ES) {             /* There was an error. */
@@ -1287,9 +1287,9 @@ de4x5_rx(struct device *dev)
                struct sk_buff *skb;
                short pkt_len = (short)(le32_to_cpu(lp->rx_ring[entry].status)
                                                                    >> 16) - 4;
-               
+
                if ((skb = de4x5_alloc_rx_buff(dev, entry, pkt_len)) == NULL) {
-                   printk("%s: Insufficient memory; nuking packet.\n", 
+                   printk("%s: Insufficient memory; nuking packet.\n",
                                                                    dev->name);
                    lp->stats.rx_dropped++;   /* Really, deferred. */
                    break;
@@ -1299,12 +1299,12 @@ de4x5_rx(struct device *dev)
                /* Push up the protocol stack */
                skb->protocol=eth_type_trans(skb,dev);
                netif_rx(skb);
-                   
+
                /* Update stats */
                lp->stats.rx_packets++;
                de4x5_local_stats(dev, skb->data, pkt_len);
            }
-           
+
            /* Change buffer ownership for this frame, back to the adapter */
            for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) {
                lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN);
@@ -1313,13 +1313,13 @@ de4x5_rx(struct device *dev)
            lp->rx_ring[entry].status = cpu_to_le32(R_OWN);
            barrier();
        }
-       
+
        /*
        ** Update entry information
        */
        lp->rx_new = (++lp->rx_new) % lp->rxRingSize;
     }
-    
+
     return 0;
 }
 
@@ -1333,20 +1333,20 @@ de4x5_tx(struct device *dev)
     u_long iobase = dev->base_addr;
     int entry;
     s32 status;
-    
+
     for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
        status = (s32)le32_to_cpu(lp->tx_ring[entry].status);
        if (status < 0) {                     /* Buffer not sent yet */
            break;
        } else if (status != 0x7fffffff) {    /* Not setup frame */
            if (status & TD_ES) {             /* An error happened */
-               lp->stats.tx_errors++; 
+               lp->stats.tx_errors++;
                if (status & TD_NC) lp->stats.tx_carrier_errors++;
                if (status & TD_LC) lp->stats.tx_window_errors++;
                if (status & TD_UF) lp->stats.tx_fifo_errors++;
                if (status & TD_EC) lp->pktStats.excessive_collisions++;
                if (status & TD_DE) lp->stats.tx_aborted_errors++;
-           
+
                if (status & (TD_LO | TD_NC | TD_EC | TD_LF)) {
                    lp->lostMedia++;
                }
@@ -1359,7 +1359,7 @@ de4x5_tx(struct device *dev)
                lp->linkOK++;
            }
            /* Update the collision counter */
-           lp->stats.collisions += ((status & TD_EC) ? 16 : 
+           lp->stats.collisions += ((status & TD_EC) ? 16 :
                                                      ((status & TD_CC) >> 3));
 
            /* Free the buffer. */
@@ -1368,7 +1368,7 @@ de4x5_tx(struct device *dev)
                lp->tx_skb[entry] = NULL;
            }
        }
-       
+
        /* Update all the pointers */
        lp->tx_old = (++lp->tx_old) % lp->txRingSize;
     }
@@ -1377,7 +1377,7 @@ de4x5_tx(struct device *dev)
        dev->tbusy = 0;                  /* Clear TX busy flag */
        if (dev->interrupt) mark_bh(NET_BH);
     }
-       
+
     return 0;
 }
 
@@ -1386,9 +1386,9 @@ de4x5_ast(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int next_tick = DE4X5_AUTOSENSE_MS;
-    
+
     disable_ast(dev);
-    
+
     if (lp->chipset == DC21140) {
        next_tick = dc21140m_autoconf(dev);
     } else if (lp->chipset == DC21041) {
@@ -1398,7 +1398,7 @@ de4x5_ast(struct device *dev)
     }
     lp->linkOK = 0;
     enable_ast(dev, next_tick);
-    
+
     return 0;
 }
 
@@ -1421,11 +1421,11 @@ de4x5_txur(struct device *dev)
        }
        outl(omr | OMR_ST | OMR_SR, DE4X5_OMR);
     }
-    
+
     return 0;
 }
 
-static int 
+static int
 de4x5_rx_ovfc(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
@@ -1442,7 +1442,7 @@ de4x5_rx_ovfc(struct device *dev)
     }
 
     outl(omr, DE4X5_OMR);
-    
+
     return 0;
 }
 
@@ -1452,22 +1452,22 @@ de4x5_close(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 imr, omr;
-    
+
     disable_ast(dev);
     dev->start = 0;
     dev->tbusy = 1;
-    
+
     if (de4x5_debug > 1) {
        printk("%s: Shutting down ethercard, status was %8.8x.\n",
               dev->name, inl(DE4X5_STS));
     }
-    
-    /* 
+
+    /*
     ** We stop the DE4X5 here... mask interrupts and stop TX & RX
     */
     DISABLE_IRQs;
     STOP_DE4X5;
-    
+
     /* Free the associated irq */
     free_irq(dev->irq, dev);
     lp->state = CLOSED;
@@ -1475,15 +1475,15 @@ de4x5_close(struct device *dev)
     /* Free any socket buffers */
     de4x5_free_rx_buffs(dev);
     de4x5_free_tx_buffs(dev);
-    
+
     MOD_DEC_USE_COUNT;
-    
+
     /* Put the adapter to sleep to save power */
     if (lp->chipset == DC21041) {
        outl(0, DE4X5_SICR);
        outl(CFDA_PSM, PCI_CFDA);
     }
-    
+
     return 0;
 }
 
@@ -1492,9 +1492,9 @@ de4x5_get_stats(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     lp->stats.rx_missed_errors = (int)(inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR));
-    
+
     return &lp->stats;
 }
 
@@ -1520,7 +1520,7 @@ de4x5_local_stats(struct device *dev, char *buf, int pkt_len)
               (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
         lp->pktStats.unicast++;
     }
-               
+
     lp->pktStats.bins[0]++;       /* Duplicates stats.rx_packets */
     if (lp->pktStats.bins[0] == 0) { /* Reset counters */
         memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
@@ -1533,7 +1533,7 @@ static void
 load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     lp->tx_ring[lp->tx_new].buf = cpu_to_le32(virt_to_bus(buf));
     lp->tx_ring[lp->tx_new].des1 &= cpu_to_le32(TD_TER);
     lp->tx_ring[lp->tx_new].des1 |= cpu_to_le32(flags);
@@ -1541,7 +1541,7 @@ load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb)
     barrier();
     lp->tx_ring[lp->tx_new].status = cpu_to_le32(T_OWN);
     barrier();
-    
+
     return;
 }
 
@@ -1553,7 +1553,7 @@ set_multicast_list(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     /* First, double check that the adapter is open */
     if (lp->state == OPEN) {
        if (dev->flags & IFF_PROMISC) {         /* set promiscuous mode */
@@ -1561,17 +1561,17 @@ set_multicast_list(struct device *dev)
            omr = inl(DE4X5_OMR);
            omr |= OMR_PR;
            outl(omr, DE4X5_OMR);
-       } else { 
+       } else {
            SetMulticastFilter(dev);
-           load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
+           load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
                                                        SETUP_FRAME_LEN, NULL);
-           
+
            lp->tx_new = (++lp->tx_new) % lp->txRingSize;
            outl(POLL_DEMAND, DE4X5_TPD);       /* Start the TX */
            dev->trans_start = jiffies;
        }
     }
-    
+
     return;
 }
 
@@ -1591,30 +1591,30 @@ SetMulticastFilter(struct device *dev)
     u32 omr, crc, poly = CRC_POLYNOMIAL_LE;
     char *pa;
     unsigned char *addrs;
-    
+
     omr = inl(DE4X5_OMR);
     omr &= ~(OMR_PR | OMR_PM);
     pa = build_setup_frame(dev, ALL);        /* Build the basic frame */
-    
+
     if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
        omr |= OMR_PM;                       /* Pass all multicasts */
     } else if (lp->setup_f == HASH_PERF) {   /* Hash Filtering */
        for (i=0;i<dev->mc_count;i++) {      /* for each address in the list */
            addrs=dmi->dmi_addr;
            dmi=dmi->next;
-           if ((*addrs & 0x01) == 1) {      /* multicast address? */ 
+           if ((*addrs & 0x01) == 1) {      /* multicast address? */
                crc = 0xffffffff;            /* init CRC for each address */
                for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-                                            /* process each address bit */ 
+                                            /* process each address bit */
                    for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
                        crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
                    }
                }
                hashcode = crc & HASH_BITS;  /* hashcode is 9 LSb of CRC */
-               
+
                byte = hashcode >> 3;        /* bit[3-8] -> byte in filter */
                bit = 1 << (hashcode & 0x07);/* bit[0-2] -> bit in byte */
-               
+
                byte <<= 1;                  /* calc offset into setup frame */
                if (byte & 0x02) {
                    byte -= 1;
@@ -1626,14 +1626,14 @@ SetMulticastFilter(struct device *dev)
        for (j=0; j<dev->mc_count; j++) {
            addrs=dmi->dmi_addr;
            dmi=dmi->next;
-           for (i=0; i<ETH_ALEN; i++) { 
+           for (i=0; i<ETH_ALEN; i++) {
                *(pa + (i&1)) = *addrs++;
                if (i & 0x01) pa += 4;
            }
        }
     }
     outl(omr, DE4X5_OMR);
-    
+
     return;
 }
 
@@ -1651,11 +1651,11 @@ eisa_probe(struct device *dev, u_long ioaddr)
     struct bus_type *lp = &bus;
     char name[DE4X5_STRLEN];
     struct device *tmp;
-    
+
     if (!ioaddr && autoprobed) return;     /* Been here before ! */
-    
+
     lp->bus = EISA;
-    
+
     if (ioaddr == 0) {                     /* Autoprobing */
        iobase = EISA_SLOT_INC;            /* Get the first slot address */
        i = 1;
@@ -1665,14 +1665,14 @@ eisa_probe(struct device *dev, u_long ioaddr)
        i = (ioaddr >> 12);
        maxSlots = i + 1;
     }
-    
+
     for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
        if (EISA_signature(name, EISA_ID)) {
            cfid = inl(PCI_CFID);
            cfrv = inl(PCI_CFRV);
            device = (u_short)(cfid >> 16);
            vendor = (u_short) cfid;
-           
+
            /* Read the EISA Configuration Registers */
            dev->irq = inb(EISA_REG0);
            dev->irq = de4x5_irq[(dev->irq >> 1) & 0x03];
@@ -1683,7 +1683,7 @@ eisa_probe(struct device *dev, u_long ioaddr)
            outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
            outl(0x00006000, PCI_CFLT);
            outl(iobase, PCI_CBIO);
-           
+
            if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) {
                if ((tmp = alloc_device(dev, iobase)) != NULL) {
                    if ((status = de4x5_hw_init(tmp, iobase)) == 0) {
@@ -1695,7 +1695,7 @@ eisa_probe(struct device *dev, u_long ioaddr)
            }
        }
     }
-    
+
     return;
 }
 
@@ -1726,11 +1726,11 @@ pci_probe(struct device *dev, u_long ioaddr)
     struct device *tmp;
 
     if ((!ioaddr || !loading_module) && autoprobed) return;
-    
+
     if (!pcibios_present()) return;          /* No PCI bus in this machine! */
-    
+
     lp->bus = PCI;
-    
+
     if ((ioaddr < 0x1000) && loading_module) {
        pbus = (u_short)(ioaddr >> 8);
        dnum = (u_short)(ioaddr & 0xff);
@@ -1739,11 +1739,11 @@ pci_probe(struct device *dev, u_long ioaddr)
        dnum = 0;
     }
 
-    for (index=0; 
+    for (index=0;
         (pcibios_find_class(class, index, &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND);
         index++) {
        dev_num = PCI_SLOT(dev_fn);
-       
+
        if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) {
            pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor);
            pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &device);
@@ -1752,10 +1752,10 @@ pci_probe(struct device *dev, u_long ioaddr)
            /* Set the device number information */
            lp->device = dev_num;
            lp->bus_num = pb;
-           
+
            /* Set the chipset information */
            lp->chipset = device;
-           
+
            /* Get the chip configuration revision register */
            pcibios_read_config_dword(pb, PCI_DEVICE, PCI_REVISION_ID, &cfrv);
 
@@ -1766,7 +1766,7 @@ pci_probe(struct device *dev, u_long ioaddr)
            /* Fetch the IRQ to be used */
            pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &irq);
            if ((irq == 0) || (irq == (u_char) 0xff)) continue;
-           
+
            /* Check if I/O accesses and Bus Mastering are enabled */
            pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status);
            if (!(status & PCI_COMMAND_IO)) continue;
@@ -1786,12 +1786,12 @@ pci_probe(struct device *dev, u_long ioaddr)
                    }
                }
            } else if (autoprobed) {
-               printk("%s: region already allocated at 0x%04x.\n", dev->name, 
+               printk("%s: region already allocated at 0x%04x.\n", dev->name,
                       (u_short)iobase);
            }
        }
     }
-    
+
     return;
 }
 
@@ -1809,7 +1809,7 @@ alloc_device(struct device *dev, u_long iobase)
 
     num_eth = de4x5_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
        if (((dev->base_addr == DE4X5_NDA) || (dev->base_addr==0)) && !adev) {
            adev=dev;
@@ -1832,13 +1832,13 @@ alloc_device(struct device *dev, u_long iobase)
        new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
        ((dev->base_addr != DE4X5_NDA) && (dev->base_addr != 0)) && !fixed) ||
        new_dev) {
        num_eth++;                         /* New device */
        dev = insert_device(dev, iobase, de4x5_probe);
     }
-    
+
     return dev;
 }
 
@@ -1891,7 +1891,7 @@ de4x5_dev_index(char *s)
 ** Auto configure the media here rather than setting the port at compile
 ** time. This routine is called by de4x5_init() and when a loss of media is
 ** detected (excessive collisions, loss of carrier, no carrier or link fail
-** [TP] or no recent receive activity) to check whether the user has been 
+** [TP] or no recent receive activity) to check whether the user has been
 ** sneaky and changed the port on us.
 */
 static int
@@ -1900,7 +1900,7 @@ autoconf_media(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;;
-    
+
     lp->linkOK = 0;
     lp->c_media = AUTO;                     /* Bogus last media */
     disable_ast(dev);
@@ -1914,7 +1914,7 @@ autoconf_media(struct device *dev)
        next_tick = dc21140m_autoconf(dev);
     }
     enable_ast(dev, next_tick);
-    
+
     return (lp->media);
 }
 
@@ -1937,7 +1937,7 @@ dc21040_autoconf(struct device *dev)
     u_long iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;
     s32 imr;
-    
+
     switch (lp->media) {
       case INIT:
        DISABLE_IRQs;
@@ -1956,36 +1956,36 @@ dc21040_autoconf(struct device *dev)
        lp->local_state = 0;
        next_tick = dc21040_autoconf(dev);
        break;
-       
+
       case TP:
-       next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI, 
+       next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI,
                                                         TP_SUSPECT, test_tp);
        break;
-       
+
       case TP_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21040_autoconf);
        break;
-       
+
       case BNC:
       case AUI:
       case BNC_AUI:
-       next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA, 
+       next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA,
                                                  BNC_AUI_SUSPECT, ping_media);
        break;
-       
+
       case BNC_AUI_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, BNC_AUI, ping_media, dc21040_autoconf);
        break;
-       
+
       case EXT_SIA:
-       next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000, 
+       next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000,
                                              NC, EXT_SIA_SUSPECT, ping_media);
        break;
-       
+
       case EXT_SIA_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, EXT_SIA, ping_media, dc21040_autoconf);
        break;
-       
+
       case NC:
        /* default to TP for all */
        reset_init_sia(dev, 0x8f01, 0xffff, 0x0000);
@@ -1997,13 +1997,13 @@ dc21040_autoconf(struct device *dev)
        lp->tx_enable = NO;
        break;
     }
-    
+
     return next_tick;
 }
 
 static int
 dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout,
-             int next_state, int suspect_state, 
+             int next_state, int suspect_state,
              int (*fn)(struct device *, int))
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
@@ -2016,7 +2016,7 @@ dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout,
        lp->local_state++;
        next_tick = 500;
        break;
-           
+
       case 1:
        if (!lp->tx_enable) {
            linkBad = fn(dev, timeout);
@@ -2036,7 +2036,7 @@ dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout,
        }
        break;
     }
-    
+
     return next_tick;
 }
 
@@ -2090,7 +2090,7 @@ dc21041_autoconf(struct device *dev)
     u_long iobase = dev->base_addr;
     s32 sts, irqs, irq_mask, imr, omr;
     int next_tick = DE4X5_AUTOSENSE_MS;
-    
+
     switch (lp->media) {
       case INIT:
        DISABLE_IRQs;
@@ -2111,7 +2111,7 @@ dc21041_autoconf(struct device *dev)
        lp->local_state = 0;
        next_tick = dc21041_autoconf(dev);
        break;
-       
+
       case TP_NW:
        if (lp->timeout < 0) {
            omr = inl(DE4X5_OMR);/* Set up full duplex for the autonegotiate */
@@ -2131,7 +2131,7 @@ dc21041_autoconf(struct device *dev)
            next_tick = dc21041_autoconf(dev);
        }
        break;
-       
+
       case ANS:
        if (!lp->tx_enable) {
            irqs = STS_LNP;
@@ -2153,11 +2153,11 @@ dc21041_autoconf(struct device *dev)
            next_tick = 3000;
        }
        break;
-       
+
       case ANS_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, ANS, test_tp, dc21041_autoconf);
        break;
-       
+
       case TP:
        if (!lp->tx_enable) {
            if (lp->timeout < 0) {
@@ -2187,11 +2187,11 @@ dc21041_autoconf(struct device *dev)
            next_tick = 3000;
        }
        break;
-       
+
       case TP_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21041_autoconf);
        break;
-       
+
       case AUI:
        if (!lp->tx_enable) {
            if (lp->timeout < 0) {
@@ -2217,11 +2217,11 @@ dc21041_autoconf(struct device *dev)
            next_tick = 3000;
        }
        break;
-       
+
       case AUI_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc21041_autoconf);
        break;
-       
+
       case BNC:
        switch (lp->local_state) {
          case 0:
@@ -2239,7 +2239,7 @@ dc21041_autoconf(struct device *dev)
                next_tick = dc21041_autoconf(dev);
            }
            break;
-           
+
          case 1:
            if (!lp->tx_enable) {
                if ((sts = ping_media(dev, 3000)) < 0) {
@@ -2259,11 +2259,11 @@ dc21041_autoconf(struct device *dev)
            break;
        }
        break;
-       
+
       case BNC_SUSPECT:
        next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc21041_autoconf);
        break;
-       
+
       case NC:
        omr = inl(DE4X5_OMR);    /* Set up full duplex for the autonegotiate */
        outl(omr | OMR_FD, DE4X5_OMR);
@@ -2276,7 +2276,7 @@ dc21041_autoconf(struct device *dev)
        lp->tx_enable = NO;
        break;
     }
-    
+
     return next_tick;
 }
 
@@ -2292,9 +2292,9 @@ dc21140m_autoconf(struct device *dev)
     int ana, anlpa, cap, cr, slnk, sr, iobase = dev->base_addr;
     int next_tick = DE4X5_AUTOSENSE_MS;
     u_long imr, omr;
-    
+
     switch(lp->media) {
-      case INIT: 
+      case INIT:
        DISABLE_IRQs;
        lp->tx_enable = FALSE;
        lp->timeout = -1;
@@ -2308,7 +2308,7 @@ dc21140m_autoconf(struct device *dev)
                lp->media = _100Mb;
            } else if (lp->autosense == _10Mb) {
                lp->media = _10Mb;
-           } else if ((lp->autosense == AUTO) && 
+           } else if ((lp->autosense == AUTO) &&
                                     ((sr=is_anc_capable(dev)) & MII_SR_ANC)) {
                ana = (((sr >> 6) & MII_ANA_TAF) | MII_ANA_CSMA);
                ana &= (de4x5_full_duplex ? ~0 : ~MII_ANA_FDAM);
@@ -2325,7 +2325,7 @@ dc21140m_autoconf(struct device *dev)
            next_tick = dc21140m_autoconf(dev);
        }
        break;
-       
+
       case ANS:
        switch (lp->local_state) {
          case 0:
@@ -2345,7 +2345,7 @@ dc21140m_autoconf(struct device *dev)
                next_tick = dc21140m_autoconf(dev);
            }
            break;
-           
+
          case 1:
            if ((sr=test_mii_reg(dev, MII_SR, MII_SR_ASSC, TRUE, 2000)) < 0) {
                next_tick = sr & ~TIMER_CB;
@@ -2356,7 +2356,7 @@ dc21140m_autoconf(struct device *dev)
                    lp->tmp = MII_SR_ASSC;
                    anlpa = mii_rd(MII_ANLPA, lp->phy[lp->active].addr, DE4X5_MII);
                    ana = mii_rd(MII_ANA, lp->phy[lp->active].addr, DE4X5_MII);
-                   if (!(anlpa & MII_ANLPA_RF) && 
+                   if (!(anlpa & MII_ANLPA_RF) &&
                         (cap = anlpa & MII_ANLPA_TAF & ana)) {
                        if (cap & MII_ANA_100M) {
                            de4x5_full_duplex = ((ana & anlpa & MII_ANA_FDAM & MII_ANA_100M) ? TRUE : FALSE);
@@ -2373,7 +2373,7 @@ dc21140m_autoconf(struct device *dev)
            break;
        }
        break;
-       
+
       case SPD_DET:                              /* Choose 10Mb/s or 100Mb/s */
         if (lp->timeout < 0) {
            lp->tmp = (lp->phy[lp->active].id ? MII_SR_LKS :
@@ -2393,7 +2393,7 @@ dc21140m_autoconf(struct device *dev)
            next_tick = dc21140m_autoconf(dev);
        }
        break;
-       
+
       case _100Mb:                               /* Set 100Mb/s */
        next_tick = 3000;
        if (!lp->tx_enable) {
@@ -2408,7 +2408,7 @@ dc21140m_autoconf(struct device *dev)
            }
        }
        break;
-       
+
       case _10Mb:                                /* Set 10Mb/s */
        next_tick = 3000;
        if (!lp->tx_enable) {
@@ -2423,7 +2423,7 @@ dc21140m_autoconf(struct device *dev)
            }
        }
        break;
-       
+
       case NC:
         if (lp->media != lp->c_media) {
            de4x5_dbg_media(dev);
@@ -2433,7 +2433,7 @@ dc21140m_autoconf(struct device *dev)
        lp->tx_enable = FALSE;
        break;
     }
-    
+
     return next_tick;
 }
 
@@ -2478,7 +2478,7 @@ de4x5_reset_phy(struct device *dev)
        }
        next_tick = test_mii_reg(dev, MII_CR, MII_CR_RST, FALSE, 500);
     }
-    
+
     return next_tick;
 }
 
@@ -2488,7 +2488,7 @@ test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 sts, csr12;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
        reset_init_sia(dev, csr13, csr14, csr15);
@@ -2499,22 +2499,22 @@ test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32
        /* clear all pending interrupts */
        sts = inl(DE4X5_STS);
        outl(sts, DE4X5_STS);
-       
+
        /* clear csr12 NRA and SRA bits */
        if (lp->chipset == DC21041) {
            csr12 = inl(DE4X5_SISR);
            outl(csr12, DE4X5_SISR);
        }
     }
-    
+
     sts = inl(DE4X5_STS) & ~TIMER_CB;
-    
+
     if (!(sts & irqs) && --lp->timeout) {
        sts = 100 | TIMER_CB;
     } else {
        lp->timeout = -1;
     }
-    
+
     return sts;
 }
 
@@ -2524,11 +2524,11 @@ test_tp(struct device *dev, s32 msec)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int sisr;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
     }
-    
+
     sisr = (inl(DE4X5_SISR) & ~TIMER_CB) & (SISR_LKF | SISR_NCR);
 
     if (sisr && --lp->timeout) {
@@ -2536,7 +2536,7 @@ test_tp(struct device *dev, s32 msec)
     } else {
        lp->timeout = -1;
     }
-    
+
     return sisr;
 }
 
@@ -2546,11 +2546,11 @@ test_sym_link(struct device *dev, int msec)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     int gep = 0;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
     }
-    
+
     if (lp->phy[lp->active].id) {
        gep = ((is_100_up(dev) && is_spd_100(dev)) ? GEP_SLNK : 0);
     } else {
@@ -2561,7 +2561,7 @@ test_sym_link(struct device *dev, int msec)
     } else {
        lp->timeout = -1;
     }
-    
+
     return gep;
 }
 
@@ -2574,21 +2574,21 @@ test_mii_reg(struct device *dev, int reg, int mask, int pol, long msec)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int test, iobase = dev->base_addr;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
     }
-    
+
     if (pol) pol = ~0;
     reg = mii_rd((u_char)reg, lp->phy[lp->active].addr, DE4X5_MII) & mask;
     test = (reg ^ pol) & mask;
-    
+
     if (test && --lp->timeout) {
        reg = 100 | TIMER_CB;
     } else {
        lp->timeout = -1;
     }
-    
+
     return reg;
 }
 
@@ -2598,7 +2598,7 @@ is_spd_100(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int spd;
-    
+
     if (lp->phy[lp->active].id) {
        spd = mii_rd(lp->phy[lp->active].spd.reg, lp->phy[lp->active].addr, DE4X5_MII);
        spd = ~(spd ^ lp->phy[lp->active].spd.value);
@@ -2606,7 +2606,7 @@ is_spd_100(struct device *dev)
     } else {
        spd = ((~inl(DE4X5_GEP)) & GEP_SLNK);
     }
-    
+
     return spd;
 }
 
@@ -2615,7 +2615,7 @@ is_100_up(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
        /* Double read for sticky bits & temporary drops */
        mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
@@ -2630,7 +2630,7 @@ is_10_up(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
        /* Double read for sticky bits & temporary drops */
        mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII);
@@ -2645,7 +2645,7 @@ is_anc_capable(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     if (lp->phy[lp->active].id) {
        return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII));
     } else {
@@ -2663,24 +2663,24 @@ ping_media(struct device *dev, int msec)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     int sisr;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
-       
+
        lp->tmp = lp->tx_new;                /* Remember the ring position */
        load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), NULL);
        lp->tx_new = (++lp->tx_new) % lp->txRingSize;
        outl(POLL_DEMAND, DE4X5_TPD);
     }
-    
+
     sisr = inl(DE4X5_SISR);
 
-    if ((!(sisr & SISR_NCR)) && 
-       ((s32)le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) && 
+    if ((!(sisr & SISR_NCR)) &&
+       ((s32)le32_to_cpu(lp->tx_ring[lp->tmp].status) < 0) &&
         (--lp->timeout)) {
        sisr = 100 | TIMER_CB;
     } else {
-       if ((!(sisr & SISR_NCR)) && 
+       if ((!(sisr & SISR_NCR)) &&
            !(le32_to_cpu(lp->tx_ring[lp->tmp].status) & (T_OWN | TD_ES)) &&
            lp->timeout) {
            sisr = 0;
@@ -2689,7 +2689,7 @@ ping_media(struct device *dev, int msec)
        }
        lp->timeout = -1;
     }
-    
+
     return sisr;
 }
 
@@ -2736,15 +2736,15 @@ de4x5_alloc_rx_buff(struct device *dev, int index, int len)
     skb_reserve(p, 2);                                /* Align */
     if (index < lp->rx_old) {                          /* Wrapped buffer */
        short tlen = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ;
-       memcpy(skb_put(p,tlen), 
+       memcpy(skb_put(p,tlen),
               bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),tlen);
-       memcpy(skb_put(p,len-tlen), 
+       memcpy(skb_put(p,len-tlen),
               bus_to_virt(le32_to_cpu(lp->rx_ring[0].buf)), len-tlen);
     } else {                                           /* Linear buffer */
-       memcpy(skb_put(p,len), 
+       memcpy(skb_put(p,len),
               bus_to_virt(le32_to_cpu(lp->rx_ring[lp->rx_old].buf)),len);
     }
-                   
+
     return p;
 #endif
 }
@@ -2831,7 +2831,7 @@ de4x5_restore_skbs(struct device *dev)
        lp->cache.save_cnt--;
        START_DE4X5;
     }
-        
+
     return;
 }
 
@@ -2866,7 +2866,7 @@ de4x5_cache_state(struct device *dev, int flag)
            }
            outl(gep, DE4X5_GEP);
        } else {
-           reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14, 
+           reset_init_sia(dev, lp->cache.csr13, lp->cache.csr14,
                                                              lp->cache.csr15);
        }
        break;
@@ -2928,25 +2928,25 @@ test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 sts, ans;
-    
+
     if (lp->timeout < 0) {
        lp->timeout = msec/100;
        outl(irq_mask, DE4X5_IMR);
-       
+
        /* clear all pending interrupts */
        sts = inl(DE4X5_STS);
        outl(sts, DE4X5_STS);
     }
-    
+
     ans = inl(DE4X5_SISR) & SISR_ANS;
     sts = inl(DE4X5_STS) & ~TIMER_CB;
-    
+
     if (!(sts & irqs) && (ans ^ ANS_NWOK) && --lp->timeout) {
        sts = 100 | TIMER_CB;
     } else {
        lp->timeout = -1;
     }
-    
+
     return sts;
 }
 
@@ -2956,7 +2956,7 @@ de4x5_setup_intr(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
     s32 imr, sts;
-    
+
     if (inl(DE4X5_OMR) & OMR_SR) {   /* Only unmask if TX/RX is enabled */
        imr = 0;
        UNMASK_IRQs;
@@ -2964,7 +2964,7 @@ de4x5_setup_intr(struct device *dev)
        outl(sts, DE4X5_STS);
        ENABLE_IRQs;
     }
-    
+
     return;
 }
 
@@ -2976,7 +2976,7 @@ reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     u_long iobase = dev->base_addr;
-    
+
     RESET_SIA;
     outl(sigr, DE4X5_SIGR);
     outl(strr, DE4X5_STRR);
@@ -2993,17 +2993,17 @@ create_packet(struct device *dev, char *frame, int len)
 {
     int i;
     char *buf = frame;
-    
+
     for (i=0; i<ETH_ALEN; i++) {             /* Use this source address */
        *buf++ = dev->dev_addr[i];
     }
     for (i=0; i<ETH_ALEN; i++) {             /* Use this destination address */
        *buf++ = dev->dev_addr[i];
     }
-    
+
     *buf++ = 0;                              /* Packet length (2 bytes) */
     *buf++ = 1;
-    
+
     return;
 }
 
@@ -3014,7 +3014,7 @@ static void
 de4x5_us_delay(u32 usec)
 {
     udelay(usec);
-    
+
     return;
 }
 
@@ -3025,11 +3025,11 @@ static void
 de4x5_ms_delay(u32 msec)
 {
     u_int i;
-    
+
     for (i=0; i<msec; i++) {
        de4x5_us_delay(1000);
     }
-    
+
     return;
 }
 
@@ -3047,17 +3047,17 @@ EISA_signature(char *name, s32 eisa_id)
        char Id[4];
     } Eisa;
     int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *);
-    
+
     *name = '\0';
     Eisa.ID = inl(eisa_id);
-    
+
     ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
     ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
     ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
     ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);
     ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
     ManCode[5]='\0';
-    
+
     for (i=0;i<siglen;i++) {
        if (strstr(ManCode, signatures[i]) != NULL) {
            strcpy(name,ManCode);
@@ -3065,7 +3065,7 @@ EISA_signature(char *name, s32 eisa_id)
            break;
        }
     }
-    
+
     return status;                         /* return the device name string */
 }
 
@@ -3077,7 +3077,7 @@ PCI_signature(char *name, struct bus_type *lp)
 {
     c_char *de4x5_signatures[] = DE4X5_SIGNATURE;
     int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *);
-    
+
     if (lp->chipset == DC21040) {
        strcpy(name, "DE434/5");
     } else {
@@ -3102,7 +3102,7 @@ PCI_signature(char *name, struct bus_type *lp)
                             )))));
        }
     }
-    
+
     return status;
 }
 
@@ -3115,7 +3115,7 @@ DevicePresent(u_long aprom_addr)
 {
     int i;
     struct bus_type *lp = &bus;
-    
+
     if (lp->chipset == DC21040) {
        outl(0, aprom_addr);           /* Reset Ethernet Address ROM Pointer */
     } else {                           /* Read new srom */
@@ -3125,7 +3125,7 @@ DevicePresent(u_long aprom_addr)
        }
        de4x5_dbg_srom((struct de4x5_srom *)&lp->srom);
     }
-    
+
     return;
 }
 
@@ -3141,7 +3141,7 @@ get_hw_addr(struct device *dev)
     for (i=0,k=0,j=0;j<3;j++) {
        k <<= 1;
        if (k > 0xffff) k-=0xffff;
-       
+
        if (lp->bus == PCI) {
            if (lp->chipset == DC21040) {
                while ((tmp = inl(DE4X5_APROM)) < 0);
@@ -3163,11 +3163,11 @@ get_hw_addr(struct device *dev)
            k += (u_short) ((tmp = inb(EISA_APROM)) << 8);
            dev->dev_addr[i++] = (u_char) tmp;
        }
-       
+
        if (k > 0xffff) k-=0xffff;
     }
     if (k == 0xffff) k=0;
-    
+
     if (lp->bus == PCI) {
        if (lp->chipset == DC21040) {
            while ((tmp = inl(DE4X5_APROM)) < 0);
@@ -3228,11 +3228,11 @@ static short
 srom_rd(u_long addr, u_char offset)
 {
     sendto_srom(SROM_RD | SROM_SR, addr);
-    
+
     srom_latch(SROM_RD | SROM_SR | DT_CS, addr);
     srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
     srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset);
-    
+
     return srom_data(SROM_RD | SROM_SR | DT_CS, addr);
 }
 
@@ -3242,7 +3242,7 @@ srom_latch(u_int command, u_long addr)
     sendto_srom(command, addr);
     sendto_srom(command | DT_CLK, addr);
     sendto_srom(command, addr);
-    
+
     return;
 }
 
@@ -3252,7 +3252,7 @@ srom_command(u_int command, u_long addr)
     srom_latch(command, addr);
     srom_latch(command, addr);
     srom_latch((command & 0x0000ff00) | DT_CS, addr);
-    
+
     return;
 }
 
@@ -3261,18 +3261,18 @@ srom_address(u_int command, u_long addr, u_char offset)
 {
     int i;
     char a;
-    
+
     a = (char)(offset << 2);
     for (i=0; i<6; i++, a <<= 1) {
        srom_latch(command | ((a < 0) ? DT_IN : 0), addr);
     }
     de4x5_us_delay(1);
-    
+
     i = (getfrom_srom(addr) >> 3) & 0x01;
     if (i != 0) {
        printk("Bad SROM address phase.....\n");
     }
-    
+
     return;
 }
 
@@ -3282,17 +3282,17 @@ srom_data(u_int command, u_long addr)
     int i;
     short word = 0;
     s32 tmp;
-    
+
     for (i=0; i<16; i++) {
        sendto_srom(command  | DT_CLK, addr);
        tmp = getfrom_srom(addr);
        sendto_srom(command, addr);
-       
+
        word = (word << 1) | ((tmp >> 3) & 0x01);
     }
-    
+
     sendto_srom(command & 0x0000ff00, addr);
-    
+
     return word;
 }
 
@@ -3301,13 +3301,13 @@ static void
 srom_busy(u_int command, u_long addr)
 {
    sendto_srom((command & 0x0000ff00) | DT_CS, addr);
-   
+
    while (!((getfrom_srom(addr) >> 3) & 0x01)) {
        de4x5_ms_delay(1);
    }
-   
+
    sendto_srom(command & 0x0000ff00, addr);
-   
+
    return;
 }
 */
@@ -3317,7 +3317,7 @@ sendto_srom(u_int command, u_long addr)
 {
     outl(command, addr);
     udelay(1);
-    
+
     return;
 }
 
@@ -3325,10 +3325,10 @@ static int
 getfrom_srom(u_long addr)
 {
     s32 tmp;
-    
+
     tmp = inl(addr);
     udelay(1);
-    
+
     return tmp;
 }
 
@@ -3345,7 +3345,7 @@ mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr)
     mii_address(phyaddr, ioaddr);          /* PHY address to be accessed     */
     mii_address(phyreg, ioaddr);           /* PHY Register to read           */
     mii_ta(MII_STRD, ioaddr);              /* Turn around time - 2 MDC       */
-    
+
     return mii_rdata(ioaddr);              /* Read data                      */
 }
 
@@ -3360,7 +3360,7 @@ mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr)
     mii_ta(MII_STWR, ioaddr);              /* Turn around time - 2 MDC       */
     data = mii_swap(data, 16);             /* Swap data bit ordering         */
     mii_wdata(data, 16, ioaddr);           /* Write data                     */
-    
+
     return;
 }
 
@@ -3369,12 +3369,12 @@ mii_rdata(u_long ioaddr)
 {
     int i;
     s32 tmp = 0;
-    
+
     for (i=0; i<16; i++) {
        tmp <<= 1;
        tmp |= getfrom_mii(MII_MRD | MII_RD, ioaddr);
     }
-    
+
     return tmp;
 }
 
@@ -3382,12 +3382,12 @@ static void
 mii_wdata(int data, int len, u_long ioaddr)
 {
     int i;
-    
+
     for (i=0; i<len; i++) {
        sendto_mii(MII_MWR | MII_WR, data, ioaddr);
        data >>= 1;
     }
-    
+
     return;
 }
 
@@ -3395,13 +3395,13 @@ static void
 mii_address(u_char addr, u_long ioaddr)
 {
     int i;
-    
+
     addr = mii_swap(addr, 5);
     for (i=0; i<5; i++) {
        sendto_mii(MII_MWR | MII_WR, addr, ioaddr);
        addr >>= 1;
     }
-    
+
     return;
 }
 
@@ -3409,12 +3409,12 @@ static void
 mii_ta(u_long rw, u_long ioaddr)
 {
     if (rw == MII_STWR) {
-       sendto_mii(MII_MWR | MII_WR, 1, ioaddr);  
-       sendto_mii(MII_MWR | MII_WR, 0, ioaddr);  
+       sendto_mii(MII_MWR | MII_WR, 1, ioaddr);
+       sendto_mii(MII_MWR | MII_WR, 0, ioaddr);
     } else {
        getfrom_mii(MII_MRD | MII_RD, ioaddr);        /* Tri-state MDIO */
     }
-    
+
     return;
 }
 
@@ -3422,13 +3422,13 @@ static int
 mii_swap(int data, int len)
 {
     int i, tmp = 0;
-    
+
     for (i=0; i<len; i++) {
        tmp <<= 1;
        tmp |= (data & 1);
        data >>= 1;
     }
-    
+
     return tmp;
 }
 
@@ -3436,13 +3436,13 @@ static void
 sendto_mii(u32 command, int data, u_long ioaddr)
 {
     u32 j;
-    
+
     j = (data & 1) << 17;
     outl(command | j, ioaddr);
     udelay(1);
     outl(command | MII_MDC | j, ioaddr);
     udelay(1);
-    
+
     return;
 }
 
@@ -3453,7 +3453,7 @@ getfrom_mii(u32 command, u_long ioaddr)
     udelay(1);
     outl(command | MII_MDC, ioaddr);
     udelay(1);
-    
+
     return ((inl(ioaddr) >> 19) & 1);
 }
 
@@ -3512,17 +3512,17 @@ mii_get_phy(struct device *dev)
     int iobase = dev->base_addr;
     int i, j, k, limit=sizeof(phy_info)/sizeof(struct phy_table);
     int id;
-    
+
     /* Issue a hard PHY reset - Broadcom is screwed up otherwise */
     outl(GEP_HRST, DE4X5_GEP);
     udelay(1000);                                  /* Assert for 1ms */
     outl(0x00, DE4X5_GEP);
     udelay(2000);                                  /* Wait for 2ms */
-    
+
     /* Search the MII address space for possible PHY devices */
     lp->active = 0;
     for (lp->mii_cnt=0, i=1; i<DE4X5_MAX_MII; i++) {
-       id = mii_get_oui(i, DE4X5_MII); 
+       id = mii_get_oui(i, DE4X5_MII);
        if ((id == 0) || (id == -1)) continue;     /* Valid ID? */
        for (j=0; j<limit; j++) {                  /* Search PHY table */
            if (id != phy_info[j].id) continue;    /* ID match? */
@@ -3542,11 +3542,11 @@ mii_get_phy(struct device *dev)
        for (k=0; lp->phy[k].id && (k < DE4X5_MAX_PHY); k++) { /*For each PHY*/
            mii_wr(MII_CR_RST, MII_CR, lp->phy[k].addr, DE4X5_MII);
            while (mii_rd(MII_CR, lp->phy[k].addr, DE4X5_MII) & MII_CR_RST);
-           
+
            de4x5_dbg_mii(dev, k);
        }
     }
-    
+
     return lp->mii_cnt;
 }
 
@@ -3556,12 +3556,12 @@ build_setup_frame(struct device *dev, int mode)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int i;
     char *pa = lp->setup_frame;
-    
+
     /* Initialise the setup frame */
     if (mode == ALL) {
        memset(lp->setup_frame, 0, SETUP_FRAME_LEN);
     }
-    
+
     if (lp->setup_f == HASH_PERF) {
        for (pa=lp->setup_frame+IMPERF_PA_OFFSET, i=0; i<ETH_ALEN; i++) {
            *(pa + i) = dev->dev_addr[i];                 /* Host address */
@@ -3578,7 +3578,7 @@ build_setup_frame(struct device *dev, int mode)
            if (i & 0x01) pa += 4;
        }
     }
-    
+
     return pa;                     /* Points to the next entry */
 }
 
@@ -3586,7 +3586,7 @@ static void
 enable_ast(struct device *dev, u32 time_out)
 {
     timeout(dev, (void *)&de4x5_ast, (u_long)dev, time_out);
-    
+
     return;
 }
 
@@ -3594,9 +3594,9 @@ static void
 disable_ast(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     del_timer(&lp->timer);
-    
+
     return;
 }
 
@@ -3606,21 +3606,21 @@ de4x5_switch_to_mii(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     long omr;
-    
+
     /* Assert the OMR_PS bit in CSR6 */
     omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
     omr |= (OMR_PS | OMR_HBD);
     outl(omr, DE4X5_OMR);
-    
+
     /* Soft Reset */
     RESET_DE4X5;
-    
+
     /* Restore the GEP */
     if (lp->chipset == DC21140) {
        outl(GEP_INIT, DE4X5_GEP);
        outl(0, DE4X5_GEP);
     }
-    
+
     /* Restore CSR6 */
     outl(omr, DE4X5_OMR);
 
@@ -3636,23 +3636,23 @@ de4x5_switch_to_srl(struct device *dev)
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
     long omr;
-    
+
     /* Deassert the OMR_PS bit in CSR6 */
     omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
     outl(omr, DE4X5_OMR);
-    
+
     /* Soft Reset */
     RESET_DE4X5;
-    
+
     /* Restore the GEP */
     if (lp->chipset == DC21140) {
        outl(GEP_INIT, DE4X5_GEP);
        outl(0, DE4X5_GEP);
     }
-    
+
     /* Restore CSR6 */
     outl(omr, DE4X5_OMR);
-    
+
     /* Reset CSR8 */
     inl(DE4X5_MFC);
 
@@ -3664,20 +3664,20 @@ timeout(struct device *dev, void (*fn)(u_long data), u_long data, u_long msec)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int dt;
-    
+
     /* First, cancel any pending timer events */
     del_timer(&lp->timer);
-    
+
     /* Convert msec to ticks */
     dt = (msec * HZ) / 1000;
     if (dt==0) dt=1;
-    
+
     /* Set up timer */
     lp->timer.expires = jiffies + dt;
     lp->timer.function = fn;
     lp->timer.data = data;
     add_timer(&lp->timer);
-    
+
     return;
 }
 
@@ -3686,7 +3686,7 @@ de4x5_dbg_open(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int i;
-    
+
     if (de4x5_debug > 1) {
        printk("%s: de4x5 opening with irq %d\n",dev->name,dev->irq);
        printk("\tphysical address: ");
@@ -3724,11 +3724,11 @@ de4x5_dbg_open(struct device *dev)
            }
        }
        printk("...0x%8.8x\n", le32_to_cpu(lp->tx_ring[i].buf));
-       printk("Ring size: \nRX: %d\nTX: %d\n", 
-              (short)lp->rxRingSize, 
-              (short)lp->txRingSize); 
+       printk("Ring size: \nRX: %d\nTX: %d\n",
+              (short)lp->rxRingSize,
+              (short)lp->txRingSize);
     }
-    
+
     return;
 }
 
@@ -3737,7 +3737,7 @@ de4x5_dbg_mii(struct device *dev, int k)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
     int iobase = dev->base_addr;
-    
+
     if (de4x5_debug > 2) {
        printk("\nMII CR:  %x\n",mii_rd(MII_CR,lp->phy[k].addr,DE4X5_MII));
        printk("MII SR:  %x\n",mii_rd(MII_SR,lp->phy[k].addr,DE4X5_MII));
@@ -3755,7 +3755,7 @@ de4x5_dbg_mii(struct device *dev, int k)
            printk("MII 20:  %x\n",mii_rd(0x14,lp->phy[k].addr,DE4X5_MII));
        }
     }
-    
+
     return;
 }
 
@@ -3763,7 +3763,7 @@ static void
 de4x5_dbg_media(struct device *dev)
 {
     struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-    
+
     if (lp->media != lp->c_media) {
        if (de4x5_debug > 0) {
            if (lp->chipset != DC21140) {
@@ -3771,10 +3771,10 @@ de4x5_dbg_media(struct device *dev)
                       (lp->media == NC  ? "unconnected!" :
                        (lp->media == TP  ? "TP." :
                         (lp->media == ANS ? "TP/Nway." :
-                         (lp->media == BNC ? "BNC." : 
-                          (lp->media == AUI ? "AUI." : 
-                           (lp->media == BNC_AUI ? "BNC/AUI." : 
-                            (lp->media == EXT_SIA ? "EXT SIA." : 
+                         (lp->media == BNC ? "BNC." :
+                          (lp->media == AUI ? "AUI." :
+                           (lp->media == BNC_AUI ? "BNC/AUI." :
+                            (lp->media == EXT_SIA ? "EXT SIA." :
                              "???."
                              ))))))));
            } else {
@@ -3788,7 +3788,7 @@ de4x5_dbg_media(struct device *dev)
        }
        lp->c_media = lp->media;
     }
-    
+
     return;
 }
 
@@ -3869,7 +3869,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
        u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
     } tmp;
-    
+
     switch(ioc->cmd) {
       case DE4X5_GET_HWADDR:           /* Get the hardware address */
        ioc->len = ETH_ALEN;
@@ -3880,7 +3880,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
            tmp.addr[i] = dev->dev_addr[i];
        }
        copy_to_user(ioc->data, tmp.addr, ioc->len);
-       
+
        break;
       case DE4X5_SET_HWADDR:           /* Set the hardware address */
        status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN);
@@ -3897,12 +3897,12 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        build_setup_frame(dev, PHYS_ADDR_ONLY);
        /* Set up the descriptor and give ownership to the card */
        while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
-       load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
+       load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
                                                        SETUP_FRAME_LEN, NULL);
        lp->tx_new = (++lp->tx_new) % lp->txRingSize;
        outl(POLL_DEMAND, DE4X5_TPD);                /* Start the TX */
        dev->tbusy = 0;                              /* Unlock the TX ring */
-       
+
        break;
       case DE4X5_SET_PROM:             /* Set Promiscuous Mode */
        if (suser()) {
@@ -3912,7 +3912,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_CLR_PROM:             /* Clear Promiscuous Mode */
        if (suser()) {
@@ -3922,19 +3922,19 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_SAY_BOO:              /* Say "Boo!" to the kernel log file */
        printk("%s: Boo!\n", dev->name);
-       
+
        break;
       case DE4X5_GET_MCA:              /* Get the multicast address table */
        ioc->len = (HASH_TABLE_LEN >> 3);
        status = verify_area(VERIFY_WRITE, ioc->data, ioc->len);
        if (!status) {
-           copy_to_user(ioc->data, lp->setup_frame, ioc->len); 
+           copy_to_user(ioc->data, lp->setup_frame, ioc->len);
        }
-       
+
        break;
       case DE4X5_SET_MCA:              /* Set a multicast address */
        if (suser()) {
@@ -3950,7 +3950,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_CLR_MCA:              /* Clear all multicast addresses */
        if (suser()) {
@@ -3959,7 +3959,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_MCA_EN:               /* Enable pass all multicast addressing */
        if (suser()) {
@@ -3969,18 +3969,18 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_GET_STATS:            /* Get the driver statistics */
        ioc->len = sizeof(lp->pktStats);
        status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
        if (status)
          break;
-       
+
        cli();
-       copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+       copy_to_user(ioc->data, &lp->pktStats, ioc->len);
        sti();
-       
+
        break;
       case DE4X5_CLR_STATS:            /* Zero out the driver statistics */
        if (suser()) {
@@ -3990,14 +3990,14 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_GET_OMR:              /* Get the OMR Register contents */
        tmp.addr[0] = inl(DE4X5_OMR);
        if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, 1))) {
            copy_to_user(ioc->data, tmp.addr, 1);
        }
-       
+
        break;
       case DE4X5_SET_OMR:              /* Set the OMR Register contents */
        if (suser()) {
@@ -4008,7 +4008,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        } else {
            status = -EPERM;
        }
-       
+
        break;
       case DE4X5_GET_REG:              /* Get the DE4X5 Registers */
        j = 0;
@@ -4025,9 +4025,9 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
            copy_to_user(ioc->data, tmp.addr, ioc->len);
        }
        break;
-       
+
 #define DE4X5_DUMP              0x0f /* Dump the DE4X5 Status */
-       
+
       case DE4X5_DUMP:
        j = 0;
        tmp.addr[j++] = dev->irq;
@@ -4037,7 +4037,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        tmp.addr[j++] = lp->rxRingSize;
        tmp.lval[j>>2] = (long)lp->rx_ring; j+=4;
        tmp.lval[j>>2] = (long)lp->tx_ring; j+=4;
-       
+
        for (i=0;i<lp->rxRingSize-1;i++){
            if (i < 3) {
                tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4;
@@ -4050,7 +4050,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
            }
        }
        tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4;
-       
+
        for (i=0;i<lp->rxRingSize-1;i++){
            if (i < 3) {
                tmp.lval[j>>2] = (s32)le32_to_cpu(lp->rx_ring[i].buf); j+=4;
@@ -4063,14 +4063,14 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
            }
        }
        tmp.lval[j>>2] = (s32)le32_to_cpu(lp->tx_ring[i].buf); j+=4;
-       
+
        for (i=0;i<lp->rxRingSize;i++){
            tmp.lval[j>>2] = le32_to_cpu(lp->rx_ring[i].status); j+=4;
        }
        for (i=0;i<lp->txRingSize;i++){
            tmp.lval[j>>2] = le32_to_cpu(lp->tx_ring[i].status); j+=4;
        }
-       
+
        tmp.lval[j>>2] = inl(DE4X5_BMR);  j+=4;
        tmp.lval[j>>2] = inl(DE4X5_TPD);  j+=4;
        tmp.lval[j>>2] = inl(DE4X5_RPD);  j+=4;
@@ -4079,18 +4079,18 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        tmp.lval[j>>2] = inl(DE4X5_STS);  j+=4;
        tmp.lval[j>>2] = inl(DE4X5_OMR);  j+=4;
        tmp.lval[j>>2] = inl(DE4X5_IMR);  j+=4;
-       tmp.lval[j>>2] = lp->chipset; j+=4; 
+       tmp.lval[j>>2] = lp->chipset; j+=4;
        if (lp->chipset == DC21140) {
            tmp.lval[j>>2] = inl(DE4X5_GEP);  j+=4;
        } else {
            tmp.lval[j>>2] = inl(DE4X5_SISR); j+=4;
            tmp.lval[j>>2] = inl(DE4X5_SICR); j+=4;
            tmp.lval[j>>2] = inl(DE4X5_STRR); j+=4;
-           tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4; 
+           tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4;
        }
-       tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4; 
+       tmp.lval[j>>2] = lp->phy[lp->active].id; j+=4;
        if (lp->phy[lp->active].id) {
-           tmp.lval[j>>2] = lp->active; j+=4; 
+           tmp.lval[j>>2] = lp->active; j+=4;
            tmp.lval[j>>2]=mii_rd(MII_CR,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
            tmp.lval[j>>2]=mii_rd(MII_SR,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
            tmp.lval[j>>2]=mii_rd(MII_ID0,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
@@ -4107,20 +4107,20 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
                tmp.lval[j>>2]=mii_rd(0x14,lp->phy[lp->active].addr,DE4X5_MII); j+=4;
            }
        }
-       
+
        tmp.addr[j++] = lp->txRingSize;
        tmp.addr[j++] = dev->tbusy;
-       
+
        ioc->len = j;
        if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
            copy_to_user(ioc->data, tmp.addr, ioc->len);
        }
-       
+
        break;
       default:
        status = -EOPNOTSUPP;
     }
-    
+
     return status;
 }
 
@@ -4143,15 +4143,16 @@ static struct device thisDE4X5 = {
     0, 0, 0, NULL, de4x5_probe };
 
 static int io=0x0b; /* EDIT THESE LINES FOR YOUR CONFIGURATION              */
+MODULE_PARM(io, "i");
 
 int
 init_module(void)
 {
     struct device *p  = (struct device *)&thisDE4X5;
-    
+
     thisDE4X5.base_addr = io;                   /* Now autoprobe the module */
     thisDE4X5.irq = 0;
-    
+
     for (; p!=NULL; p=p->next) {
        if (register_netdev(p) != 0)
          return -EIO;
@@ -4166,25 +4167,25 @@ cleanup_module(void)
     struct de4x5_private *lp = (struct de4x5_private *) thisDE4X5.priv;
     struct device *p  = (struct device *)&thisDE4X5;
     int keep_loaded = 0;
-    
+
     for (; p!=NULL; p=p->next) {
        keep_loaded += (p->flags & IFF_UP);     /* Is an interface up?       */
     }
-    
+
     if (keep_loaded) {
        printk("de4x5: Cannot unload modules - %d interface%s%s still active.\n",
               keep_loaded, (keep_loaded>1 ? "s ": " "),
               (keep_loaded>1 ? "are": "is"));
        return;
     }
-    
+
     for (p=thisDE4X5.next; p!=NULL; p=p->next) {
        if (p->priv) {                          /* Private area allocated?   */
            struct de4x5_private *lp = (struct de4x5_private *)p->priv;
            if (lp->cache.buf) {                /* MAC buffers allocated?    */
                kfree(lp->cache.buf);           /* Free the MAC buffers      */
            }
-           release_region(p->base_addr, (lp->bus == PCI ? 
+           release_region(p->base_addr, (lp->bus == PCI ?
                                          DE4X5_PCI_TOTAL_SIZE :
                                          DE4X5_EISA_TOTAL_SIZE));
            kfree(lp->cache.priv);              /* Free the private area     */
@@ -4198,7 +4199,7 @@ cleanup_module(void)
             kfree(lp->cache.buf);
        }
        release_region(thisDE4X5.base_addr,
-                     (lp->bus == PCI ? 
+                     (lp->bus == PCI ?
                       DE4X5_PCI_TOTAL_SIZE :
                       DE4X5_EISA_TOTAL_SIZE));
        kfree(lp->cache.priv);
index 293b37790d9c3fe9958095d17b4d1eeab4522bb8..d52263cdca998fd92cd8f40e73afd3c4fcf8b54a 100644 (file)
@@ -36,7 +36,7 @@ static const char *version =
  *
  *     You should have received a copy of the GNU General Public License
  *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  **************************************************************/
 /* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
@@ -89,6 +89,7 @@ static const char *version =
 #define PRINTK(x) /**/
 #endif
 unsigned int de600_debug = DE600_DEBUG;
+MODULE_PARM(de600_debug, "i");
 \f
 #include <linux/module.h>
 
@@ -468,9 +469,9 @@ de600_start_xmit(struct sk_buff *skb, struct device *dev)
                dev->tbusy = !free_tx_pages;
                select_prn();
        }
-       
+
        sti(); /* interrupts back on */
-       
+
 #ifdef FAKE_SMALL_MAX
        /* This will "patch" the socket TCP proto at an early moment */
        if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
@@ -613,7 +614,7 @@ de600_rx_intr(struct device *dev)
 
        skb->dev = dev;
        skb_reserve(skb,2);     /* Align */
-       
+
        /* 'skb->data' points to the start of sk_buff data area. */
        buffer = skb_put(skb,size);
 
@@ -621,11 +622,11 @@ de600_rx_intr(struct device *dev)
        de600_setup_address(read_from, RW_ADDR);
        for (i = size; i > 0; --i, ++buffer)
                *buffer = de600_read_byte(READ_DATA, dev);
-       
+
        ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
 
        skb->protocol=eth_type_trans(skb,dev);
-       
+
        netif_rx(skb);
        /*
         * If any worth-while packets have been received, netif_rx()
@@ -707,9 +708,9 @@ de600_probe(struct device *dev)
        dev->hard_start_xmit = &de600_start_xmit;
 
        ether_setup(dev);
-       
+
        dev->flags&=~IFF_MULTICAST;
-       
+
        select_prn();
        return 0;
 }
index 7cfc5ce577fc2fe673e7ee406b8f356a3a945dcb..caadf3b6289d461e3b9f04be63369a8029ceb377 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     You should have received a copy of the GNU General Public License
  *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *****************************************************************************/
 static const char *version =
@@ -192,6 +192,13 @@ static int clone = DE620_CLONE;
 
 static unsigned int de620_debug = DE620_DEBUG;
 
+MODULE_PARM(bnc, "i");
+MODULE_PARM(utp, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clone, "i");
+MODULE_PARM(de620_debug, "i");
+
 /***********************************************
  *                                             *
  * Index to functions, as function prototypes. *
@@ -485,18 +492,18 @@ get_stats(struct device *dev)
 
 static void de620_set_multicast_list(struct device *dev)
 {
-       if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
+       if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
        { /* Enable promiscuous mode */
                /*
                 *      We must make the kernel realise we had to move
                 *      into promisc mode or we start all out war on
                 *      the cable. - AC
                 */
-               dev->flags|=IFF_PROMISC;                
-       
+               dev->flags|=IFF_PROMISC;
+
                de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
        }
-       else 
+       else
        { /* Disable promiscuous mode, use normal mode */
                de620_set_register(dev, W_TCR, TCR_DEF);
        }
@@ -584,9 +591,9 @@ de620_start_xmit(struct sk_buff *skb, struct device *dev)
        dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
 
        ((struct netstats *)(dev->priv))->tx_packets++;
-       
+
        restore_flags(flags); /* interrupts maybe back on */
-       
+
        dev_kfree_skb (skb, FREE_WRITE);
 
        return 0;
@@ -897,7 +904,7 @@ de620_probe(struct device *dev)
        /* base_addr and irq are already set, see above! */
 
        ether_setup(dev);
-       
+
        /* dump eeprom */
        if (de620_debug) {
                printk("\nEEPROM contents:\n");
index ece64bf928f0705cf7cd3f79990ab8b49bf1f699..5d509e0fb3728ab346b449b40808bd8d553bddda 100644 (file)
@@ -4,9 +4,9 @@
 
 
                       Copyright 1994 David C. Davies
-                                  and 
+                                  and
                         United States Government
-        (as represented by the Director, National Security Agency).  
+        (as represented by the Director, National Security Agency).
 
                Copyright 1995  Digital Equipment Corporation.
 
@@ -61,7 +61,7 @@
        Digital Equipment Corporation, 1989
     8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
        Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-    
+
 
     Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
     driver.
        [Alan Cox: Changed the code to allow command line irq/io assignments]
        [Dave Davies: Changed the code to allow command line mem/name
                                                                 assignments]
-    6) run the net startup bits for your eth?? interface manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your eth?? interface manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
     Note that autoprobing is not allowed in loadable modules - the system is
     already up and running and you're messing with interrupts.
 
-    To unload a module, turn off the associated interface 
+    To unload a module, turn off the associated interface
     'ifconfig eth?? down' then 'rmmod depca'.
 
     To assign a base memory address for the shared memory  when running as a
     loadable module, see 5 above.  To include the adapter  name (if you have
     no PROM  but know the card name)  also see 5  above. Note that this last
-    option  will not work  with kernel  built-in  depca's. 
+    option  will not work  with kernel  built-in  depca's.
 
     The shared memory assignment for a loadable module  makes sense to avoid
     the 'memory autoprobe' picking the wrong shared memory  (for the case of
     ----------------
 
     Version   Date        Description
-  
+
       0.1     25-jan-94   Initial writing.
       0.2     27-jan-94   Added LANCE TX hardware buffer chaining.
       0.3      1-feb-94   Added multiple DEPCA support.
       0.351   30-apr-94   Added EISA support. Added DE422 recognition.
       0.36    16-may-94   DE422 fix released.
       0.37    22-jul-94   Added MODULE support
-      0.38    15-aug-94   Added DBR ROM switch in depca_close(). 
+      0.38    15-aug-94   Added DBR ROM switch in depca_close().
                           Multi DEPCA bug fix.
       0.38axp 15-sep-94   Special version for Alpha AXP Linux V1.0.
       0.381   12-dec-94   Added DE101 recognition, fix multicast bug.
       0.383   22-feb-95   Fix for conflict with VESA SCSI reported by
                           <stromain@alf.dec.com>
       0.384   17-mar-95   Fix a ring full bug reported by <bkm@star.rl.ac.uk>
-      0.385    3-apr-95   Fix a recognition bug reported by 
+      0.385    3-apr-95   Fix a recognition bug reported by
                                                 <ryan.niemi@lastfrontier.com>
       0.386   21-apr-95   Fix the last fix...sorry, must be galloping senility
       0.40    25-May-95   Rewrite for portability & updated.
                           ALPHA support from <jestabro@amt.tay1.dec.com>
       0.41    26-Jun-95   Added verify_area() calls in depca_ioctl() from
                           suggestion by <heiko@colossus.escape.de>
-      0.42    27-Dec-95   Add 'mem' shared memory assignment for loadable 
+      0.42    27-Dec-95   Add 'mem' shared memory assignment for loadable
                           modules.
                           Add 'adapter_name' for loadable modules when no PROM.
-                         Both above from a suggestion by 
+                         Both above from a suggestion by
                          <pchen@woodruffs121.residence.gatech.edu>.
                          Add new multicasting code.
       0.421   22-Apr-96          Fix alloc_device() bug <jari@markkus2.fimr.fi>
@@ -300,14 +300,14 @@ static enum {DEPCA, de100, de101, de200, de201, de202, de210, de422, unknown} ad
 ** Memory Alignment. Each descriptor is 4 longwords long. To force a
 ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
 ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry. 
+** and hence the RX descriptor ring's first entry.
 */
 #define ALIGN4      ((u_long)4 - 1)       /* 1 longword align */
 #define ALIGN8      ((u_long)8 - 1)       /* 2 longword (quadword) align */
 #define ALIGN         ALIGN8              /* Keep the LANCE happy... */
 
 /*
-** The DEPCA Rx and Tx ring descriptors. 
+** The DEPCA Rx and Tx ring descriptors.
 */
 struct depca_rx_desc {
     volatile s32 base;
@@ -454,7 +454,7 @@ int depca_probe(struct device *dev)
     eisa_probe(dev, iobase);
 
     if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
-      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name, 
+      printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name,
                                                                       iobase);
     }
 
@@ -496,7 +496,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
       dev->base_addr = ioaddr;
 
       if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */
-       printk("%s: %s at 0x%04lx (EISA slot %d)", 
+       printk("%s: %s at 0x%04lx (EISA slot %d)",
                            dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f));
       } else {                             /* ISA port address */
        printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
@@ -515,7 +515,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
        if ((nicsr & _128KB) && (adapter == de422)) netRAM = 128;
        offset = 0x0000;
 
-       /* Shared Memory Base Address */ 
+       /* Shared Memory Base Address */
        if (nicsr & BUF) {
          offset = 0x8000;              /* 32kbyte RAM offset*/
          nicsr &= ~BS;                 /* DEPCA RAM in top 32k */
@@ -533,7 +533,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
            nicsr |= SHE;
            outb(nicsr, DEPCA_NICSR);
          }
+
          /* Define the device private memory */
          dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
          if (dev->priv == NULL)
@@ -591,7 +591,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
 #ifndef MODULE
            unsigned char irqnum;
            autoirq_setup(0);
-           
+
            /* Assign the correct irq list */
            switch (lp->adapter) {
            case DEPCA:
@@ -612,7 +612,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
 
            /* Trigger an initialization just for the interrupt. */
            outw(INEA | INIT, DEPCA_DATA);
-         
+
            irqnum = autoirq_report(1);
            if (!irqnum) {
              printk(" and failed to detect IRQ line.\n");
@@ -624,7 +624,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
                  printk(" and uses IRQ%d.\n", dev->irq);
                }
              }
-             
+
              if (!dev->irq) {
                printk(" but incorrect IRQ line detected.\n");
                status = -ENXIO;
@@ -636,7 +636,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
          }
          if (status) release_region(ioaddr, DEPCA_TOTAL_SIZE);
        } else {
-         printk(",\n      requests %dkB RAM: only %dkB is available!\n", 
+         printk(",\n      requests %dkB RAM: only %dkB is available!\n",
                                                        (mem_len>>10), netRAM);
          status = -ENXIO;
        }
@@ -661,7 +661,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
       dev->do_ioctl = &depca_ioctl;
 
       dev->mem_start = 0;
-       
+
       /* Fill in the generic field of the device structure. */
       ether_setup(dev);
     } else {                           /* Incorrectly initialised hardware */
@@ -711,11 +711,11 @@ depca_open(struct device *dev)
     nicsr = ((nicsr & ~IM & ~LED)|IEN);
     outb(nicsr, DEPCA_NICSR);
     outw(CSR0,DEPCA_ADDR);
-    
-    dev->tbusy = 0;                         
+
+    dev->tbusy = 0;
     dev->interrupt = 0;
     dev->start = 1;
-    
+
     status = InitRestartDepca(dev);
 
     if (depca_debug > 1){
@@ -725,7 +725,7 @@ depca_open(struct device *dev)
   }
 
   MOD_INC_USE_COUNT;
-  
+
   return status;
 }
 
@@ -770,8 +770,8 @@ depca_init_ring(struct device *dev)
   return;
 }
 
-/* 
-** Writes a socket buffer to TX descriptor ring and starts transmission 
+/*
+** Writes a socket buffer to TX descriptor ring and starts transmission
 */
 static int
 depca_start_xmit(struct sk_buff *skb, struct device *dev)
@@ -788,7 +788,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev)
     } else {
       printk("%s: transmit timed out, status %04x, resetting.\n",
             dev->name, inw(DEPCA_DATA));
-       
+
       STOP_DEPCA;
       depca_init_ring(dev);
       LoadCSRs(dev);
@@ -814,24 +814,24 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev)
          /* Trigger an immediate send demand. */
          outw(CSR0, DEPCA_ADDR);
          outw(INEA | TDMD, DEPCA_DATA);
-         
+
          dev->trans_start = jiffies;
          dev_kfree_skb(skb, FREE_WRITE);
        }
        if (TX_BUFFS_AVAIL) {
          dev->tbusy=0;
-       }  
+       }
       } else {
        status = -1;
       }
     }
   }
-  
+
   return status;
 }
 
 /*
-** The DEPCA interrupt handler. 
+** The DEPCA interrupt handler.
 */
 static void
 depca_interrupt(int irq, void *dev_id, struct pt_regs * regs)
@@ -846,7 +846,7 @@ depca_interrupt(int irq, void *dev_id, struct pt_regs * regs)
   } else {
     lp = (struct depca_private *)dev->priv;
     ioaddr = dev->base_addr;
-    
+
     if (dev->interrupt)
       printk("%s: Re-entering the interrupt handler.\n", dev->name);
 
@@ -891,7 +891,7 @@ depca_rx(struct device *dev)
   int i, entry;
   s32 status;
 
-  for (entry=lp->rx_new; 
+  for (entry=lp->rx_new;
        !(readl(&lp->rx_ring[entry].base) & R_OWN);
        entry=lp->rx_new){
     status = readl(&lp->rx_ring[entry].base) >> 16 ;
@@ -905,7 +905,7 @@ depca_rx(struct device *dev)
        if (status & R_OFLO) lp->stats.rx_over_errors++;
        if (status & R_CRC)  lp->stats.rx_crc_errors++;
        if (status & R_BUFF) lp->stats.rx_fifo_errors++;
-      } else { 
+      } else {
        short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
        struct sk_buff *skb;
 
@@ -923,13 +923,13 @@ depca_rx(struct device *dev)
            memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
          }
 
-         /* 
-         ** Notify the upper protocol layers that there is another 
+         /*
+         ** Notify the upper protocol layers that there is another
          ** packet to handle
          */
          skb->protocol=eth_type_trans(skb,dev);
          netif_rx(skb);
+
          /*
          ** Update stats
          */
@@ -953,7 +953,7 @@ depca_rx(struct device *dev)
                     (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
            lp->pktStats.unicast++;
          }
-         
+
          lp->pktStats.bins[0]++;           /* Duplicates stats.rx_packets */
          if (lp->pktStats.bins[0] == 0) {  /* Reset counters */
            memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
@@ -966,7 +966,7 @@ depca_rx(struct device *dev)
       }
       /* Change buffer ownership for this last frame, back to the adapter */
       for (; lp->rx_old!=entry; lp->rx_old=(++lp->rx_old)&lp->rxRingMask) {
-       writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN, 
+       writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN,
                                                &lp->rx_ring[lp->rx_old].base);
       }
       writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
@@ -1039,9 +1039,9 @@ depca_close(struct device *dev)
           dev->name, inw(DEPCA_DATA));
   }
 
-  /* 
+  /*
   ** We stop the DEPCA here -- it occasionally polls
-  ** memory if we don't. 
+  ** memory if we don't.
   */
   outw(STOP, DEPCA_DATA);
 
@@ -1095,7 +1095,7 @@ static int InitRestartDepca(struct device *dev)
   outw(INIT, DEPCA_DATA);                /* initialize DEPCA */
 
   /* wait for lance to complete initialisation */
-  for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++); 
+  for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++);
 
   if (i!=100) {
     /* clear IDON by writing a "1", enable interrupts and start lance */
@@ -1131,7 +1131,7 @@ set_multicast_list(struct device *dev)
 {
   struct depca_private *lp = (struct depca_private *)dev->priv;
   u_long ioaddr = dev->base_addr;
-  
+
   if (irq2dev_map[dev->irq] != NULL) {
     while(dev->tbusy);                /* Stop ring access */
     set_bit(0, (void*)&dev->tbusy);
@@ -1180,10 +1180,10 @@ static void SetMulticastFilter(struct device *dev)
     for (i=0;i<dev->mc_count;i++) {        /* for each address in the list */
       addrs=dmi->dmi_addr;
       dmi=dmi->next;
-      if ((*addrs & 0x01) == 1) {          /* multicast address? */ 
+      if ((*addrs & 0x01) == 1) {          /* multicast address? */
        crc = 0xffffffff;                  /* init CRC for each address */
        for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
-                                          /* process each address bit */ 
+                                          /* process each address bit */
          for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
            crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0);
          }
@@ -1191,9 +1191,9 @@ static void SetMulticastFilter(struct device *dev)
        hashcode = (crc & 1);              /* hashcode is 6 LSb of CRC ... */
        for (j=0;j<5;j++) {                /* ... in reverse order. */
          hashcode = (hashcode << 1) | ((crc>>=1) & 1);
-       }                                      
-       
-       
+       }
+
+
        byte = hashcode >> 3;              /* bit[3-5] -> byte in filter */
        bit = 1 << (hashcode & 0x07);      /* bit[0-2] -> bit in byte */
        lp->init_block.mcast_table[byte] |= bit;
@@ -1224,7 +1224,7 @@ static void isa_probe(struct device *dev, u_long ioaddr)
   }
 
   for (; (i<maxSlots) && (dev!=NULL) && ports[i]; i++) {
-    if (DevicePresent(ports[i]) == 0) { 
+    if (DevicePresent(ports[i]) == 0) {
       if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) {
        if ((dev = alloc_device(dev, ports[i])) != NULL) {
          if (depca_hw_init(dev, ports[i]) == 0) {
@@ -1267,7 +1267,7 @@ static void eisa_probe(struct device *dev, u_long ioaddr)
 
   for (; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
     if (EISA_signature(name, EISA_ID)) {
-      if (DevicePresent(iobase) == 0) { 
+      if (DevicePresent(iobase) == 0) {
        if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
          if ((dev = alloc_device(dev, iobase)) != NULL) {
            if (depca_hw_init(dev, iobase) == 0) {
@@ -1299,7 +1299,7 @@ alloc_device(struct device *dev, u_long iobase)
 
     num_eth = depca_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
        if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) {
            adev=dev;
@@ -1322,13 +1322,13 @@ alloc_device(struct device *dev, u_long iobase)
        new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
        ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) ||
        new_dev) {
        num_eth++;                         /* New device */
        dev = insert_device(dev, iobase, depca_probe);
     }
-    
+
     return dev;
 }
 
@@ -1426,7 +1426,7 @@ static void DepcaSignature(char *name, u_long paddr)
 ** if the first address octet is a 0x08 - this minimises the chances of
 ** messing around with some other hardware, but it assumes that this DEPCA
 ** card initialized itself correctly.
-** 
+**
 ** Search the Ethernet address ROM for the signature. Since the ROM address
 ** counter can start at an arbitrary point, the search must include the entire
 ** probe sequence length plus the (length_of_the_signature - 1).
@@ -1456,7 +1456,7 @@ static int DevicePresent(u_long ioaddr)
     nicsr |= AAC;
     outb(nicsr, DEPCA_NICSR);
   }
-  
+
   dev.llsig.a = ETH_PROM_SIG;
   dev.llsig.b = ETH_PROM_SIG;
   sigLength = sizeof(u32) << 1;
@@ -1525,7 +1525,7 @@ static int load_packet(struct device *dev, struct sk_buff *skb)
   entry = lp->tx_new;                                 /* Ring around buffer number. */
   end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
   if (!(readl(&lp->tx_ring[end].base) & T_OWN)) {/* Enough room? */
-    /* 
+    /*
     ** Caution: the write order is important here... don't set up the
     ** ownership rights until all the other information is in place.
     */
@@ -1560,9 +1560,9 @@ static int load_packet(struct device *dev, struct sk_buff *skb)
                                                /* ownership of packet */
       writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
       if (i == 0) i=lp->txRingMask+1;
-    }   
+    }
     writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
+
     lp->tx_new = (++end) & lp->txRingMask;     /* update current pointers */
   } else {
     status = -1;
@@ -1610,7 +1610,7 @@ static void depca_dbg_open(struct device *dev)
   struct depca_private *lp = (struct depca_private *)dev->priv;
   u_long ioaddr = dev->base_addr;
   struct depca_init *p = (struct depca_init *)lp->sh_mem;
-  int i; 
+  int i;
 
   if (depca_debug > 1){
     /* Copy the shadow init_block to shared memory */
@@ -1662,11 +1662,11 @@ static void depca_dbg_open(struct device *dev)
     printk("\trx_ring at: 0x%8.8x\n",readl(&p->rx_ring));
     printk("\ttx_ring at: 0x%8.8x\n",readl(&p->tx_ring));
     printk("dma_buffs: 0x%8.8lx\n",lp->dma_buffs);
-    printk("Ring size:\nRX: %d  Log2(rxRingMask): 0x%8.8x\n", 
-          (int)lp->rxRingMask + 1, 
+    printk("Ring size:\nRX: %d  Log2(rxRingMask): 0x%8.8x\n",
+          (int)lp->rxRingMask + 1,
           lp->rx_rlen);
-    printk("TX: %d  Log2(txRingMask): 0x%8.8x\n", 
-          (int)lp->txRingMask + 1, 
+    printk("TX: %d  Log2(txRingMask): 0x%8.8x\n",
+          (int)lp->txRingMask + 1,
           lp->tx_rlen);
     outw(CSR2,DEPCA_ADDR);
     printk("CSR2&1: 0x%4.4x",inw(DEPCA_DATA));
@@ -1772,7 +1772,7 @@ static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd)
   case DEPCA_GET_MCA:                /* Get the multicast address table */
     ioc->len = (HASH_TABLE_LEN >> 3);
     if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len); 
+      copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len);
     }
 
     break;
@@ -1807,7 +1807,7 @@ static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd)
     cli();
     ioc->len = sizeof(lp->pktStats);
     if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+      copy_to_user(ioc->data, &lp->pktStats, ioc->len);
     }
     sti();
 
@@ -1851,8 +1851,10 @@ static struct device thisDepca = {
 
 static int irq=7;      /* EDIT THESE LINE FOR YOUR CONFIGURATION */
 static int io=0x200;    /* Or use the irq= io= options to insmod */
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
 
-/* See depca_probe() for autoprobe messages when a module */   
+/* See depca_probe() for autoprobe messages when a module */
 int
 init_module(void)
 {
index 19896ff95fc751c93a75d3c159b825eeac967198..a234a8555d9bec1cd4946bab44410708614c0aeb 100644 (file)
@@ -886,7 +886,7 @@ dgrs_ioctl(struct device *devN, struct ifreq *ifr, int cmd)
                privN->bcomm->bc_filter_port = ioc.port;
                privN->bcomm->bc_filter_num = ioc.filter;
                privN->bcomm->bc_filter_len = ioc.len;
-               
+
                if (ioc.len)
                {
                        COPY_FROM_USER(S2HN(privN->bcomm->bc_filter_area),
@@ -914,7 +914,7 @@ dgrs_intr(int irq, void *dev_id, struct pt_regs *regs)
        I596_CB         *cbp;
        int             cmd;
        int             i;
-       
+
        ++priv0->intrcnt;
        if (1) ++priv0->bcomm->bc_cnt[4];
        if (0)
@@ -1483,7 +1483,7 @@ dgrs_scan(struct device *dev)
                                + (inb(io+ES4H_AS_23_16) << 16);
 
                        irq = is2iv[ inb(io+ES4H_IS) & ES4H_IS_INTMASK ];
-                       
+
                        dgrs_found_device(dev, io, mem, irq, 0L, 0L);
 
                        dev = 0;
@@ -1514,6 +1514,15 @@ static int       iptrap[4] = { -1 };
 static long    ipxnet = -1;
 static int     nicmode = -1;
 
+MODULE_PARM(debug, "i");
+MODULE_PARM(dma, "i");
+MODULE_PARM(hashexpire, "i");
+MODULE_PARM(spantree, "i");
+MODULE_PARM(ipaddr, "1-4i");
+MODULE_PARM(iptrap, "1-4i");
+MODULE_PARM(ipxnet, "i");
+MODULE_PARM(nicmode, "i");
+
 int
 init_module(void)
 {
@@ -1549,13 +1558,13 @@ init_module(void)
                        dgrs_iptrap[i] = iptrap[i];
        if (ipxnet != -1)
                dgrs_ipxnet = htonl( ipxnet );
-               
+
        if (dgrs_debug)
        {
                printk("dgrs: SW=%s FW=Build %d %s\n",
                        version, dgrs_firmnum, dgrs_firmdate);
        }
-       
+
        /*
         *      Find and configure all the cards
         */
index 141c444846d4209d1bdfd89aceafeec8251b9f5f..f68227ab1f792c8c240342770ecfe57938566464 100644 (file)
@@ -59,7 +59,7 @@ static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
 #define E21_MEM_ENABLE 0x10
 #define  E21_MEM_ON            0x05    /* Enable memory in 16 bit mode. */
 #define  E21_MEM_ON_8  0x07    /* Enable memory in  8 bit mode. */
-#define E21_MEM_BASE   0x11    
+#define E21_MEM_BASE   0x11
 #define E21_IRQ_LOW            0x12    /* The low three bits of the IRQ number. */
 #define E21_IRQ_HIGH   0x14    /* The high IRQ bit and media select ...  */
 #define E21_MEDIA              0x14    /* (alias). */
@@ -226,7 +226,7 @@ int e21_probe1(struct device *dev, int ioaddr)
           over the 128K region! */
        if (dev->mem_start == 0)
                dev->mem_start = 0xd0000;
-       
+
 #ifdef notdef
        /* These values are unused.  The E2100 has a 2K window into the packet
           buffer.  The window can be set to start on any page boundary. */
@@ -398,6 +398,11 @@ static int irq[MAX_E21_CARDS]  = { 0, };
 static int mem[MAX_E21_CARDS] = { 0, };
 static int xcvr[MAX_E21_CARDS] = { 0, };               /* choose int. or ext. xcvr */
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
index c4b07413a0ba5755733b289807f906fdd09f03a0..099f0416ca5ebc4280710f4140830a99486509f1 100644 (file)
@@ -8,7 +8,7 @@
        according to the terms of the GNU Public License,
        incorporated herein by reference.
 
-       The author may be reached at bao.ha@srs.gov 
+       The author may be reached at bao.ha@srs.gov
        or 418 Hastings Place, Martinez, GA 30907.
 
        Things remaining to do:
@@ -38,7 +38,7 @@
        0.07a   Fix a stat report which counts every packet as a
                heart-beat failure. (BCH, 6/3/95)
 
-       0.07    Modified to support all other 82595-based lan cards.  
+       0.07    Modified to support all other 82595-based lan cards.
                The IRQ vector of the EtherExpress Pro will be set
                according to the value saved in the EEPROM.  For other
                cards, I will do autoirq_request() to grab the next
                print out format. (BCH, 3/9/95 and 3/14/95)
 
        0.06    First stable release that I am comfortable with. (BCH,
-               3/2/95) 
+               3/2/95)
 
-       0.05    Complete testing of multicast. (BCH, 2/23/95)   
+       0.05    Complete testing of multicast. (BCH, 2/23/95)
 
-       0.04    Adding multicast support. (BCH, 2/14/95)        
+       0.04    Adding multicast support. (BCH, 2/14/95)
 
-       0.03    First widely alpha release for public testing. 
-               (BCH, 2/14/95)  
+       0.03    First widely alpha release for public testing.
+               (BCH, 2/14/95)
 
 */
 
@@ -67,18 +67,18 @@ static const char *version =
 /*
   Sources:
 
-       This driver wouldn't have been written without the availability 
-       of the Crynwr's Lan595 driver source code.  It helps me to 
-       familiarize with the 82595 chipset while waiting for the Intel 
-       documentation.  I also learned how to detect the 82595 using 
+       This driver wouldn't have been written without the availability
+       of the Crynwr's Lan595 driver source code.  It helps me to
+       familiarize with the 82595 chipset while waiting for the Intel
+       documentation.  I also learned how to detect the 82595 using
        the packet driver's technique.
 
        This driver is written by cutting and pasting the skeleton.c driver
        provided by Donald Becker.  I also borrowed the EEPROM routine from
        Donald Becker's 82586 driver.
 
-       Datasheet for the Intel 82595 (including the TX and FX version). It 
-       provides just enough info that the casual reader might think that it 
+       Datasheet for the Intel 82595 (including the TX and FX version). It
+       provides just enough info that the casual reader might think that it
        documents the i82595.
 
        The User Manual for the 82595.  It provides a lot of the missing
@@ -147,7 +147,7 @@ struct eepro_local {
 
 /* Index to functions, as function prototypes. */
 
-extern int eepro_probe(struct device *dev);    
+extern int eepro_probe(struct device *dev);
 
 static int     eepro_probe1(struct device *dev, short ioaddr);
 static int     eepro_open(struct device *dev);
@@ -184,10 +184,10 @@ single packet.  In other systems with faster computers and more congested
 network traffics, the ring linked list should improve performance by
 allowing up to 8K worth of packets to be queued.
 
-The sizes of the receive and transmit buffers can now be changed via lilo 
+The sizes of the receive and transmit buffers can now be changed via lilo
 or insmod.  Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0"
 where rx-buffer is in KB unit.  Modules uses the parameter mem which is
-also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."  
+also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."
 The receive buffer has to be more than 3K or less than 29K.  Otherwise,
 it is reset to the default of 24K, and, hence, 8K for the trasnmit
 buffer (transmit-buffer = 32K - receive-buffer).
@@ -198,11 +198,11 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define RCV_RAM         0x6000  /* 24KB default for RCV buffer */
 #define RCV_LOWER_LIMIT 0x00    /* 0x0000 */
 /* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */    /* 0x5ffe */
-#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)   
+#define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)
 /* #define XMT_RAM         (RAM_SIZE - RCV_RAM) */    /* 8KB for XMT buffer */
 #define XMT_RAM         (RAM_SIZE - (rcv_ram))    /* 8KB for XMT buffer */
 /* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */  /* 0x6000 */
-#define XMT_LOWER_LIMIT ((rcv_ram) >> 8) 
+#define XMT_LOWER_LIMIT ((rcv_ram) >> 8)
 #define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8)   /* 0x7ffe */
 #define        XMT_HEADER      8
 
@@ -216,9 +216,9 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        XMT_CHAIN       0x04
 #define        XMT_COUNT       0x06
 
-#define        BANK0_SELECT    0x00            
-#define        BANK1_SELECT    0x40            
-#define        BANK2_SELECT    0x80            
+#define        BANK0_SELECT    0x00
+#define        BANK1_SELECT    0x40
+#define        BANK2_SELECT    0x80
 
 /* Bank 0 registers */
 #define        COMMAND_REG     0x00    /* Register 0 */
@@ -278,7 +278,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        REG13           0x0d
 #define        FDX             0x00
 #define        A_N_ENABLE      0x02
-       
+
 #define        I_ADD_REG0      0x04
 #define        I_ADD_REG1      0x05
 #define        I_ADD_REG2      0x06
@@ -349,9 +349,9 @@ int eepro_probe1(struct device *dev, short ioaddr)
                /* We seem to have the 82595 signature, let's
                   play with its counter (last 2 bits of
                   register 2 of bank 0) to be sure. */
-       
-               counter = (id & R_ROBIN_BITS);  
-               if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) == 
+
+               counter = (id & R_ROBIN_BITS);
+               if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) ==
                        (counter + 0x40)) {
 
                        /* Yes, the 82595 has been found */
@@ -367,33 +367,33 @@ int eepro_probe1(struct device *dev, short ioaddr)
 
                        if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
                                eepro = 0;
-                               printk("%s: Intel 82595-based lan card at %#x,", 
+                               printk("%s: Intel 82595-based lan card at %#x,",
                                        dev->name, ioaddr);
                        }
                        else {
                                eepro = 1;
-                               printk("%s: Intel EtherExpress Pro/10 at %#x,", 
+                               printk("%s: Intel EtherExpress Pro/10 at %#x,",
                                        dev->name, ioaddr);
                        }
 
                        /* Fill in the 'dev' fields. */
                        dev->base_addr = ioaddr;
-                       
+
                        for (i=0; i < 6; i++) {
                                dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
                                printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
                        }
-                       
+
                        if ((dev->mem_end & 0x3f) < 3 ||        /* RX buffer must be more than 3K */
                                (dev->mem_end & 0x3f) > 29)     /* and less than 29K */
                                dev->mem_end = RCV_RAM;         /* or it will be set to 24K */
                        else dev->mem_end = 1024*dev->mem_end;  /* Maybe I should shift << 10 */
 
                        /* From now on, dev->mem_end contains the actual size of rx buffer */
-                       
+
                        if (net_debug > 3)
                                printk(", %dK RCV buffer", (int)(dev->mem_end)/1024);
-                               
+
                        outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                        id = inb(ioaddr + REG3);
                        if (id & TPE_BIT)
@@ -425,7 +425,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                }
                        }
                        else printk(", %s.\n", ifmap[dev->if_port]);
-                       
+
                        if ((dev->mem_start & 0xf) > 0) /* I don't know if this is */
                                net_debug = dev->mem_start & 7; /* still useful or not */
 
@@ -436,7 +436,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                                dev->name);
                        }
 
-                       if (net_debug) 
+                       if (net_debug)
                                printk(version);
 
                        /* Grab the region so we can find another board if autoIRQ fails. */
@@ -481,27 +481,27 @@ int eepro_probe1(struct device *dev, short ioaddr)
 static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
 static int     eepro_grab_irq(struct device *dev)
 {
-       int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};       
+       int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};
        int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
 
        outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
 
        /* Enable the interrupt line. */
        temp_reg = inb(ioaddr + REG1);
-       outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
-       
+       outb(temp_reg | INT_ENABLE, ioaddr + REG1);
+
        outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */
 
        /* clear all interrupts */
-       outb(ALL_MASK, ioaddr + STATUS_REG); 
+       outb(ALL_MASK, ioaddr + STATUS_REG);
        /* Let EXEC event to interrupt */
-       outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG); 
+       outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);
 
        do {
                outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
 
                temp_reg = inb(ioaddr + INT_NO_REG);
-               outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG); 
+               outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
 
                outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
@@ -510,13 +510,13 @@ static int        eepro_grab_irq(struct device *dev)
                        autoirq_setup(0);
 
                        outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
-                               
+
                        if (*irqp == autoirq_report(2) &&  /* It's a good IRQ line */
-                               (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0)) 
+                               (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0))
                                        break;
 
                        /* clear all interrupts */
-                       outb(ALL_MASK, ioaddr + STATUS_REG); 
+                       outb(ALL_MASK, ioaddr + STATUS_REG);
                }
        } while (*++irqp);
 
@@ -524,15 +524,15 @@ static int        eepro_grab_irq(struct device *dev)
 
        /* Disable the physical interrupt line. */
        temp_reg = inb(ioaddr + REG1);
-       outb(temp_reg & 0x7f, ioaddr + REG1); 
+       outb(temp_reg & 0x7f, ioaddr + REG1);
 
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
        /* Mask all the interrupts. */
-       outb(ALL_MASK, ioaddr + INT_MASK_REG); 
+       outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
        /* clear all interrupts */
-       outb(ALL_MASK, ioaddr + STATUS_REG); 
+       outb(ALL_MASK, ioaddr + STATUS_REG);
 
        return dev->irq;
 }
@@ -553,12 +553,12 @@ eepro_open(struct device *dev)
                lp->eepro = 1; /* Yes, an Intel EtherExpress Pro/10 */
        else lp->eepro = 0; /* No, it is a generic 82585 lan card */
 
-       /* Get the interrupt vector for the 82595 */    
+       /* Get the interrupt vector for the 82595 */
        if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
                printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
                return -EAGAIN;
        }
-                               
+
        if (irq2dev_map[dev->irq] != 0
                || (irq2dev_map[dev->irq] = dev) == 0)
                return -EAGAIN;
@@ -569,18 +569,18 @@ eepro_open(struct device *dev)
        temp_reg = inb(ioaddr + EEPROM_REG);
 
        lp->stepping = temp_reg >> 5;   /* Get the stepping number of the 595 */
-       
+
        if (net_debug > 3)
                printk("The stepping of the 82595 is %d\n", lp->stepping);
 
        if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
                outb(temp_reg & 0xef, ioaddr + EEPROM_REG);
-       for (i=0; i < 6; i++) 
-               outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i); 
-                       
+       for (i=0; i < 6; i++)
+               outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
+
        temp_reg = inb(ioaddr + REG1);    /* Setup Transmit Chaining */
        outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
-               | RCV_Discard_BadFrame, ioaddr + REG1);  
+               | RCV_Discard_BadFrame, ioaddr + REG1);
 
        temp_reg = inb(ioaddr + REG2); /* Match broadcast */
        outb(temp_reg | 0x14, ioaddr + REG2);
@@ -590,34 +590,34 @@ eepro_open(struct device *dev)
 
        /* Set the receiving mode */
        outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-       
+
        temp_reg = inb(ioaddr + INT_NO_REG);
-       outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
+       outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
 
        /* Initialize the RCV and XMT upper and lower limits */
-       outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); 
-       outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); 
-       outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG); 
-       outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG); 
+       outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
+       outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
+       outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG);
+       outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG);
 
        /* Enable the interrupt line. */
        temp_reg = inb(ioaddr + REG1);
-       outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
+       outb(temp_reg | INT_ENABLE, ioaddr + REG1);
 
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
        /* Let RX and TX events to interrupt */
-       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
        /* clear all interrupts */
-       outb(ALL_MASK, ioaddr + STATUS_REG); 
+       outb(ALL_MASK, ioaddr + STATUS_REG);
 
        /* Initialize RCV */
-       outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); 
+       outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR);
        lp->rx_start = (RCV_LOWER_LIMIT << 8) ;
-       outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); 
+       outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP);
 
        /* Initialize XMT */
-       outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR); 
+       outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR);
 
        /* Check for the i82595TX and i82595FX */
        old8 = inb(ioaddr + 8);
@@ -652,15 +652,15 @@ eepro_open(struct device *dev)
                else if (net_debug > 3)
                        printk("i82595TX detected!\n");
        }
-       
+
        outb(SEL_RESET_CMD, ioaddr);
        /* We are supposed to wait for 2 us after a SEL_RESET */
        SLOW_DOWN_IO;
-       SLOW_DOWN_IO;   
+       SLOW_DOWN_IO;
 
        lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */
-       lp->tx_last = 0;  
-       
+       lp->tx_last = 0;
+
        dev->tbusy = 0;
        dev->interrupt = 0;
        dev->start = 1;
@@ -683,7 +683,7 @@ eepro_send_packet(struct sk_buff *skb, struct device *dev)
 
        if (net_debug > 5)
                printk("eepro: entering eepro_send_packet routine.\n");
-       
+
        if (dev->tbusy) {
                /* If we get here, some higher level has decided we are broken.
                   There should really be a "kick me" function call instead. */
@@ -696,15 +696,15 @@ eepro_send_packet(struct sk_buff *skb, struct device *dev)
                lp->stats.tx_errors++;
 
                /* Try to restart the adaptor. */
-               outb(SEL_RESET_CMD, ioaddr); 
+               outb(SEL_RESET_CMD, ioaddr);
                /* We are supposed to wait for 2 us after a SEL_RESET */
                SLOW_DOWN_IO;
                SLOW_DOWN_IO;
 
                /* Do I also need to flush the transmit buffers here? YES? */
-               lp->tx_start = lp->tx_end = rcv_ram; 
+               lp->tx_start = lp->tx_end = rcv_ram;
                lp->tx_last = 0;
-       
+
                dev->tbusy=0;
                dev->trans_start = jiffies;
 
@@ -738,7 +738,7 @@ eepro_send_packet(struct sk_buff *skb, struct device *dev)
 
        if (net_debug > 5)
                printk("eepro: exiting eepro_send_packet routine.\n");
-       
+
        return 0;
 }
 
@@ -753,24 +753,24 @@ eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 
        if (net_debug > 5)
                printk("eepro: entering eepro_interrupt routine.\n");
-       
+
        if (dev == NULL) {
                printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
                return;
        }
        dev->interrupt = 1;
-       
+
        ioaddr = dev->base_addr;
 
-       do { 
+       do {
                status = inb(ioaddr + STATUS_REG);
-               
+
                if (status & RX_INT) {
                        if (net_debug > 4)
                                printk("eepro: packet received interrupt.\n");
 
                        /* Acknowledge the RX_INT */
-                       outb(RX_INT, ioaddr + STATUS_REG); 
+                       outb(RX_INT, ioaddr + STATUS_REG);
 
                        /* Get the received packets */
                        eepro_rx(dev);
@@ -781,18 +781,18 @@ eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                                printk("eepro: packet transmit interrupt.\n");
 
                        /* Acknowledge the TX_INT */
-                       outb(TX_INT, ioaddr + STATUS_REG); 
+                       outb(TX_INT, ioaddr + STATUS_REG);
 
                        /* Process the status of transmitted packets */
                        eepro_transmit_interrupt(dev);
                }
-       
+
        } while ((boguscount-- > 0) && (status & 0x06));
 
        dev->interrupt = 0;
        if (net_debug > 5)
                printk("eepro: exiting eepro_interrupt routine.\n");
-       
+
        return;
 }
 
@@ -811,23 +811,23 @@ eepro_close(struct device *dev)
 
        /* Disable the physical interrupt line. */
        temp_reg = inb(ioaddr + REG1);
-       outb(temp_reg & 0x7f, ioaddr + REG1); 
+       outb(temp_reg & 0x7f, ioaddr + REG1);
 
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
        /* Flush the Tx and disable Rx. */
-       outb(STOP_RCV_CMD, ioaddr); 
+       outb(STOP_RCV_CMD, ioaddr);
        lp->tx_start = lp->tx_end = rcv_ram ;
-       lp->tx_last = 0;  
+       lp->tx_last = 0;
 
        /* Mask all the interrupts. */
-       outb(ALL_MASK, ioaddr + INT_MASK_REG); 
+       outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
        /* clear all interrupts */
-       outb(ALL_MASK, ioaddr + STATUS_REG); 
+       outb(ALL_MASK, ioaddr + STATUS_REG);
 
        /* Reset the 82595 */
-       outb(RESET_CMD, ioaddr); 
+       outb(RESET_CMD, ioaddr);
 
        /* release the interrupt */
        free_irq(dev->irq, NULL);
@@ -864,7 +864,7 @@ set_multicast_list(struct device *dev)
        unsigned short mode;
        struct dev_mc_list *dmi=dev->mc_list;
 
-       if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63) 
+       if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
        {
                /*
                 *      We must make the kernel realise we had to move
@@ -872,17 +872,17 @@ set_multicast_list(struct device *dev)
                 *      the cable. If it was a promisc request the
                 *      flag is already set. If not we assert it.
                 */
-               dev->flags|=IFF_PROMISC;                
+               dev->flags|=IFF_PROMISC;
 
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                mode = inb(ioaddr + REG2);
-               outb(mode | PRMSC_Mode, ioaddr + REG2); 
+               outb(mode | PRMSC_Mode, ioaddr + REG2);
                mode = inb(ioaddr + REG3);
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
                printk("%s: promiscuous mode enabled.\n", dev->name);
-       } 
-       else if (dev->mc_count==0 ) 
+       }
+       else if (dev->mc_count==0 )
        {
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                mode = inb(ioaddr + REG2);
@@ -891,11 +891,11 @@ set_multicast_list(struct device *dev)
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
        }
-       else 
+       else
        {
                unsigned short status, *eaddrs;
                int i, boguscount = 0;
-               
+
                /* Disable RX and TX interrupts.  Necessary to avoid
                   corruption of the HOST_ADDRESS_REG by interrupt
                   service routines. */
@@ -903,7 +903,7 @@ set_multicast_list(struct device *dev)
 
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                mode = inb(ioaddr + REG2);
-               outb(mode | Multi_IA, ioaddr + REG2);   
+               outb(mode | Multi_IA, ioaddr + REG2);
                mode = inb(ioaddr + REG3);
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
@@ -912,7 +912,7 @@ set_multicast_list(struct device *dev)
                outw(0, ioaddr + IO_PORT);
                outw(0, ioaddr + IO_PORT);
                outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
-               for (i = 0; i < dev->mc_count; i++) 
+               for (i = 0; i < dev->mc_count; i++)
                {
                        eaddrs=(unsigned short *)dmi->dmi_addr;
                        dmi=dmi->next;
@@ -929,9 +929,9 @@ set_multicast_list(struct device *dev)
 
                /* Update the transmit queue */
                i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
-               if (lp->tx_start != lp->tx_end) 
-               { 
-                       /* update the next address and the chain bit in the 
+               if (lp->tx_start != lp->tx_end)
+               {
+                       /* update the next address and the chain bit in the
                           last packet */
                        outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
                        outw(i, ioaddr + IO_PORT);
@@ -948,16 +948,16 @@ set_multicast_list(struct device *dev)
                do { /* We should be doing this in the eepro_interrupt()! */
                        SLOW_DOWN_IO;
                        SLOW_DOWN_IO;
-                       if (inb(ioaddr + STATUS_REG) & 0x08) 
+                       if (inb(ioaddr + STATUS_REG) & 0x08)
                        {
                                i = inb(ioaddr);
                                outb(0x08, ioaddr + STATUS_REG);
                                if (i & 0x20) { /* command ABORTed */
-                                       printk("%s: multicast setup failed.\n", 
+                                       printk("%s: multicast setup failed.\n",
                                                dev->name);
                                        break;
                                } else if ((i & 0x0f) == 0x03)  { /* MC-Done */
-                                       printk("%s: set Rx mode to %d addresses.\n", 
+                                       printk("%s: set Rx mode to %d addresses.\n",
                                                dev->name, dev->mc_count);
                                        break;
                                }
@@ -965,8 +965,8 @@ set_multicast_list(struct device *dev)
                } while (++boguscount < 100);
 
                /* Re-enable RX and TX interrupts */
-               outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
-       
+               outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
+
        }
        outb(RCV_ENABLE_CMD, ioaddr);
 }
@@ -986,10 +986,10 @@ read_eeprom(int ioaddr, int location)
        short ee_addr = ioaddr + EEPROM_REG;
        int read_cmd = location | EE_READ_CMD;
        short ctrl_val = EECS ;
-       
+
        outb(BANK2_SELECT, ioaddr);
        outb(ctrl_val, ee_addr);
-       
+
        /* Shift the read command bits out. */
        for (i = 8; i >= 0; i--) {
                short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
@@ -1001,7 +1001,7 @@ read_eeprom(int ioaddr, int location)
                eeprom_delay();
        }
        outb(ctrl_val, ee_addr);
-       
+
        for (i = 16; i > 0; i--) {
                outb(ctrl_val | EESK, ee_addr);  eeprom_delay();
                retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
@@ -1036,9 +1036,9 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                service routines. */
                outb(ALL_MASK, ioaddr + INT_MASK_REG);
 
-               if (dev->interrupt == 1) {  
+               if (dev->interrupt == 1) {
                        /* Enable RX and TX interrupts */
-                       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+                       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
                        continue;
                }
 
@@ -1049,13 +1049,13 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                        tx_available = lp->tx_start - lp->tx_end;
                else tx_available = XMT_RAM;
 
-               if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) 
+               if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER)
                        >= tx_available)   /* No space available ??? */
                        {
                        eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */
 
                        /* Enable RX and TX interrupts */
-                       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+                       outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
                        continue;
                }
 
@@ -1063,12 +1063,12 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
                if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
-                       if ((RAM_SIZE - last) <= XMT_HEADER) {  
+                       if ((RAM_SIZE - last) <= XMT_HEADER) {
                        /* Arrrr!!!, must keep the xmt header together,
                          several days were lost to chase this one down. */
                                last = rcv_ram;
                                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-                       }       
+                       }
                        else end = rcv_ram + (end - RAM_SIZE);
                }
 
@@ -1088,15 +1088,15 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                }
 
                /* A dummy read to flush the DRAM write pipeline */
-               status = inw(ioaddr + IO_PORT); 
+               status = inw(ioaddr + IO_PORT);
 
-               if (lp->tx_start == lp->tx_end) {       
+               if (lp->tx_start == lp->tx_end) {
                        outw(last, ioaddr + XMT_BAR);
                        outb(XMT_CMD, ioaddr);
                        lp->tx_start = last;   /* I don't like to change tx_start here */
                }
                else {
-                       /* update the next address and the chain bit in the 
+                       /* update the next address and the chain bit in the
                        last packet */
                        if (lp->tx_end != last) {
                                outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
@@ -1114,8 +1114,8 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                lp->tx_end = end;
 
                /* Enable RX and TX interrupts */
-               outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
-       
+               outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
+
                if (dev->tbusy) {
                        dev->tbusy = 0;
                }
@@ -1141,7 +1141,7 @@ eepro_rx(struct device *dev)
 
        if (net_debug > 5)
                printk("eepro: entering eepro_rx routine.\n");
-       
+
        /* Set the read pointer to the start of the RCV */
        outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
        rcv_event = inw(ioaddr + IO_PORT);
@@ -1174,12 +1174,12 @@ eepro_rx(struct device *dev)
                                outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
                        }
 
-       
-                       skb->protocol = eth_type_trans(skb,dev);        
+
+                       skb->protocol = eth_type_trans(skb,dev);
                        netif_rx(skb);
                        lp->stats.rx_packets++;
                }
-               else { /* Not sure will ever reach here, 
+               else { /* Not sure will ever reach here,
                          I set the 595 to discard bad received frames */
                        lp->stats.rx_errors++;
                        if (rcv_status & 0x0100)
@@ -1188,7 +1188,7 @@ eepro_rx(struct device *dev)
                                lp->stats.rx_frame_errors++;
                        else if (rcv_status & 0x0800)
                                lp->stats.rx_crc_errors++;
-                       printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
+                       printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
                                dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
                }
                if (rcv_status & 0x1000)
@@ -1201,7 +1201,7 @@ eepro_rx(struct device *dev)
                outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
                rcv_event = inw(ioaddr + IO_PORT);
 
-       } 
+       }
        if (rcv_car == 0)
                rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
        outw(rcv_car - 1, ioaddr + RCV_STOP);
@@ -1215,10 +1215,10 @@ eepro_transmit_interrupt(struct device *dev)
 {
        struct eepro_local *lp = (struct eepro_local *)dev->priv;
        short ioaddr = dev->base_addr;
-       short boguscount = 20; 
+       short boguscount = 20;
        short xmt_status;
 
-       while (lp->tx_start != lp->tx_end) { 
+       while (lp->tx_start != lp->tx_end) {
 
                outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
                xmt_status = inw(ioaddr+IO_PORT);
@@ -1231,7 +1231,7 @@ eepro_transmit_interrupt(struct device *dev)
                mark_bh(NET_BH);
 
                if (xmt_status & 0x2000)
-                       lp->stats.tx_packets++; 
+                       lp->stats.tx_packets++;
                else {
                        lp->stats.tx_errors++;
                        if (xmt_status & 0x0400)
@@ -1247,7 +1247,7 @@ eepro_transmit_interrupt(struct device *dev)
                }
 
                if (--boguscount == 0)
-                       break;  
+                       break;
        }
 }
 
@@ -1263,6 +1263,10 @@ static int io = 0x200;
 static int irq = 0;
 static int mem = (RCV_RAM/1024);       /* Size of the rx buffer in KB */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(mem, "i");
+
 int
 init_module(void)
 {
index 2a6329b75f5a78d18b3ffcf5806425cb4e6e0290..d8736f72c7acb3b0629f0efb03c4e7e28bb88e44 100644 (file)
  * as far as I know, to the similarly-named "EtherExpress Pro" range.
  *
  * Historically, Linux support for these cards has been very bad.  However,
- * things seem to be getting better slowly. 
+ * things seem to be getting better slowly.
  */
 
-/* It would be nice to seperate out all the 82586-specific code, so that it 
+/* It would be nice to seperate out all the 82586-specific code, so that it
  * could be shared between drivers (as with 8390.c).  But this would be quite
  * a messy job.  The main motivation for doing this would be to bring 3c507
  * support back up to scratch.
  * as follows:
  *
  * (the low five bits of the SMPTR are ignored)
- * 
+ *
  *  base+0x4000..400f      memory at SMPTR+0..15
  *  base+0x8000..800f      memory at SMPTR+16..31
  *  base+0xc000..c007      dubious stuff (memory at SMPTR+16..23 apparently)
  *  base+0xc008..c00f      memory at 0x0008..0x000f
  *
- * This last set (the one at c008) is particularly handy because the SCB 
- * lives at 0x0008.  So that set of ports gives us easy random access to data 
+ * This last set (the one at c008) is particularly handy because the SCB
+ * lives at 0x0008.  So that set of ports gives us easy random access to data
  * in the SCB without having to mess around setting up pointers and the like.
  * We always use this method to access the SCB (via the scb_xx() functions).
  *
@@ -63,7 +63,7 @@
  * - 8-bit mode is not supported, and makes things go wrong.
  * - Multicast and promiscuous modes are not supported.
  * - The card seems to want to give us two interrupts every time something
- *   happens, where just one would be better. 
+ *   happens, where just one would be better.
  * - The statistics may not be getting reported properly.
  */
 
@@ -90,7 +90,7 @@
 #include <linux/malloc.h>
 
 #ifndef NET_DEBUG
-#define NET_DEBUG 4 
+#define NET_DEBUG 4
 #endif
 
 #include "eexpress.h"
  * Private data declarations
  */
 
-struct net_local 
+struct net_local
 {
        struct enet_statistics stats;
        unsigned long init_time;     /* jiffies when eexp_hw_init586 called */
@@ -128,7 +128,7 @@ struct net_local
 static unsigned short start_code[] = {
 /* 0xfff6 */
        0x0000,                 /* set bus to 16 bits */
-       0x0000,0x0000,         
+       0x0000,0x0000,
        0x0000,0x0000,          /* address of ISCP (lo,hi) */
 
 /* 0x0000 */
@@ -136,7 +136,7 @@ static unsigned short start_code[] = {
        0x0008,0x0000,0x0000,   /* offset,address (lo,hi) of SCB */
 
        0x0000,0x0000,          /* SCB: status, commands */
-       0x0000,0x0000,          /* links to first command block, 
+       0x0000,0x0000,          /* links to first command block,
                                   first receive descriptor */
        0x0000,0x0000,          /* CRC error, alignment error counts */
        0x0000,0x0000,          /* out of resources, overrun error counts */
@@ -146,7 +146,7 @@ static unsigned short start_code[] = {
 
 /* 0x0020 -- start of 82586 CU program */
 #define CONF_LINK 0x0020
-       0x0000,Cmd_Config,      
+       0x0000,Cmd_Config,
        0x0032,                 /* link to next command */
        0x080c,                 /* 12 bytes follow : fifo threshold=8 */
        0x2e40,                 /* don't rx bad frames
@@ -156,9 +156,9 @@ static unsigned short start_code[] = {
                                 */
        0x6000,                 /* default backoff method & priority
                                 * interframe spacing = 0x60 */
-       0xf200,                 /* slot time=0x200 
+       0xf200,                 /* slot time=0x200
                                 * max collision retry = 0xf */
-       0x0000,                 /* no HDLC : normal CRC : enable broadcast 
+       0x0000,                 /* no HDLC : normal CRC : enable broadcast
                                 * disable promiscuous/multicast modes */
        0x003c,                 /* minimum frame length = 60 octets) */
 
@@ -245,12 +245,12 @@ static inline void scb_wrrfa(struct device *dev, unsigned short val)
 
 static inline void set_loopback(struct device *dev)
 {
-       outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config); 
+       outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
 }
 
 static inline void clear_loopback(struct device *dev)
 {
-       outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config); 
+       outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
 }
 
 static inline short int SHADOW(short int addr)
@@ -278,17 +278,17 @@ int express_probe(struct device *dev)
        else if (ioaddr)
                return ENXIO;
 
-       for (port=&ports[0] ; *port ; port++ ) 
+       for (port=&ports[0] ; *port ; port++ )
        {
                unsigned short sum = 0;
                int i;
-               for ( i=0 ; i<4 ; i++ ) 
+               for ( i=0 ; i<4 ; i++ )
                {
                        unsigned short t;
                        t = inb(*port + ID_PORT);
                        sum |= (t>>4) << ((t & 0x03)<<2);
                }
-               if (sum==0xbaba && !eexp_hw_probe(dev,*port)) 
+               if (sum==0xbaba && !eexp_hw_probe(dev,*port))
                        return 0;
        }
        return ENODEV;
@@ -307,12 +307,12 @@ static int eexp_open(struct device *dev)
        printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
 #endif
 
-       if (!irq || !irqrmap[irq]) 
+       if (!irq || !irqrmap[irq])
                return -ENXIO;
 
        if (irq2dev_map[irq] ||
           ((irq2dev_map[irq]=dev),0) ||
-            request_irq(irq,&eexp_irq,0,"EtherExpress",NULL)) 
+            request_irq(irq,&eexp_irq,0,"EtherExpress",NULL))
                return -EAGAIN;
 
        request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
@@ -338,9 +338,9 @@ static int eexp_close(struct device *dev)
 
        int irq = dev->irq;
 
-       dev->tbusy = 1; 
+       dev->tbusy = 1;
        dev->start = 0;
-  
+
        outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
        lp->started = 0;
        scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
@@ -365,7 +365,7 @@ static struct enet_statistics *eexp_stats(struct device *dev)
        return &lp->stats;
 }
 
-/* 
+/*
  * This gets called when a higher level thinks we are broken.  Check that
  * nothing has become jammed in the CU.
  */
@@ -375,11 +375,11 @@ static void unstick_cu(struct device *dev)
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short ioaddr = dev->base_addr;
 
-       if (lp->started) 
+       if (lp->started)
        {
-               if ((jiffies - dev->trans_start)>50) 
+               if ((jiffies - dev->trans_start)>50)
                {
-                       if (lp->tx_link==lp->last_tx_restart) 
+                       if (lp->tx_link==lp->last_tx_restart)
                        {
                                unsigned short boguscount=200,rsst;
                                printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
@@ -389,9 +389,9 @@ static void unstick_cu(struct device *dev)
                                scb_wrcbl(dev, lp->tx_link);
                                scb_command(dev, SCB_CUstart);
                                outb(0,ioaddr+SIGNAL_CA);
-                               while (!SCB_complete(rsst=scb_status(dev))) 
+                               while (!SCB_complete(rsst=scb_status(dev)))
                                {
-                                       if (!--boguscount) 
+                                       if (!--boguscount)
                                        {
                                                boguscount=200;
                                                printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
@@ -407,7 +407,7 @@ static void unstick_cu(struct device *dev)
                        else
                        {
                                unsigned short status = scb_status(dev);
-                               if (SCB_CUdead(status)) 
+                               if (SCB_CUdead(status))
                                {
                                        unsigned short txstatus = eexp_hw_lasttxstat(dev);
                                        printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
@@ -417,11 +417,11 @@ static void unstick_cu(struct device *dev)
                                else
                                {
                                        unsigned short txstatus = eexp_hw_lasttxstat(dev);
-                                       if (dev->tbusy && !txstatus) 
+                                       if (dev->tbusy && !txstatus)
                                        {
                                                printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
                                                       dev->name,status,txstatus);
-                                               eexp_hw_init586(dev); 
+                                               eexp_hw_init586(dev);
                                                dev->tbusy = 0;
                                                mark_bh(NET_BH);
                                        }
@@ -460,21 +460,21 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
 #endif
 
        outb(SIRQ_dis|irqrmap[dev->irq],dev->base_addr+SET_IRQ);
-       
+
        /* If dev->tbusy is set, all our tx buffers are full but the kernel
         * is calling us anyway.  Check that nothing bad is happening.
         */
-       if (dev->tbusy) 
+       if (dev->tbusy)
                unstick_cu(dev);
 
-       if (buf==NULL) 
+       if (buf==NULL)
        {
                /* Some higher layer thinks we might have missed a
                 * tx-done interrupt.  Does this ever actually happen?
                 */
                unsigned short status = scb_status(dev);
                unsigned short txstatus = eexp_hw_lasttxstat(dev);
-               if (SCB_CUdead(status)) 
+               if (SCB_CUdead(status))
                {
                        printk(KERN_WARNING "%s: CU has died! status %04x %04x, attempting to restart...\n",
                                dev->name, status, txstatus);
@@ -486,7 +486,7 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
                return 0;
        }
 
-       if (set_bit(0,(void *)&dev->tbusy)) 
+       if (set_bit(0,(void *)&dev->tbusy))
        {
                lp->stats.tx_dropped++;
        }
@@ -516,7 +516,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
        struct net_local *lp;
        unsigned short ioaddr,status,ack_cmd;
 
-       if (dev==NULL) 
+       if (dev==NULL)
        {
                printk(KERN_WARNING "eexpress: irq %d for unknown device\n",
                       irq);
@@ -526,10 +526,10 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
        lp = (struct net_local *)dev->priv;
        ioaddr = dev->base_addr;
 
-       outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ); 
+       outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
+
+       dev->interrupt = 1;
 
-       dev->interrupt = 1; 
-  
        status = scb_status(dev);
 
 #if NET_DEBUG > 4
@@ -538,7 +538,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
 
        ack_cmd = SCB_ack(status);
 
-       if (lp->started==0 && SCB_complete(status)) 
+       if (lp->started==0 && SCB_complete(status))
        {
                while (SCB_CUstat(status)==2)
                                status = scb_status(dev);
@@ -554,7 +554,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
                        tdr_status = inw(dev->base_addr + 0x8004);
                        if (tdr_status & TDR_SHORT) {
                                        printk(KERN_WARNING "%s: TDR reports cable short at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
-                       } 
+                       }
                        else if (tdr_status & TDR_OPEN) {
                                        printk(KERN_WARNING "%s: TDR reports cable broken at %d tick%s\n", dev->name, tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
                        }
@@ -573,18 +573,18 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
                scb_wrrfa(dev, lp->rx_buf_start);
                ack_cmd |= SCB_CUstart | SCB_RUstart | 0x2000;
        }
-       else if (lp->started) 
+       else if (lp->started)
        {
                unsigned short txstatus;
                txstatus = eexp_hw_lasttxstat(dev);
        }
 
-       if (SCB_rxdframe(status)) 
+       if (SCB_rxdframe(status))
        {
                eexp_hw_rx_pio(dev);
        }
 
-       if ((lp->started&2)!=0 && SCB_RUstat(status)!=4) 
+       if ((lp->started&2)!=0 && SCB_RUstat(status)!=4)
        {
                printk(KERN_WARNING "%s: RU stopped: status %04x\n",
                        dev->name,status);
@@ -592,14 +592,14 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
                eexp_hw_rxinit(dev);
                scb_wrrfa(dev, lp->rx_buf_start);
                ack_cmd |= SCB_RUstart;
-       } 
-       else if (lp->started==1 && SCB_RUstat(status)==4) 
+       }
+       else if (lp->started==1 && SCB_RUstat(status)==4)
                lp->started|=2;
 
        scb_command(dev, ack_cmd);
        outb(0,ioaddr+SIGNAL_CA);
 
-       outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); 
+       outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
 
        dev->interrupt = 0;
 #if NET_DEBUG > 6
@@ -617,7 +617,7 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
  * to the upper levels. Basic sanity check on each frame
  * descriptor, though we don't bother trying to fix broken ones.
  */
+
 static void eexp_hw_rx_pio(struct device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
@@ -629,7 +629,7 @@ static void eexp_hw_rx_pio(struct device *dev)
        printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
 #endif
 
-       while (boguscount--) 
+       while (boguscount--)
        {
                unsigned short status, rfd_cmd, rx_next, pbuf, pkt_len;
 
@@ -639,13 +639,13 @@ static void eexp_hw_rx_pio(struct device *dev)
                rx_next = inw(ioaddr + DATAPORT);
                pbuf = inw(ioaddr + DATAPORT);
 
-               if (FD_Done(status)) 
+               if (FD_Done(status))
                {
                        outw(pbuf, ioaddr + READ_PTR);
                        pkt_len = inw(ioaddr + DATAPORT);
 
                        if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16
-                               || (pkt_len & 0xc000)!=0xc000) 
+                               || (pkt_len & 0xc000)!=0xc000)
                        {
                                /* This should never happen.  If it does,
                                 * we almost certainly have a driver bug.
@@ -655,10 +655,10 @@ static void eexp_hw_rx_pio(struct device *dev)
                                        status,rfd_cmd,rx_next,pbuf,pkt_len);
                                continue;
                        }
-                       else if (!FD_OK(status)) 
+                       else if (!FD_OK(status))
                        {
                                lp->stats.rx_errors++;
-                               if (FD_CRC(status)) 
+                               if (FD_CRC(status))
                                        lp->stats.rx_crc_errors++;
                                if (FD_Align(status))
                                        lp->stats.rx_frame_errors++;
@@ -674,7 +674,7 @@ static void eexp_hw_rx_pio(struct device *dev)
                                struct sk_buff *skb;
                                pkt_len &= 0x3fff;
                                skb = dev_alloc_skb(pkt_len+16);
-                               if (skb == NULL) 
+                               if (skb == NULL)
                                {
                                        printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
                                        lp->stats.rx_dropped++;
@@ -732,11 +732,11 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
 
        dev->trans_start = jiffies;
        lp->tx_tail = lp->tx_head;
-       if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE)) 
+       if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
                lp->tx_head = TX_BUF_START;
-       else 
+       else
                lp->tx_head += TX_BUF_SIZE;
-       if (lp->tx_head != lp->tx_reap) 
+       if (lp->tx_head != lp->tx_reap)
                dev->tbusy = 0;
 }
 
@@ -768,7 +768,7 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
        hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
        hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
 
-       if (hw_addr[2]!=0x00aa || ((hw_addr[1] & 0xff00)!=0x0000)) 
+       if (hw_addr[2]!=0x00aa || ((hw_addr[1] & 0xff00)!=0x0000))
        {
                printk(" rejected: invalid address %04x%04x%04x\n",
                        hw_addr[2],hw_addr[1],hw_addr[0]);
@@ -776,15 +776,15 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
        }
 
        /* Calculate the EEPROM checksum.  Carry on anyway if it's bad,
-        * though. 
+        * though.
         */
        for (i = 0; i < 64; i++)
                xsum += eexp_hw_readeeprom(ioaddr, i);
-       if (xsum != 0xbaba) 
+       if (xsum != 0xbaba)
                printk(" (bad EEPROM xsum 0x%02x)", xsum);
 
        dev->base_addr = ioaddr;
-       for ( i=0 ; i<6 ; i++ ) 
+       for ( i=0 ; i<6 ; i++ )
                dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
 
        {
@@ -800,11 +800,11 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
        }
 
        dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-       if (!dev->priv) 
+       if (!dev->priv)
                return ENOMEM;
 
        memset(dev->priv, 0, sizeof(struct net_local));
-       
+
        printk("; using IRQ %d, %s connector", dev->irq,ifmap[dev->if_port]);
 
        /* Find out how much RAM we have on the card */
@@ -816,7 +816,7 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
        {
                outw(memory_size<<10, dev->base_addr + WRITE_PTR);
                outw(memory_size<<10, dev->base_addr + READ_PTR);
-               if (inw(dev->base_addr+DATAPORT)) 
+               if (inw(dev->base_addr+DATAPORT))
                        break;
                outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
                outw(memory_size<<10, dev->base_addr + READ_PTR);
@@ -863,19 +863,19 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
  * Read a word from the EtherExpress on-board serial EEPROM.
  * The EEPROM contains 64 words of 16 bits.
  */
-static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, 
+static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
                                         unsigned char location)
 {
        unsigned short cmd = 0x180|(location&0x7f);
        unsigned short rval = 0,wval = EC_CS|i586_RST;
        int i;
+
        outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
-       for (i=0x100 ; i ; i>>=1 ) 
+       for (i=0x100 ; i ; i>>=1 )
        {
-               if (cmd&i) 
+               if (cmd&i)
                        wval |= EC_Wr;
-               else 
+               else
                        wval &= ~EC_Wr;
 
                outb(wval,ioaddr+EEPROM_Ctrl);
@@ -883,14 +883,14 @@ static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
                eeprom_delay();
                outb(wval,ioaddr+EEPROM_Ctrl);
                eeprom_delay();
-       }       
+       }
        wval &= ~EC_Wr;
        outb(wval,ioaddr+EEPROM_Ctrl);
-       for (i=0x8000 ; i ; i>>=1 ) 
+       for (i=0x8000 ; i ; i>>=1 )
        {
                outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
                eeprom_delay();
-               if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd) 
+               if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
                        rval |= i;
                outb(wval,ioaddr+EEPROM_Ctrl);
                eeprom_delay();
@@ -918,36 +918,36 @@ static unsigned short eexp_hw_lasttxstat(struct device *dev)
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short tx_block = lp->tx_reap;
        unsigned short status;
-  
-       if ((!dev->tbusy) && lp->tx_head==lp->tx_reap) 
+
+       if ((!dev->tbusy) && lp->tx_head==lp->tx_reap)
                return 0x0000;
 
        do
        {
                outw(tx_block, dev->base_addr + SM_PTR);
                status = inw(SHADOW(tx_block));
-               if (!Stat_Done(status)) 
+               if (!Stat_Done(status))
                {
                        lp->tx_link = tx_block;
                        return status;
                }
-               else 
+               else
                {
                        lp->last_tx_restart = 0;
                        lp->stats.collisions += Stat_NoColl(status);
-                       if (!Stat_OK(status)) 
+                       if (!Stat_OK(status))
                        {
-                               if (Stat_Abort(status)) 
+                               if (Stat_Abort(status))
                                        lp->stats.tx_aborted_errors++;
-                               if (Stat_TNoCar(status) || Stat_TNoCTS(status)) 
+                               if (Stat_TNoCar(status) || Stat_TNoCTS(status))
                                        lp->stats.tx_carrier_errors++;
-                               if (Stat_TNoDMA(status)) 
+                               if (Stat_TNoDMA(status))
                                        lp->stats.tx_fifo_errors++;
                        }
                        else
                                lp->stats.tx_packets++;
                }
-               if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE)) 
+               if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
                        lp->tx_reap = tx_block = TX_BUF_START;
                else
                        lp->tx_reap = tx_block += TX_BUF_SIZE;
@@ -961,7 +961,7 @@ static unsigned short eexp_hw_lasttxstat(struct device *dev)
        return status;
 }
 
-/* 
+/*
  * This should never happen. It is called when some higher routine detects
  * that the CU has stopped, to try to restart it from the last packet we knew
  * we were working on, or the idle loop if we had finished for the time.
@@ -971,7 +971,7 @@ static void eexp_hw_txrestart(struct device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short ioaddr = dev->base_addr;
-  
+
        lp->last_tx_restart = lp->tx_link;
        scb_wrcbl(dev, lp->tx_link);
        scb_command(dev, SCB_CUstart);
@@ -979,11 +979,11 @@ static void eexp_hw_txrestart(struct device *dev)
 
        {
                unsigned short boguscount=50,failcount=5;
-               while (!scb_status(dev)) 
+               while (!scb_status(dev))
                {
-                       if (!--boguscount) 
+                       if (!--boguscount)
                        {
-                               if (--failcount) 
+                               if (--failcount)
                                {
                                        printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
                                        scb_wrcbl(dev, lp->tx_link);
@@ -1007,10 +1007,10 @@ static void eexp_hw_txrestart(struct device *dev)
 /*
  * Writes down the list of transmit buffers into card memory.  Each
  * entry consists of an 82586 transmit command, followed by a jump
- * pointing to itself.  When we want to transmit a packet, we write 
+ * pointing to itself.  When we want to transmit a packet, we write
  * the data into the appropriate transmit buffer and then modify the
  * preceding jump to point at the new transmit command.  This means that
- * the 586 command unit is continuously active. 
+ * the 586 command unit is continuously active.
  */
 
 static void eexp_hw_txinit(struct device *dev)
@@ -1020,7 +1020,7 @@ static void eexp_hw_txinit(struct device *dev)
        unsigned short curtbuf;
        unsigned short ioaddr = dev->base_addr;
 
-       for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ ) 
+       for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
        {
                outw(tx_block, ioaddr + WRITE_PTR);
 
@@ -1052,23 +1052,23 @@ static void eexp_hw_txinit(struct device *dev)
  * Write the circular list of receive buffer descriptors to card memory.
  * The end of the list isn't marked, which means that the 82586 receive
  * unit will loop until buffers become available (this avoids it giving us
- * "out of resources" messages). 
+ * "out of resources" messages).
  */
 
 static void eexp_hw_rxinit(struct device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short rx_block = lp->rx_buf_start;
-       unsigned short ioaddr = dev->base_addr; 
+       unsigned short ioaddr = dev->base_addr;
 
        lp->num_rx_bufs = 0;
        lp->rx_first = rx_block;
-       do 
+       do
        {
                lp->num_rx_bufs++;
 
                outw(rx_block, ioaddr + WRITE_PTR);
-               
+
                outw(0, ioaddr + DATAPORT);  outw(0, ioaddr+DATAPORT);
                outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
                outw(rx_block + 0x16, ioaddr+DATAPORT);
@@ -1080,8 +1080,8 @@ static void eexp_hw_rxinit(struct device *dev)
                outw(0xdead, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
-               
-               outw(0x8000, ioaddr+DATAPORT); 
+
+               outw(0x8000, ioaddr+DATAPORT);
                outw(0xffff, ioaddr+DATAPORT);
                outw(rx_block + 0x20, ioaddr+DATAPORT);
                outw(0, ioaddr+DATAPORT);
@@ -1114,7 +1114,7 @@ static void eexp_hw_init586(struct device *dev)
 
        lp->started = 0;
 
-       set_loopback(dev);  
+       set_loopback(dev);
 
        /* Bash the startup code a bit */
        start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):
@@ -1122,7 +1122,7 @@ static void eexp_hw_init586(struct device *dev)
        lp->promisc = dev->flags & IFF_PROMISC;
        memcpy(&start_code[33], &dev->dev_addr[0], 6);
 
-       outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ); 
+       outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
 
        /* Download the startup code */
        outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
@@ -1155,16 +1155,16 @@ static void eexp_hw_init586(struct device *dev)
 
        {
                unsigned short rboguscount=50,rfailcount=5;
-               while (inw(ioaddr+0x4000)) 
+               while (inw(ioaddr+0x4000))
                {
-                       if (!--rboguscount) 
+                       if (!--rboguscount)
                        {
                                printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
                                        dev->name);
                                scb_command(dev, 0);
                                outb(0,ioaddr+SIGNAL_CA);
                                rboguscount = 100;
-                               if (!--rfailcount) 
+                               if (!--rfailcount)
                                {
                                        printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
                                                dev->name);
@@ -1180,11 +1180,11 @@ static void eexp_hw_init586(struct device *dev)
 
        {
                unsigned short iboguscount=50,ifailcount=5;
-               while (!scb_status(dev)) 
+               while (!scb_status(dev))
                {
-                       if (!--iboguscount) 
+                       if (!--iboguscount)
                        {
-                               if (--ifailcount) 
+                               if (--ifailcount)
                                {
                                        printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
                                                dev->name, scb_status(dev), scb_rdcmd(dev));
@@ -1193,7 +1193,7 @@ static void eexp_hw_init586(struct device *dev)
                                        outb(0,ioaddr+SIGNAL_CA);
                                        iboguscount = 100;
                                }
-                               else 
+                               else
                                {
                                        printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
                                        return;
@@ -1201,9 +1201,9 @@ static void eexp_hw_init586(struct device *dev)
                        }
                }
        }
-  
-       clear_loopback(dev); 
-       outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ); 
+
+       clear_loopback(dev);
+       outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);
 
        lp->init_time = jiffies;
 #if NET_DEBUG > 6
@@ -1232,15 +1232,18 @@ eexp_set_multicast(struct device *dev)
 
 static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
 
-static struct device dev_eexp[EEXP_MAX_CARDS] = 
+static struct device dev_eexp[EEXP_MAX_CARDS] =
 {
         { NULL,         /* will allocate dynamically */
-         0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },  
+         0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
 };
 
 static int irq[EEXP_MAX_CARDS] = {0, };
 static int io[EEXP_MAX_CARDS] = {0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(EEXP_MAX_CARDS) "i");
+
 /* Ideally the user would give us io=, irq= for every card.  If any parameters
  * are specified, we verify and then use them.  If no parameters are given, we
  * autoprobe for one card only.
@@ -1271,7 +1274,7 @@ int init_module(void)
 void cleanup_module(void)
 {
        int this_dev;
-        
+
        for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
                struct device *dev = &dev_eexp[this_dev];
                if (dev->priv != NULL) {
index 09bb0be4773827f6bf56890be424fb6df7d5d0be..f67e5a4a9e03023aa764fe40c54b55d7cbd976d4 100644 (file)
@@ -17,8 +17,8 @@
        3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files.
           Too bad it doesn't work -- see below.
 
-       The ES3210 is an EISA shared memory NS8390 implementation. Note 
-       that all memory copies to/from the board must be 32bit transfers. 
+       The ES3210 is an EISA shared memory NS8390 implementation. Note
+       that all memory copies to/from the board must be 32bit transfers.
        Which rules out using eth_io_copy_and_sum() in this driver.
 
        Apparently there are two slightly different revisions of the
@@ -26,7 +26,7 @@
        and !rii0102.cfg) One has media select in the cfg file and the
        other doesn't. Hopefully this will work with either.
 
-       That is about all I can tell you about it, having never actually 
+       That is about all I can tell you about it, having never actually
        even seen one of these cards. :)  Try http://www.interlan.com
        if you want more info.
 
@@ -86,7 +86,7 @@ static void es_block_output(struct device *dev, int count, const unsigned char *
 #define ES_ADDR2       0x01
 
 /*
- * Two card revisions. EISA ID's are always rev. minor, rev. major,, and 
+ * Two card revisions. EISA ID's are always rev. minor, rev. major,, and
  * then the three vendor letters stored in 5 bits each, with an "a" = 1.
  * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA
  * config utility determines automagically what config file(s) to use.
@@ -117,7 +117,7 @@ static void es_block_output(struct device *dev, int count, const unsigned char *
 static unsigned char lo_irq_map[] = {3, 4, 5, 6, 7, 9, 10};
 static unsigned char hi_irq_map[] = {11, 12, 0, 14, 0, 0, 0, 15};
 
-/* 
+/*
  *     Probe for the card. The best way is to read the EISA ID if it
  *     is known. Then we check the prefix of the station address
  *     PROM for a match against the Racal-Interlan assigned value.
@@ -168,7 +168,7 @@ int es_probe1(struct device *dev, int ioaddr)
        if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) {
                return ENODEV;
        }
-       
+
 /*     Check the Racal vendor ID as well. */
        if (inb(ioaddr + ES_SA_PROM + 0) != ES_ADDR0
                || inb(ioaddr + ES_SA_PROM + 1) != ES_ADDR1
@@ -187,7 +187,7 @@ int es_probe1(struct device *dev, int ioaddr)
        }
 
        printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr);
-       for(i = 0; i < ETHER_ADDR_LEN; i++) 
+       for(i = 0; i < ETHER_ADDR_LEN; i++)
                printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i)));
 
        /* Snarf the interrupt now. */
@@ -303,7 +303,7 @@ static void es_reset_8390(struct device *dev)
  *     that the associated memcpy will only use "rep; movsl" as long as
  *     we keep the counts as some multiple of doublewords. This is a
  *     requirement of the hardware, and also prevents us from using
- *     eth_io_copy_and_sum() since we can't guarantee it will limit 
+ *     eth_io_copy_and_sum() since we can't guarantee it will limit
  *     itself to doubleword access.
  */
 
@@ -321,7 +321,7 @@ es_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
        hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
 
-/*     
+/*
  *     Block input and output are easy on shared memory ethercards, the only
  *     complication is when the ring buffer wraps. The count will already
  *     be rounded up to a doubleword value via es_get_8390_hdr() above.
@@ -392,6 +392,10 @@ static int io[MAX_ES_CARDS] = { 0, };
 static int irq[MAX_ES_CARDS]  = { 0, };
 static int mem[MAX_ES_CARDS] = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_ES_CARDS) "i");
+
 int
 init_module(void)
 {
@@ -435,4 +439,3 @@ cleanup_module(void)
        }
 }
 #endif /* MODULE */
-
index 143578a939b2273faad378ff3eeafdf9728c6511..a5727b2fe655b265545ee4bd938ff9861f723bd9 100644 (file)
    Sources:
      - skeleton.c  a sample network driver core for linux,
        written by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
-     - at1700.c a driver for Allied Telesis AT1700, written 
+     - at1700.c a driver for Allied Telesis AT1700, written
        by Donald Becker.
      - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
        written by Markku Viima
      - The Fujitsu MB86965 databook.
-   
+
    Valuable assistance from:
-       Markku Viima (ICL) 
+       Markku Viima (ICL)
        Ari Valve (ICL)
-   
+
    Revision history:
 
    Version     Date            Description
-   
+
    0.01                15.12-94        Initial version (card detection)
    0.02         23.01-95        Interrupt is now hooked correctly
    0.03         01.02-95        Rewrote initialization part
@@ -44,7 +44,7 @@
    0.05                08.02-95        If there were more than one packet to send,
                                transmit was jammed due to invalid
                                register write...now fixed
-   0.06         19.02-95        Rewrote interrupt handling        
+   0.06         19.02-95        Rewrote interrupt handling
    0.07         13.04-95        Wrote EEPROM read routines
                                 Card configuration now set according to
                                data read from EEPROM
                                 port if AUTO is selected
 
    0.09         01.09-95       Added module support
-   
-   0.10         04.09-95       Fixed receive packet allocation to work         
+
+   0.10         04.09-95       Fixed receive packet allocation to work
                                with kernels > 1.3.x
-   
-   0.20                20.09-95        Added support for EtherTeam32 EISA      
 
-   0.21         17.10-95        Removed the unnecessary extern 
+   0.20                20.09-95        Added support for EtherTeam32 EISA
+
+   0.21         17.10-95        Removed the unnecessary extern
                                init_etherdev() declaration. Some
                                other cleanups.
    Bugs:
-       In some cases the interface autoprobing code doesn't find 
-       the correct interface type. In this case you can 
-       manually choose the interface type in DOS with E16IC.EXE which is 
+       In some cases the interface autoprobing code doesn't find
+       the correct interface type. In this case you can
+       manually choose the interface type in DOS with E16IC.EXE which is
        configuration software for EtherTeam16i and EtherTeam32 cards.
-       
+
    To do:
        - Real multicast support
 */
 
-static char *version = 
+static char *version =
        "eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n";
 
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/types.h>                 
-#include <linux/fcntl.h>                 
-#include <linux/interrupt.h>             
-#include <linux/ptrace.h>                
-#include <linux/ioport.h>                
-#include <linux/in.h>            
-#include <linux/malloc.h>                
-#include <linux/string.h>                
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
 #include <linux/errno.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-#include <asm/system.h>                  
-#include <asm/bitops.h>                  
-#include <asm/io.h>              
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
 #include <asm/dma.h>
 
 /* Few macros */
-#define BIT(a)                 ( (1 << (a)) )  
-#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) 
+#define BIT(a)                 ( (1 << (a)) )
+#define BITSET(ioaddr, bnum)   ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
 #define BITCLR(ioaddr, bnum)   ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
 
 /* This is the I/O address space for Etherteam 16i adapter. */
@@ -114,7 +114,7 @@ static char *version =
 /* Some interrupt masks */
 #define ETH16I_INTR_ON        0x8f82
 #define ETH16I_INTR_OFF               0x0000
-        
+
 /* Buffers header status byte meanings */
 #define PKT_GOOD               BIT(5)
 #define PKT_GOOD_RMT           BIT(4)
@@ -140,7 +140,7 @@ static char *version =
 #define ALIGN_ERR              BIT(2)
 #define CRC_ERR                BIT(1)
 #define RX_BUF_OVERFLOW        BIT(0)
-              
+
 /* Transmit Interrupt Enable Register (DLCR2) */
 #define TX_INTR_REG            2
 #define TX_INTR_DONE           BIT(7)
@@ -179,14 +179,14 @@ static char *version =
 #define SRAM_CYCLE_TIME_100NS  BIT(6)
 #define SYSTEM_BUS_WIDTH_8     BIT(5)       /* 1 = 8bit, 0 = 16bit */
 #define BUFFER_WIDTH_8         BIT(4)       /* 1 = 8bit, 0 = 16bit */
-#define TBS1                   BIT(3)       
+#define TBS1                   BIT(3)
 #define TBS0                   BIT(2)
 #define MBS1                   BIT(1)       /* 00=8kb,  01=16kb  */
 #define MBS0                   BIT(0)       /* 10=32kb, 11=64kb  */
 
-#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */ 
+#ifndef ETH16I_TX_BUF_SIZE                   /* 0 = 2kb, 1 = 4kb  */
 #define ETH16I_TX_BUF_SIZE     2             /* 2 = 8kb, 3 = 16kb */
-#endif                                      
+#endif
 #define TX_BUF_1x2048            0
 #define TX_BUF_2x2048            1
 #define TX_BUF_2x4098            2
@@ -221,7 +221,7 @@ static char *version =
 
 /* DMA Burst and Transceiver Mode Register (BMPR13) */
 #define TRANSCEIVER_MODE_REG   13
-#define TRANSCEIVER_MODE_RB    2         
+#define TRANSCEIVER_MODE_RB    2
 #define IO_BASE_UNLOCK        BIT(7)
 #define LOWER_SQUELCH_TRESH    BIT(6)
 #define LINK_TEST_DISABLE      BIT(5)
@@ -261,7 +261,7 @@ static char *version =
   #define E_PORT_TP                    2
   #define E_PORT_AUTO                  3
 #define E_PRODUCT_CFG                  0x30
+
 
 /* Macro to slow down io between EEPROM clock transitions */
 #define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { __SLOW_DOWN_IO; }}while(0)
@@ -286,7 +286,7 @@ static unsigned int eth32i_portlist[] =
 static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15 };
 
 /* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };  
+static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };
 #define EISA_IRQ_REG   0xc89
 
 static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
@@ -303,7 +303,7 @@ struct eth16i_local {
   struct enet_statistics stats;
   unsigned int tx_started:1;
   unsigned char tx_queue;         /* Number of packets in transmit buffer */
-  unsigned short tx_queue_len;         
+  unsigned short tx_queue_len;
   unsigned int tx_buf_size;
   unsigned long open_time;
 };
@@ -327,17 +327,17 @@ static int eth16i_close(struct device *dev);
 static int eth16i_tx(struct sk_buff *skb, struct device *dev);
 static void eth16i_rx(struct device *dev);
 static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev); 
+static void eth16i_multicast(struct device *dev);
 static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
 static void eth16i_initialize(struct device *dev);
 static struct enet_statistics *eth16i_get_stats(struct device *dev);
 
 static char *cardname = "ICL EtherTeam 16i/32";
 
-#ifdef HAVE_DEVLIST 
+#ifdef HAVE_DEVLIST
 /* Support for alternate probe manager */
-/struct netdev_entry eth16i_drv = 
-   {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list}; 
+/struct netdev_entry eth16i_drv =
+   {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
 
 #else  /* Not HAVE_DEVLIST */
 int eth16i_probe(struct device *dev)
@@ -346,7 +346,7 @@ int eth16i_probe(struct device *dev)
   int ioaddr;
   int base_addr = dev ? dev->base_addr : 0;
 
-  if(eth16i_debug > 4) 
+  if(eth16i_debug > 4)
     printk("Probing started for %s\n", cardname);
 
   if(base_addr > 0x1ff)           /* Check only single location */
@@ -381,12 +381,12 @@ static int eth16i_probe1(struct device *dev, short ioaddr)
   boot = 1;          /* To inform initialization that we are in boot probe */
 
   /*
-     The MB86985 chip has on register which holds information in which 
+     The MB86985 chip has on register which holds information in which
      io address the chip lies. First read this register and compare
      it to our current io address and if match then this could
      be our chip.
   */
-  
+
   if(ioaddr < 0x1000) {
     if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
       return -ENODEV;
@@ -396,21 +396,21 @@ static int eth16i_probe1(struct device *dev, short ioaddr)
 
   if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
     return -ENODEV;
-  
-  /* 
+
+  /*
      Now it seems that we have found an ethernet chip in this particular
-     ioaddr. The MB86985 chip has this feature, that when you read a 
+     ioaddr. The MB86985 chip has this feature, that when you read a
      certain register it will increase its io base address to next
      configurable slot. Now when we have found the chip, first thing is
      to make sure that the chip's ioaddr will hold still here.
   */
-  
+
   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
   outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
-  
+
   outb(0x00, ioaddr + RESET);             /* Will reset some parts of chip */
   BITSET(ioaddr + CONFIG_REG_0, BIT(7));  /* This will disable the data link */
-  
+
   if(dev == NULL)
     dev = init_etherdev(0, sizeof(struct eth16i_local));
 
@@ -418,18 +418,18 @@ static int eth16i_probe1(struct device *dev, short ioaddr)
     printk(version);
 
   dev->base_addr = ioaddr;
+
   irq = eth16i_get_irq(ioaddr);
   dev->irq = irq;
 
   /* Try to obtain interrupt vector */
   if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i", NULL)) {
-    printk("%s: %s at %#3x, but is unusable due 
+    printk("%s: %s at %#3x, but is unusable due
            conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
     return EAGAIN;
   }
 
-  printk("%s: %s at %#3x, IRQ %d, ", 
+  printk("%s: %s at %#3x, IRQ %d, ",
         dev->name, cardname, ioaddr, dev->irq);
 
   /* Let's grab the region */
@@ -437,13 +437,13 @@ static int eth16i_probe1(struct device *dev, short ioaddr)
 
   /* Now we will have to lock the chip's io address */
   eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
-  outb(0x38, ioaddr + TRANSCEIVER_MODE_REG); 
+  outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
 
   eth16i_initialize(dev);   /* Initialize rest of the chip's registers */
-  
+
   /* Now let's same some energy by shutting down the chip ;) */
   BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-   
+
   /* Initialize the device structure */
   if(dev->priv == NULL)
     dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
@@ -477,7 +477,7 @@ static void eth16i_initialize(struct device *dev)
     ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
   }
 
-  for(i = 0; i < 6; i++) { 
+  for(i = 0; i < 6; i++) {
     outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
     if(boot) {
       printk("%02x", inb(ioaddr + NODE_ID_0 + i));
@@ -488,11 +488,11 @@ static void eth16i_initialize(struct device *dev)
 
   /* Now we will set multicast addresses to accept none */
   eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
-  for(i = 0; i < 8; i++) 
+  for(i = 0; i < 8; i++)
     outb(0x00, ioaddr + HASH_TABLE_0 + i);
 
   /*
-     Now let's disable the transmitter and receiver, set the buffer ram 
+     Now let's disable the transmitter and receiver, set the buffer ram
      cycle time, bus width and buffer data path width. Also we shall
      set transmit buffer size and total buffer size.
   */
@@ -509,7 +509,7 @@ static void eth16i_initialize(struct device *dev)
 
   if( (node_w & 0x00FF) == 64)
     node_byte |= MBS0;
-  
+
   node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
 
   outb(node_byte, ioaddr + CONFIG_REG_0);
@@ -520,15 +520,15 @@ static void eth16i_initialize(struct device *dev)
   if(boot) /* Now set port type */
   {
     char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
-    
+
     ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
     dev->if_port = (ptype & 0x00FF);
-    
+
     printk(" %s interface.\n", porttype[dev->if_port]);
 
     if(ptype == E_PORT_AUTO)
       ptype = eth16i_probe_port(ioaddr);
-    
+
     eth16i_set_port(ioaddr, ptype);
   }
 
@@ -563,7 +563,7 @@ static int eth16i_probe_port(short ioaddr)
     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
     eth16i_set_port(ioaddr, i);
-   
+
     if(eth16i_debug > 1)
        printk("Set port number %d\n", i);
 
@@ -581,15 +581,15 @@ static int eth16i_probe_port(short ioaddr)
        printk("TRANSMIT_DONE timeout\n");
     }
   }
-  
+
   if( eth16i_debug > 1)
        printk("Using default port\n");
+
  return E_PORT_BNC;
 }
 
 static void eth16i_set_port(short ioaddr, int porttype)
-{ 
+{
     unsigned short temp = 0;
 
     eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
@@ -605,12 +605,12 @@ static void eth16i_set_port(short ioaddr, int porttype)
 
     case E_PORT_TP :
       break;
-      
+
     case E_PORT_DIX :
       temp |= AUI_SELECT;
       BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
       break;
-    }  
+    }
     outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
 
     if(eth16i_debug > 1) {
@@ -626,29 +626,29 @@ static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l)
   outb(0xff, ioaddr + TX_STATUS_REG);
 
   outw(l, ioaddr + DATAPORT);
-  outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);  
-  
+  outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
+
   starttime = jiffies;
-  outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); 
+  outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
 
   while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
     if( (jiffies - starttime) > TIMEOUT_TICKS) {
       break;
     }
   }
-  
+
   return(0);
 }
 
 static int eth16i_receive_probe_packet(short ioaddr)
 {
   int starttime;
-  
+
   starttime = jiffies;
-  
+
   while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
     if( (jiffies - starttime) > TIMEOUT_TICKS) {
-      
+
       if(eth16i_debug > 1)
        printk("Timeout occurred waiting transmit packet received\n");
       starttime = jiffies;
@@ -659,7 +659,7 @@ static int eth16i_receive_probe_packet(short ioaddr)
         return -1;
         }
       }
-      
+
       if(eth16i_debug > 1)
        printk("RECEIVE_PACKET\n");
       return(0); /* Found receive packet */
@@ -677,7 +677,7 @@ static int eth16i_receive_probe_packet(short ioaddr)
 static int eth16i_get_irq(short ioaddr)
 {
   unsigned char cbyte;
-  
+
   if( ioaddr < 0x1000) {
        cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
        return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
@@ -696,11 +696,11 @@ static int eth16i_check_signature(short ioaddr)
 {
   int i;
   unsigned char creg[4] = { 0 };
-  
+
   for(i = 0; i < 4 ; i++) {
 
     creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
-  
+
     if(eth16i_debug > 1)
        printk("eth16i: read signature byte %x at %x\n", creg[i],
               ioaddr + TRANSMIT_MODE_REG + i);
@@ -710,7 +710,7 @@ static int eth16i_check_signature(short ioaddr)
   creg[2] &= 0x7F;      /* Mask DCLEN bit */
 
 #ifdef 0
-/* 
+/*
        This was removed because the card was sometimes left to state
        from which it couldn't be find anymore. If there is need
        to more strict chech still this have to be fixed.
@@ -746,7 +746,7 @@ static int eth16i_read_eeprom(int ioaddr, int offset)
   data = eth16i_read_eeprom_word(ioaddr);
   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
 
-  return(data);  
+  return(data);
 }
 
 static int eth16i_read_eeprom_word(int ioaddr)
@@ -769,7 +769,7 @@ static int eth16i_read_eeprom_word(int ioaddr)
 static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
 {
   int i;
-  
+
   outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
   outb(DI_0, ioaddr + EEPROM_DATA_REG);
   outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
@@ -783,31 +783,31 @@ static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
     eeprom_slow_io();
     outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
     eeprom_slow_io();
-  } 
+  }
 }
 
 static int eth16i_open(struct device *dev)
 {
   struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
   int ioaddr = dev->base_addr;
-  
+
   irq2dev_map[dev->irq] = dev;
 
   /* Powerup the chip */
   outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-  
+
   /* Initialize the chip */
-  eth16i_initialize(dev);  
-  
+  eth16i_initialize(dev);
+
   /* Set the transmit buffer size */
   lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
-  
+
   if(eth16i_debug > 3)
     printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
 
   /* Now enable Transmitter and Receiver sections */
   BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
+
   /* Now switch to register bank 2, for run time operation */
   eth16i_select_regbank(2, ioaddr);
 
@@ -817,7 +817,7 @@ static int eth16i_open(struct device *dev)
   lp->tx_queue_len = 0;
 
   /* Turn on interrupts*/
-  outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);  
+  outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
   dev->tbusy = 0;
   dev->interrupt = 0;
@@ -862,24 +862,24 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
   int ioaddr = dev->base_addr;
 
   if(dev->tbusy) {
-    /* 
-       If we get here, some higher level has decided that we are broken. 
-       There should really be a "kick me" function call instead. 
+    /*
+       If we get here, some higher level has decided that we are broken.
+       There should really be a "kick me" function call instead.
     */
-    
+
     int tickssofar = jiffies - dev->trans_start;
-    if(tickssofar < TIMEOUT_TICKS)  /* Let's not rush with our timeout, */  
+    if(tickssofar < TIMEOUT_TICKS)  /* Let's not rush with our timeout, */
       return 1;                     /* wait a couple of ticks first     */
 
     printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
-          inw(ioaddr + TX_STATUS_REG), 
-          (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ? 
+          inw(ioaddr + TX_STATUS_REG),
+          (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
           "IRQ conflict" : "network cable problem");
 
     /* Let's dump all registers */
-    if(eth16i_debug > 0) { 
+    if(eth16i_debug > 0) {
       printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
-            dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2), 
+            dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2),
             inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
             inb(ioaddr + 6), inb(ioaddr + 7));
 
@@ -893,27 +893,27 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
     lp->stats.tx_errors++;
 
     /* Now let's try to restart the adaptor */
-    
+
     BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
     outw(0xffff, ioaddr + RESET);
     eth16i_initialize(dev);
     outw(0xffff, ioaddr + TX_STATUS_REG);
     BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-            
+
     lp->tx_started = 0;
     lp->tx_queue = 0;
     lp->tx_queue_len = 0;
-    
+
     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-    
+
     dev->tbusy = 0;
     dev->trans_start = jiffies;
   }
 
-  /* 
+  /*
      If some higher layer thinks we've missed an tx-done interrupt
      we are passed NULL. Caution: dev_tint() handles the cli()/sti()
-     itself 
+     itself
   */
   if(skb == NULL) {
     dev_tint(dev);
@@ -931,19 +931,19 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
   else {
     short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
     unsigned char *buf = skb->data;
-  
+
     outw(length, ioaddr + DATAPORT);
-    
-    if( ioaddr < 0x1000 ) 
+
+    if( ioaddr < 0x1000 )
        outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
     else {
        unsigned char frag = length % 4;
 
        outsl(ioaddr + DATAPORT, buf, length >> 2);
-       
+
        if( frag != 0 ) {
          outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
-         if( frag == 3 ) 
+         if( frag == 3 )
            outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
        }
     }
@@ -964,12 +964,12 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
       /* There is still more room for one more packet in tx buffer */
       dev->tbusy = 0;
     }
-        
+
     outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
     /* Turn TX interrupts back on */
     /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
-  } 
+  }
   dev_kfree_skb(skb, FREE_WRITE);
 
   return 0;
@@ -983,14 +983,14 @@ static void eth16i_rx(struct device *dev)
 
   /* Loop until all packets have been read */
   while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
-    
-    /* Read status byte from receive buffer */ 
+
+    /* Read status byte from receive buffer */
     ushort status = inw(ioaddr + DATAPORT);
 
     if(eth16i_debug > 4)
-      printk("%s: Receiving packet mode %02x status %04x.\n", 
+      printk("%s: Receiving packet mode %02x status %04x.\n",
             dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
-  
+
       if( !(status & PKT_GOOD) ) {
        /* Hmm..something went wrong. Let's check what error occurred */
        lp->stats.rx_errors++;
@@ -1006,7 +1006,7 @@ static void eth16i_rx(struct device *dev)
        ushort pkt_len = inw(ioaddr + DATAPORT);
 
        if(pkt_len > ETH_FRAME_LEN) {
-         printk("%s: %s claimed a very large packet, size of %d bytes.\n", 
+         printk("%s: %s claimed a very large packet, size of %d bytes.\n",
                 dev->name, cardname, pkt_len);
          outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
          lp->stats.rx_dropped++;
@@ -1015,29 +1015,29 @@ static void eth16i_rx(struct device *dev)
 
        skb = dev_alloc_skb(pkt_len + 3);
        if( skb == NULL ) {
-         printk("%s: Couldn't allocate memory for packet (len %d)\n", 
+         printk("%s: Couldn't allocate memory for packet (len %d)\n",
                 dev->name, pkt_len);
          outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
          lp->stats.rx_dropped++;
          break;
        }
-       
+
        skb->dev = dev;
        skb_reserve(skb,2);
-       /* 
+       /*
           Now let's get the packet out of buffer.
           size is (pkt_len + 1) >> 1, cause we are now reading words
           and it have to be even aligned.
-       */ 
+       */
 
-       if( ioaddr < 0x1000) 
+       if( ioaddr < 0x1000)
          insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
-       else {  
+       else {
          unsigned char *buf = skb_put(skb, pkt_len);
          unsigned char frag = pkt_len % 4;
 
          insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
-       
+
          if(frag != 0) {
                unsigned short rest[2];
                rest[0] = inw( ioaddr + DATAPORT );
@@ -1047,19 +1047,19 @@ static void eth16i_rx(struct device *dev)
                memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
          }
        }
-       
+
         skb->protocol=eth_type_trans(skb, dev);
        netif_rx(skb);
        lp->stats.rx_packets++;
-         
+
        if( eth16i_debug > 5 ) {
          int i;
          printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
-         for(i = 0; i < 14; i++) 
+         for(i = 0; i < 14; i++)
            printk(" %02x", skb->data[i]);
          printk(".\n");
        }
-       
+
       } /* else */
 
     if(--boguscount <= 0)
@@ -1099,7 +1099,7 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   }
 
   /* Turn off all interrupts from adapter */
-  outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG); 
+  outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
 
   dev->interrupt = 1;
 
@@ -1107,12 +1107,12 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   lp = (struct eth16i_local *)dev->priv;
   status = inw(ioaddr + TX_STATUS_REG);      /* Get the status */
   outw(status, ioaddr + TX_STATUS_REG);      /* Clear status bits */
-  
+
   if(eth16i_debug > 3)
     printk("%s: Interrupt with status %04x.\n", dev->name, status);
 
   if( status & 0x00ff ) {          /* Let's check the transmit status reg */
-    
+
     if(status & TX_DONE) {         /* The transmit has been done */
       lp->stats.tx_packets++;
 
@@ -1133,14 +1133,14 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
       }
     }
   }
-    
-  if( ( status & 0xff00 ) || 
+
+  if( ( status & 0xff00 ) ||
      ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
     eth16i_rx(dev);  /* We have packet in receive buffer */
   }
 
   dev->interrupt = 0;
-  
+
   /* Turn interrupts back on */
   outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
 
@@ -1150,11 +1150,11 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void eth16i_multicast(struct device *dev)
 {
   short ioaddr = dev->base_addr;
-  
-  if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC)) 
+
+  if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
   {
     dev->flags|=IFF_PROMISC;   /* Must do this */
-    outb(3, ioaddr + RECEIVE_MODE_REG);    
+    outb(3, ioaddr + RECEIVE_MODE_REG);
   } else {
     outb(2, ioaddr + RECEIVE_MODE_REG);
   }
@@ -1172,7 +1172,7 @@ static void eth16i_select_regbank(unsigned char banknbr, short ioaddr)
   unsigned char data;
 
   data = inb(ioaddr + CONFIG_REG_1);
-  outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1); 
+  outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
 }
 
 #ifdef MODULE
@@ -1186,11 +1186,14 @@ static struct device dev_eth16i = {
 int io = 0x2a0;
 int irq = 0;
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int init_module(void)
 {
        if(io == 0)
                printk("eth16i: You should not use auto-probing with insmod!\n");
-       
+
        dev_eth16i.base_addr = io;
        dev_eth16i.irq = irq;
        if( register_netdev( &dev_eth16i ) != 0 ) {
@@ -1210,5 +1213,3 @@ void cleanup_module(void)
 }
 
 #endif /* MODULE */
-
-
index 5c4c8c31c7c878ce735bc772e2e30740a5872b95..a5d6ec240d5a849c60243899e8d5a1e0f088efae 100644 (file)
     kernel with the ewrk3 configuration turned off and reboot.
     5) insmod ewrk3.o
           [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
-    6) run the net startup bits for your new eth?? interface manually 
-    (usually /etc/rc.inet[12] at boot time). 
+    6) run the net startup bits for your new eth?? interface manually
+    (usually /etc/rc.inet[12] at boot time).
     7) enjoy!
 
     Note that autoprobing is not allowed in loadable modules - the system is
     already up and running and you're messing with interrupts.
 
-    To unload a module, turn off the associated interface 
+    To unload a module, turn off the associated interface
     'ifconfig eth?? down' then 'rmmod ewrk3'.
 
     Promiscuous   mode has been  turned  off  in this driver,   but  all the
     ----------------
 
     Version   Date        Description
-  
+
       0.1     26-aug-94   Initial writing. ALPHA code release.
-      0.11    31-aug-94   Fixed: 2k mode memory base calc., 
+      0.11    31-aug-94   Fixed: 2k mode memory base calc.,
                                  LeMAC version calc.,
                                 IRQ vector assignments during autoprobe.
       0.12    31-aug-94   Tested working on LeMAC2 (DE20[345]-AC) card.
                           Added verify_area() calls in ewrk3_ioctl() from
                           suggestion by <heiko@colossus.escape.de>.
                          Add new multicasting code.
-      0.41    20-Jan-96   Fix IRQ set up problem reported by 
+      0.41    20-Jan-96   Fix IRQ set up problem reported by
                           <kenneth@bbs.sas.ntu.ac.sg>.
       0.42    22-Apr-96          Fix alloc_device() bug <jari@markkus2.fimr.fi>
       0.43    16-Aug-96          Update alloc_device() to conform to de4x5.c
@@ -196,7 +196,7 @@ static int ewrk3_debug = 1;
 #define MAX_NUM_EWRK3S 21
 #endif
 
-#ifndef EWRK3_EISA_IO_PORTS 
+#ifndef EWRK3_EISA_IO_PORTS
 #define EWRK3_EISA_IO_PORTS 0x0c00      /* I/O port base address, slot 0 */
 #endif
 
@@ -358,7 +358,7 @@ int ewrk3_probe(struct device *dev)
     eisa_probe(dev, iobase);
 
     if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
-      printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name, 
+      printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
                                                                       iobase);
     }
 
@@ -419,7 +419,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
       EthwrkSignature(name, eeprom_image);
       if (*name != '\0') {                         /* found a EWRK3 device */
        dev->base_addr = iobase;
-      
+
        if (iobase > 0x400) {
          outb(eisa_cr, EISA_CR);                  /* Rewrite the EISA CR */
        }
@@ -433,12 +433,12 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
          hard_strapped = 1;
        } else if ((iobase&0x0fff)==EWRK3_EISA_IO_PORTS) {
                                                   /* EISA slot address */
-         printk("%s: %s at %#4lx (EISA slot %ld)", 
+         printk("%s: %s at %#4lx (EISA slot %ld)",
                                 dev->name, name, iobase, ((iobase>>12)&0x0f));
        } else {                                   /* ISA port address */
          printk("%s: %s at %#4lx", dev->name, name, iobase);
        }
-       
+
        if (!status) {
          printk(", h/w address ");
          if (lemac!=LeMAC2) DevicePresent(iobase);/* need after EWRK3_INIT */
@@ -470,7 +470,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
            cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
            outb(cr, EWRK3_CR);
 
-           /* 
+           /*
            ** Determine the base address and window length for the EWRK3
            ** RAM from the memory base register.
            */
@@ -490,7 +490,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
                status = -ENXIO;
              }
            }
-         
+
            /*
            ** See the top of this source code for comments about
            ** uncommenting this line.
@@ -506,9 +506,9 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
              } else {
                printk("      is in I/O only mode");
              }
-           
+
              /* private area & initialise */
-             dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private), 
+             dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
                                                                   GFP_KERNEL);
              if (dev->priv == NULL) {
                return -ENOMEM;
@@ -521,40 +521,40 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
              lp->hard_strapped = hard_strapped;
 
              lp->mPage = 64;
-             if (cmr & CMR_DRAM) lp->mPage <<= 1 ;/* 2 DRAMS on module */ 
+             if (cmr & CMR_DRAM) lp->mPage <<= 1 ;/* 2 DRAMS on module */
 
              sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
              request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
 
              lp->irq_mask = ICR_TNEM|ICR_TXDM|ICR_RNEM|ICR_RXDM;
-             
+
              if (!hard_strapped) {
                /*
                ** Enable EWRK3 board interrupts for autoprobing
                */
                icr |= ICR_IE;                     /* Enable interrupts */
                outb(icr, EWRK3_ICR);
-           
+
                /* The DMA channel may be passed in on this parameter. */
                dev->dma = 0;
-       
+
                /* To auto-IRQ we enable the initialization-done and DMA err,
                   interrupts. For now we will always get a DMA error. */
                if (dev->irq < 2) {
 #ifndef MODULE
                  u_char irqnum;
-             
+
                  autoirq_setup(0);
 
-                 /* 
+                 /*
                  ** Trigger a TNE interrupt.
                  */
                  icr |=ICR_TNEM;
                  outb(1,EWRK3_TDQ);          /* Write to the TX done queue */
                  outb(icr, EWRK3_ICR);       /* Unmask the TXD interrupt */
-             
+
                  irqnum = irq[((icr & IRQ_SEL) >> 4)];
-             
+
                  dev->irq = autoirq_report(1);
                  if ((dev->irq) && (irqnum == dev->irq)) {
                    printk(" and uses IRQ%d.\n", dev->irq);
@@ -568,7 +568,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
                    }
                    status = -ENXIO;
                  }
-               
+
                  DISABLE_IRQs;                 /* Mask all interrupts */
 
 #endif /* MODULE */
@@ -591,7 +591,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
       if (ewrk3_debug > 1) {
        printk(version);
       }
-      
+
       /* The EWRK3-specific entries in the device structure. */
       dev->open = &ewrk3_open;
       dev->hard_start_xmit = &ewrk3_queue_pkt;
@@ -601,7 +601,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
       dev->do_ioctl = &ewrk3_ioctl;
 
       dev->mem_start = 0;
-       
+
       /* Fill in the generic field of the device structure. */
       ether_setup(dev);
     }
@@ -634,8 +634,8 @@ ewrk3_open(struct device *dev)
       status = -EAGAIN;
     } else {
 
-      /* 
-      ** Re-initialize the EWRK3... 
+      /*
+      ** Re-initialize the EWRK3...
       */
       ewrk3_init(dev);
 
@@ -660,7 +660,7 @@ ewrk3_open(struct device *dev)
        printk("  fmqc: 0x%02x\n", inb(EWRK3_FMQC));
       }
 
-      dev->tbusy = 0;                         
+      dev->tbusy = 0;
       dev->start = 1;
       dev->interrupt = UNMASK_INTERRUPTS;
 
@@ -692,9 +692,9 @@ ewrk3_init(struct device *dev)
   struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
   u_char csr, page;
   u_long iobase = dev->base_addr;
-  
-  /* 
-  ** Enable any multicasts 
+
+  /*
+  ** Enable any multicasts
   */
   set_multicast_list(dev);
 
@@ -718,7 +718,7 @@ ewrk3_init(struct device *dev)
   START_EWRK3;                              /* Enable the TX and/or RX */
 }
 
-/* 
+/*
 ** Writes a socket buffer to the free page queue
 */
 static int
@@ -737,7 +737,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
     } else if (!lp->hard_strapped) {
       printk("%s: transmit timed/locked out, status %04x, resetting.\n",
                                                   dev->name, inb(EWRK3_CSR));
-       
+
       /*
       ** Mask all board interrupts
       */
@@ -762,16 +762,16 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
     dev_tint(dev);
   } else if (skb->len > 0) {
 
-    /* 
+    /*
     ** Block a timer-based transmit from overlapping.  This could better be
-    ** done with atomic_swap(1, dev->tbusy), but set_bit() works as well. 
+    ** done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
     */
     if (set_bit(0, (void*)&dev->tbusy) != 0)
       printk("%s: Transmitter access conflict.\n", dev->name);
 
     DISABLE_IRQs;                      /* So that the page # remains correct */
-    
-    /* 
+
+    /*
     ** Get a free page from the FMQ when resources are available
     */
     if (inb(EWRK3_FMQC) > 0) {
@@ -801,7 +801,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
 
        if (!status) {
 
-          /* 
+          /*
          ** Set up the buffer control structures and copy the data from
          ** the socket buffer to the shared memory .
          */
@@ -809,7 +809,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
          if (lp->shmem_length == IO_ONLY) {
            int i;
            u_char *p = skb->data;
-           
+
            outb((char)(TCR_QMODE | TCR_PAD | TCR_IFC), EWRK3_DATA);
            outb((char)(skb->len & 0xff), EWRK3_DATA);
            outb((char)((skb->len >> 8) & 0xff), EWRK3_DATA);
@@ -858,7 +858,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
       printk("ewrk3_queue_pkt(): No free resources...\n");
       printk("ewrk3_queue_pkt(): CSR: %02x ICR: %02x FMQC: %02x\n",inb(EWRK3_CSR),inb(EWRK3_ICR),inb(EWRK3_FMQC));
     }
-    
+
     /* Check for free resources: clear 'tbusy' if there are some */
     if (inb(EWRK3_FMQC) > 0) {
       dev->tbusy = 0;
@@ -871,7 +871,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
 }
 
 /*
-** The EWRK3 interrupt handler. 
+** The EWRK3 interrupt handler.
 */
 static void
 ewrk3_interrupt(int irq, void *dev_id, struct pt_regs * regs)
@@ -895,8 +895,8 @@ ewrk3_interrupt(int irq, void *dev_id, struct pt_regs * regs)
       /* get the interrupt information */
       csr = inb(EWRK3_CSR);
 
-      /* 
-      ** Mask the EWRK3 board interrupts and turn on the LED 
+      /*
+      ** Mask the EWRK3 board interrupts and turn on the LED
       */
       DISABLE_IRQs;
 
@@ -1017,8 +1017,8 @@ ewrk3_rx(struct device *dev)
              memcpy_fromio(p, buf, pkt_len);
            }
 
-           /* 
-           ** Notify the upper protocol layers that there is another 
+           /*
+           ** Notify the upper protocol layers that there is another
            ** packet to handle
            */
            skb->protocol=eth_type_trans(skb,dev);
@@ -1131,7 +1131,7 @@ ewrk3_close(struct device *dev)
           dev->name, inb(EWRK3_CSR));
   }
 
-  /* 
+  /*
   ** We stop the EWRK3 here... mask interrupts and stop TX & RX
   */
   DISABLE_IRQs;
@@ -1150,7 +1150,7 @@ ewrk3_close(struct device *dev)
 
   if (!lp->hard_strapped) {
     free_irq(dev->irq, NULL);
-    
+
     irq2dev_map[dev->irq] = 0;
   }
 
@@ -1165,7 +1165,7 @@ ewrk3_get_stats(struct device *dev)
   struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
 
   /* Null body since there is no framing error counter */
-    
+
   return &lp->stats;
 }
 
@@ -1181,7 +1181,7 @@ set_multicast_list(struct device *dev)
 
   if (irq2dev_map[dev->irq] != NULL) {
     csr = inb(EWRK3_CSR);
-    
+
     if (lp->shmem_length == IO_ONLY) {
       lp->mctbl = (char *) PAGE0_HTE;
     } else {
@@ -1242,11 +1242,11 @@ static void SetMulticastFilter(struct device *dev)
     if (lp->shmem_length == IO_ONLY) {
       for (i=0; i<(HASH_TABLE_LEN >> 4) - 1; i++) {
        outb(0x00, EWRK3_DATA);
-      } 
+      }
       outb(0x80, EWRK3_DATA); i++;           /* insert the broadcast bit */
       for (; i<(HASH_TABLE_LEN >> 3); i++) {
        outb(0x00, EWRK3_DATA);
-      } 
+      }
     } else {
       memset_io(lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
       writeb(0x80, (char *)(lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
@@ -1256,10 +1256,10 @@ static void SetMulticastFilter(struct device *dev)
     for (i=0;i<dev->mc_count;i++) {          /* for each address in the list */
       addrs=dmi->dmi_addr;
       dmi=dmi->next;
-      if ((*addrs & 0x01) == 1) {            /* multicast address? */ 
+      if ((*addrs & 0x01) == 1) {            /* multicast address? */
        crc = 0xffffffff;                    /* init CRC for each address */
        for (byte=0;byte<ETH_ALEN;byte++) {  /* for each address byte */
-                                            /* process each address bit */ 
+                                            /* process each address bit */
          for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
            crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
          }
@@ -1276,7 +1276,7 @@ static void SetMulticastFilter(struct device *dev)
          tmp = inb(EWRK3_DATA);
          tmp |= bit;
          outw((short)((long)lp->mctbl) + byte, EWRK3_PIR1);
-         outb(tmp, EWRK3_DATA); 
+         outb(tmp, EWRK3_DATA);
        } else {
          writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
        }
@@ -1309,7 +1309,7 @@ static void isa_probe(struct device *dev, u_long ioaddr)
   }
 
   for (; (i<maxSlots) && (dev!=NULL);iobase+=EWRK3_IOP_INC, i++) {
-    if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {    
+    if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
       if (DevicePresent(iobase) == 0) {
        if ((dev = alloc_device(dev, iobase)) != NULL) {
          if (ewrk3_hw_init(dev, iobase) == 0) {
@@ -1383,7 +1383,7 @@ alloc_device(struct device *dev, u_long iobase)
 
     num_eth = ewrk3_dev_index(dev->name);
     if (loading_module) return dev;
-    
+
     while (1) {
        if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr==0)) && !adev) {
            adev=dev;
@@ -1406,13 +1406,13 @@ alloc_device(struct device *dev, u_long iobase)
        new_dev = 0;
     }
 
-    if (((dev->next == NULL) &&  
+    if (((dev->next == NULL) &&
        ((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
        new_dev) {
        num_eth++;                         /* New device */
        dev = insert_device(dev, iobase, ewrk3_probe);
     }
-    
+
     return dev;
 }
 
@@ -1525,7 +1525,7 @@ static void EthwrkSignature(char *name, char *eeprom_image)
 /*
 ** Look for a special sequence in the Ethernet station address PROM that
 ** is common across all EWRK3 products.
-** 
+**
 ** Search the Ethernet address ROM for the signature. Since the ROM address
 ** counter can start at an arbitrary point, the search must include the entire
 ** probe sequence length plus the (length_of_the_signature - 1).
@@ -1737,7 +1737,7 @@ static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        memcpy_fromio(tmp.addr, (char *)(lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3));
       }
       ioc->len = (HASH_TABLE_LEN >> 3);
-      copy_to_user(ioc->data, tmp.addr, ioc->len); 
+      copy_to_user(ioc->data, tmp.addr, ioc->len);
     }
     lp->lock = 0;                               /* Unlock the page register */
 
@@ -1776,7 +1776,7 @@ static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd)
     cli();
     ioc->len = sizeof(lp->pktStats);
     if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-      copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+      copy_to_user(ioc->data, &lp->pktStats, ioc->len);
     }
     sti();
 
@@ -1880,10 +1880,13 @@ static struct device thisEthwrk = {
   0, 0, 0, 0,
   0x300, 5,   /* I/O address, IRQ */
   0, 0, 0, NULL, ewrk3_probe };
-       
+
 static int io=0x300;   /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
 static int irq=5;      /* or use the insmod io= irq= options           */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int
 init_module(void)
 {
@@ -1916,4 +1919,3 @@ cleanup_module(void)
  *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
  * End:
  */
-
index d9e69da69b3c824b256b1a15c8c5a9d8e9f5d4a7..eec4b45e256fa9dff5b593eeed64b7fc44279f7c 100644 (file)
@@ -264,7 +264,7 @@ int fmv18x_probe1(struct device *dev, short ioaddr)
        dev->set_multicast_list = &set_multicast_list;
 
        /* Fill in the fields of 'dev' with ethernet-generic values. */
-          
+
        ether_setup(dev);
        return 0;
 }
@@ -374,7 +374,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev)
 
                /* Disable both interrupts. */
                outw(0x0000, ioaddr + TX_INTR);
-               
+
                outw(length, ioaddr + DATAPORT);
                outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
 
@@ -543,7 +543,7 @@ net_rx(struct device *dev)
                }
 
                if (net_debug > 5 && i > 0)
-                       printk("%s: Exint Rx packet with mode %02x after %d ticks.\n", 
+                       printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
                                   dev->name, inb(ioaddr + RX_MODE), i);
        }
 
@@ -600,17 +600,17 @@ static void
 set_multicast_list(struct device *dev)
 {
        short ioaddr = dev->base_addr;
-       if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) 
+       if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
        {
                /*
                 *      We must make the kernel realise we had to move
                 *      into promisc mode or we start all out war on
                 *      the cable. - AC
                 */
-               dev->flags|=IFF_PROMISC;                
-       
+               dev->flags|=IFF_PROMISC;
+
                outb(3, ioaddr + RX_MODE);      /* Enable promiscuous mode */
-       } 
+       }
        else
                outb(2, ioaddr + RX_MODE);      /* Disable promiscuous, use normal mode */
 }
@@ -626,6 +626,9 @@ static struct device dev_fmv18x = {
 static int io = 0x220;
 static int irq = 0;
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
 int init_module(void)
 {
        if (io == 0)
index 7441fd7ed7f35f0b80fa4eb38696c14175d8d15b..635b9764add0f142e9f8d47d4c5dafe3c6043d7a 100644 (file)
@@ -67,7 +67,7 @@ static unsigned int hpplus_portlist[] =
 */
 
 #define HP_ID                  0x00    /* ID register, always 0x4850. */
-#define HP_PAGING              0x02    /* Registers visible @ 8-f, see PageName. */ 
+#define HP_PAGING              0x02    /* Registers visible @ 8-f, see PageName. */
 #define HPP_OPTION             0x04    /* Bitmapped options, see HP_Option.    */
 #define HPP_OUT_ADDR   0x08    /* I/O output location in Perf_Page.    */
 #define HPP_IN_ADDR            0x0A    /* I/O input location in Perf_Page.             */
@@ -84,7 +84,7 @@ enum PageName {
        MAC_Page = 1,                           /* The ethernet address (+checksum). */
        HW_Page = 2,                            /* EEPROM-loaded hardware parameters. */
        LAN_Page = 4,                           /* Transceiver selection, testing, etc. */
-       ID_Page = 6 }; 
+       ID_Page = 6 };
 
 /* The bit definitions for the HPP_OPTION register. */
 enum HP_Option {
@@ -425,6 +425,9 @@ static struct device dev_hpp[MAX_HPP_CARDS] = {
 static int io[MAX_HPP_CARDS] = { 0, };
 static int irq[MAX_HPP_CARDS]  = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HPP_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
index fc965f77efe4440f621fa4e1e4c882251107f12c..531d5f20f63d4b91077b7f25194019e64d1106b0 100644 (file)
@@ -137,7 +137,7 @@ int hp_probe1(struct device *dev, int ioaddr)
 
        if (ei_debug  &&  version_printed++ == 0)
                printk(version);
+
        printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
 
        for(i = 0; i < ETHER_ADDR_LEN; i++)
@@ -237,7 +237,7 @@ hp_reset_8390(struct device *dev)
 
        outb_p(saved_config, hp_base + HP_CONFIGURE);
        SLOW_DOWN_IO; SLOW_DOWN_IO;
-       
+
        if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
                printk("%s: hp_reset_8390() did not complete.\n", dev->name);
 
@@ -259,14 +259,14 @@ hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
        outb_p(ring_page, nic_base + EN0_RSARHI);
        outb_p(E8390_RREAD+E8390_START, nic_base);
 
-       if (ei_status.word16) 
+       if (ei_status.word16)
          insw(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-       else 
+       else
          insb(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
 
        outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
 }
-       
+
 /* Block input and output, similar to the Crynwr packet driver. If you are
    porting to a new ethercard look at the packet driver source for hints.
    The HP LAN doesn't use shared memory -- we put the packet
@@ -392,6 +392,9 @@ static struct device dev_hp[MAX_HP_CARDS] = {
 static int io[MAX_HP_CARDS] = { 0, };
 static int irq[MAX_HP_CARDS]  = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_HP_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
index acd8ee1379a9d69113f3423a81085654c49b71d9..3392d811762e261ac961b4f6594e191c91ed1a46 100644 (file)
  *
  * This driver is based on the 'hpfepkt' crynwr packet driver.
  *
- * This source/code is public free; you can distribute it and/or modify 
+ * This source/code is public free; you can distribute it and/or modify
  * it under terms of the GNU General Public License (published by the
- * Free Software Foundation) either version two of this License, or any 
+ * Free Software Foundation) either version two of this License, or any
  * later version.
  * ----------------------------------------------------------------------------
  *
- * Note: Some routines (interrupt handling, transmit) assumes that  
+ * Note: Some routines (interrupt handling, transmit) assumes that
  *       there is the PERFORMANCE page selected...
  *
  * ----------------------------------------------------------------------------
@@ -48,7 +48,7 @@
  * Russel Nellson <nelson@crynwr.com> for help with obtaining sources
  * of the 'hpfepkt' packet driver.
  *
- * Also thanks to Abacus Electric s.r.o which let me to use their 
+ * Also thanks to Abacus Electric s.r.o which let me to use their
  * motherboard for my second computer.
  *
  * ----------------------------------------------------------------------------
@@ -65,7 +65,7 @@
  *
  * Revision history:
  * =================
- * 
+ *
  *    Version   Date       Description
  *
  *     0.1     14-May-95   Initial writing. ALPHA code was released.
@@ -157,17 +157,17 @@ struct hp100_private {
 /*
  *  variables
  */
+
 static struct hp100_eisa_id hp100_eisa_ids[] = {
 
   /* 10/100 EISA card with REVA Cascade chip */
-  { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA }, 
+  { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA },
 
   /* 10/100 ISA card with REVA Cascade chip */
   { 0x050F1F022, "HP J2573 rev A", HP100_BUS_ISA },
 
   /* 10 only EISA card with Cascade chip */
-  { 0x02019F022, "HP 27248B",      HP100_BUS_EISA }, 
+  { 0x02019F022, "HP 27248B",      HP100_BUS_EISA },
 
   /* 10/100 EISA card with Cascade chip */
   { 0x04019F022, "HP J2577",       HP100_BUS_EISA },
@@ -208,7 +208,7 @@ static int hp100_down_vg_link( struct device *dev );
 /*
  *  probe functions
  */
+
 int hp100_probe( struct device *dev )
 {
   int base_addr = dev ? dev -> base_addr : 0;
@@ -225,7 +225,7 @@ int hp100_probe( struct device *dev )
        else
         return hp100_probe1( dev, base_addr, HP100_BUS_EISA );
     }
-   else 
+   else
 #ifdef CONFIG_PCI
   if ( base_addr > 0 && base_addr < 8 + 1 )
     pci_start_index = 0x100 | ( base_addr - 1 );
@@ -234,12 +234,12 @@ int hp100_probe( struct device *dev )
     if ( base_addr != 0 ) return -ENXIO;
 
   /* at first - scan PCI bus(es) */
-  
+
 #ifdef CONFIG_PCI
   if ( pcibios_present() )
     {
       int pci_index;
-      
+
 #ifdef HP100_DEBUG_PCI
       printk( "hp100: PCI BIOS is present, checking for devices..\n" );
 #endif
@@ -247,17 +247,17 @@ int hp100_probe( struct device *dev )
         {
           u_char pci_bus, pci_device_fn;
           u_short pci_command;
-          
+
           if ( pcibios_find_device( PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A,
                                    pci_index, &pci_bus,
                                    &pci_device_fn ) != 0 ) break;
           pcibios_read_config_dword( pci_bus, pci_device_fn,
                                     PCI_BASE_ADDRESS_0, &ioaddr );
-                                        
+
           ioaddr &= ~3;                /* remove I/O space marker in bit 0. */
-              
+
           if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-              
+
           pcibios_read_config_word( pci_bus, pci_device_fn,
                                    PCI_COMMAND, &pci_command );
           if ( !( pci_command & PCI_COMMAND_MASTER ) )
@@ -277,23 +277,23 @@ int hp100_probe( struct device *dev )
     }
   if ( pci_start_index > 0 ) return -ENODEV;
 #endif /* CONFIG_PCI */
-         
+
   /* at second - probe all EISA possible port regions (if EISA bus present) */
-  
+
   for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )
     {
       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
       if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA ) == 0 ) return 0;
     }
-         
+
   /* at third - probe all ISA possible port regions */
-         
+
   for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )
     {
       if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
       if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA ) == 0 ) return 0;
     }
-                                                                            
+
   return -ENODEV;
 }
 
@@ -319,7 +319,7 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
     if ( inb( ioaddr + 0 ) != HP100_HW_ID_0 ||
          inb( ioaddr + 1 ) != HP100_HW_ID_1 ||
          ( inb( ioaddr + 2 ) & 0xf0 ) != HP100_HW_ID_2_REVA ||
-         inb( ioaddr + 3 ) != HP100_HW_ID_3 ) 
+         inb( ioaddr + 3 ) != HP100_HW_ID_3 )
        return -ENODEV;
 
   dev -> base_addr = ioaddr;
@@ -346,7 +346,7 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
     {
       printk( "hp100_probe: bad EISA ID checksum at base port 0x%x\n", ioaddr );
       return -ENODEV;
-    }  
+    }
 
   for ( i = 0; i < sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ); i++ )
     if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )
@@ -359,7 +359,7 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
   eid = &hp100_eisa_ids[ i ];
   if ( ( eid -> id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )
     {
-      printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n", 
+      printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n",
        eid -> name, ioaddr );
       return -ENODEV;
     }
@@ -368,19 +368,19 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
     uc += hp100_inb( LAN_ADDR + i );
   if ( uc != 0xff )
     {
-      printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n", 
+      printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n",
        eid -> name, ioaddr );
       return -EIO;
     }
 
 #ifndef HP100_IO_MAPPED
   hp100_page( HW_MAP );
-  mem_mapped = ( hp100_inw( OPTION_LSW ) & 
+  mem_mapped = ( hp100_inw( OPTION_LSW ) &
                  ( HP100_MEM_EN | HP100_BM_WRITE | HP100_BM_READ ) ) != 0;
   mem_ptr_phys = mem_ptr_virt = NULL;
   if ( mem_mapped )
     {
-      mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) | 
+      mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) |
                                ( hp100_inw( MEM_MAP_MSW ) << 16 ) );
       (u_int)mem_ptr_phys &= ~0x1fff;  /* 8k alignment */
       if ( bus == HP100_BUS_ISA && ( (u_long)mem_ptr_phys & ~0xfffff ) != 0 )
@@ -416,7 +416,7 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
   lp -> soft_model = hp100_inb( SOFT_MODEL );
   lp -> mac1_mode = HP100_MAC1MODE3;
   lp -> mac2_mode = HP100_MAC2MODE3;
-  
+
   dev -> base_addr = ioaddr;
   hp100_page( HW_MAP );
   dev -> irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQ_MASK;
@@ -441,7 +441,7 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
   ether_setup( dev );
 
   lp -> lan_type = hp100_sense_lan( dev );
-     
+
   printk( "%s: %s at 0x%x, IRQ %d, ",
     dev -> name, lp -> id -> name, ioaddr, dev -> irq );
   switch ( bus ) {
@@ -472,9 +472,9 @@ static int hp100_probe1( struct device *dev, int ioaddr, int bus )
     default:
       printk( "Warning! Link down.\n" );
   }
-               
+
   hp100_stop_interface( dev );
-  
+
   return 0;
 }
 
@@ -496,7 +496,7 @@ static int hp100_open( struct device *dev )
   irq2dev_map[ dev -> irq ] = dev;
 
   MOD_INC_USE_COUNT;
-  
+
   dev -> tbusy = 0;
   dev -> trans_start = jiffies;
   dev -> interrupt = 0;
@@ -505,21 +505,21 @@ static int hp100_open( struct device *dev )
   lp -> lan_type = hp100_sense_lan( dev );
   lp -> mac1_mode = HP100_MAC1MODE3;
   lp -> mac2_mode = HP100_MAC2MODE3;
-  
+
   hp100_page( MAC_CTRL );
   hp100_orw( HP100_LINK_BEAT_DIS | HP100_RESET_LB, LAN_CFG_10 );
 
   hp100_stop_interface( dev );
   hp100_load_eeprom( dev );
 
-  hp100_outw( HP100_MMAP_DIS | HP100_SET_HB | 
+  hp100_outw( HP100_MMAP_DIS | HP100_SET_HB |
               HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
   hp100_outw( HP100_DEBUG_EN | HP100_RX_HDR | HP100_EE_EN | HP100_RESET_HB |
               HP100_FAKE_INT | HP100_RESET_LB, OPTION_LSW );
   hp100_outw( HP100_ADV_NXT_PKT | HP100_TX_CMD | HP100_RESET_LB |
                 HP100_PRIORITY_TX | ( hp100_priority_tx ? HP100_SET_HB : HP100_RESET_HB ),
               OPTION_MSW );
-                                       
+
   hp100_page( MAC_ADDRESS );
   for ( i = 0; i < 6; i++ )
     hp100_outb( dev -> dev_addr[ i ], MAC_ADDR + i );
@@ -567,7 +567,7 @@ static int hp100_close( struct device *dev )
   return 0;
 }
 
-/* 
+/*
  *  transmit
  */
 
@@ -591,7 +591,7 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
         lp -> hub_status = hp100_login_to_vg_hub( dev );
       hp100_start_interface( dev );
     }
-  
+
   if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
     {
 #ifdef HP100_DEBUG
@@ -635,20 +635,20 @@ static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
       dev -> trans_start = jiffies;
       return -EAGAIN;
     }
-    
+
   if ( skb == NULL )
     {
       dev_tint( dev );
       return 0;
     }
-    
+
   if ( skb -> len <= 0 ) return 0;
 
   for ( i = 0; i < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_TX_CMD ); i++ )
     {
 #ifdef HP100_DEBUG_TX
       printk( "hp100_start_xmit: busy\n" );
-#endif    
+#endif
     }
 
   hp100_ints_off();
@@ -717,7 +717,7 @@ static void hp100_rx( struct device *dev )
       hp100_page( PERFORMANCE );
     }
 #endif
-  
+
   packets = hp100_inb( RX_PKT_CNT );
 #ifdef HP100_DEBUG
   if ( packets > 1 )
@@ -729,7 +729,7 @@ static void hp100_rx( struct device *dev )
         {
 #ifdef HP100_DEBUG_TX
           printk( "hp100_rx: busy, remaining packets = %d\n", packets );
-#endif    
+#endif
         }
       if ( lp -> mem_mapped )
         {
@@ -761,7 +761,7 @@ static void hp100_rx( struct device *dev )
        else
         {
           u_char *ptr;
-        
+
           skb -> dev = dev;
           ptr = (u_char *)skb_put( skb, pkt_len );
           if ( lp -> mem_mapped )
@@ -797,7 +797,7 @@ static void hp100_rx( struct device *dev )
 /*
  *  statistics
  */
+
 static struct enet_statistics *hp100_get_stats( struct device *dev )
 {
   int ioaddr = dev -> base_addr;
@@ -813,7 +813,7 @@ static void hp100_update_stats( struct device *dev )
   int ioaddr = dev -> base_addr;
   u_short val;
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-         
+
   hp100_page( MAC_CTRL );              /* get all statistics bytes */
   val = hp100_inw( DROPPED ) & 0x0fff;
   lp -> stats.rx_errors += val;
@@ -845,7 +845,7 @@ static void hp100_clear_stats( int ioaddr )
 /*
  *  Set or clear the multicast filter for this adapter.
  */
-                                                          
+
 static void hp100_set_multicast_list( struct device *dev)
 {
   int ioaddr = dev -> base_addr;
@@ -956,14 +956,14 @@ static void hp100_start_interface( struct device *dev )
       hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
     }
   sti();
-} 
+}
 
 static void hp100_stop_interface( struct device *dev )
 {
   int ioaddr = dev -> base_addr;
   u_short val;
 
-  hp100_outw( HP100_INT_EN | HP100_RESET_LB | 
+  hp100_outw( HP100_INT_EN | HP100_RESET_LB |
               HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
   val = hp100_inw( OPTION_LSW );
   hp100_page( HW_MAP );
@@ -1030,10 +1030,10 @@ static int hp100_down_vg_link( struct device *dev )
   if ( i <= 0 )                                /* not signal - not logout */
     return 0;
   hp100_andw( ~HP100_LINK_CMD, LAN_CFG_VG );
-  time = jiffies + 10*HZ/100; 
+  time = jiffies + 10*HZ/100;
   while ( time > jiffies )
-    if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST | 
-                                        HP100_LINK_CABLE_ST | 
+    if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST |
+                                        HP100_LINK_CABLE_ST |
                                         HP100_LINK_GOOD_ST ) ) )
       return 0;
 #ifdef HP100_DEBUG
@@ -1047,7 +1047,7 @@ static int hp100_login_to_vg_hub( struct device *dev )
   int i;
   int ioaddr = dev -> base_addr;
   u_short val;
-  unsigned long time;  
+  unsigned long time;
 
   hp100_page( MAC_CTRL );
   hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
@@ -1062,7 +1062,7 @@ static int hp100_login_to_vg_hub( struct device *dev )
 #endif
       return -EIO;
     }
-    
+
   if ( hp100_down_vg_link( dev ) < 0 ) /* if fail, try reset VG link */
     {
       hp100_andw( ~HP100_VG_RESET, LAN_CFG_VG );
@@ -1081,9 +1081,9 @@ static int hp100_login_to_vg_hub( struct device *dev )
     }
 
   time = jiffies + ( HZ / 2 );
-  do {   
+  do {
     val = hp100_inw( LAN_CFG_VG );
-    if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) == 
+    if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) ==
                  ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) )
       return 0;        /* success */
   } while ( time > jiffies );
@@ -1103,10 +1103,11 @@ down_link:
 /*
  *  module section
  */
+
 #ifdef MODULE
 
 static int hp100_port = -1;
+MODULE_PARM(hp100_port, "i");
 
 static char devicename[9] = { 0, };
 static struct device dev_hp100 = {
@@ -1125,7 +1126,7 @@ int init_module( void )
   if ( register_netdev( &dev_hp100 ) != 0 )
     return -EIO;
   return 0;
-}         
+}
 
 void cleanup_module( void )
 {
index e93d3060639ca518d898afffe689552c76d1989d..fd6c78b5581dacd3b4680511944f175a18df7d28 100644 (file)
@@ -13,7 +13,7 @@
 
 /*
    Changes by Peter De Schrijver (Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
-       
+
        + changed name to ibmtr.c in anticipation of other tr boards.
        + changed reset code and adapter open code.
        + added SAP open code.
         - removed redundant information display
         - some code reworking
 
-   Changes by Michel Lespinasse (walken@via.ecp.fr), 
+   Changes by Michel Lespinasse (walken@via.ecp.fr),
      Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr)
      (February 18, 1996) :
-       - modified shared memory and mmio access port the driver to 
+       - modified shared memory and mmio access port the driver to
           alpha platform (structure access -> readb/writeb)
 
    Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
@@ -56,7 +56,7 @@
          complete. (August 15 1996)
         - completed multiple adapter support. (November 20 1996)
 */
-       
+
 #ifdef PCMCIA
 #define MODULE
 #endif
 #define USE_MEMCPY 1
 
 /* version and credits */
-static char *version = 
+static char *version =
 "ibmtr.c: v1.3.57  8/ 7/94 Peter De Schrijver and Mark Swanson\n"
 "         v2.1.10 11/20/96 Paul Norton <pnorton@cts.com>\n";
+
 static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
                           0x04, 0x03, 0x04, 0x0f,
                           0x03, 0x06, 0x03, 0x01,
@@ -184,13 +184,13 @@ int DummyCallCount=0;
 /*  This routine combined with the #DEFINE DPRINTD serves
     to workaround the gcc apparent bug.   in tr_tx() */
 
-static void DummyCall(const char * fmt,...) 
+static void DummyCall(const char * fmt,...)
 { DummyCallCount++; return; }
 #endif
 
 static void PrtChanID(char *pcid, short stride) {
        short i, j;
-       for (i=0, j=0; i<24; i++, j+=stride) 
+       for (i=0, j=0; i<24; i++, j+=stride)
                printk("%1x", ((int) pcid[j]) & 0x0f);
        printk("\n");
 }
@@ -255,19 +255,19 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
        __u32 cd_chanid;
        unsigned char *tchanid, ctemp;
 
-#ifndef MODULE                 
+#ifndef MODULE
        dev = init_trdev(dev,0);
 #endif
 
        /* Query the adapter PIO base port which will return
-       indication of where MMIO was placed. We also have a 
+       indication of where MMIO was placed. We also have a
        coded interrupt number. */
-               
+
                segment = inb(PIOaddr);
        /* out of range values so we'll assume non-existent IO device */
        if (segment < 0x40 || segment > 0xe0)
-                return -ENODEV; 
-               
+                return -ENODEV;
+
        /* Compute the linear base address of the MMIO area
           as LINUX doesn't care about segments          */
        t_mmio=(((__u32)(segment & 0xfc) << 11) + 0x80000);
@@ -275,22 +275,22 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
        if (ibmtr_debug_trace & TRC_INIT)
                DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %08X intr: %d\n",
                          PIOaddr, (int)segment, t_mmio, (int)intr);
-               
+
        /* Now we will compare expected 'channelid' strings with
           what we is there to learn of ISA/MCA or not TR card */
        cd_chanid = (CHANNEL_ID + t_mmio);  /* for efficiency */
-       tchanid=pcchannelid; 
+       tchanid=pcchannelid;
        cardpresent=TR_ISA;  /* try ISA */
 
        /* suboptimize knowing first byte different */
        ctemp = readb(cd_chanid) & 0x0f;
        if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
-               tchanid=mcchannelid; 
+               tchanid=mcchannelid;
                cardpresent=TR_MCA;
                if (ctemp != *tchanid)  /* Neither ISA nor MCA */
                        cardpresent=NOTOK;
        }
-               
+
        if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
                for (i=2,j=1; i<=46; i=i+2,j++) {
                        if ((readb(cd_chanid+i) & 0x0f) != tchanid[j]) {
@@ -299,12 +299,12 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
                        }
                }
        }
-               
+
        /* If we have an ISA board check for the ISA P&P version,
           as it has different IRQ settings */
        if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio)==0x0e))
                cardpresent=TR_ISAPNP;
-               
+
        if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
                if (ibmtr_debug_trace & TRC_INIT) {
                        DPRINTK("Channel ID string not found for PIOaddr: %4hx\n", PIOaddr);
@@ -314,11 +314,11 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
                }
                 return -ENODEV;
        }
-               
+
        /* Now, allocate some of the pl0 buffers for this driver.. */
        ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
        if (ti == NULL) return -ENOMEM;
-               
+
        memset(ti, 0, sizeof(struct tok_info));
 
        ti->mmio= t_mmio;
@@ -362,7 +362,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
                ti->global_int_enable=PIOaddr+ADAPTINTREL;
                ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
                break;
-      
+
        }
 
        if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
@@ -375,7 +375,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
        }
 
        /* Get hw address of token ring card */
-#if !TR_NEWFORMAT 
+#if !TR_NEWFORMAT
        DPRINTK("hw address: ");
 #endif
        j=0;
@@ -420,7 +420,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
 #if !TR_NEWFORMAT
        DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, "
                "dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
-               ti->data_rate, ti->token_release, ti->avail_shared_ram/2, 
+               ti->data_rate, ti->token_release, ti->avail_shared_ram/2,
                ti->shared_ram_paging, ti->dhb_size4mb, ti->dhb_size16mb);
 #endif
 
@@ -430,7 +430,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
           maximum space will will use for two adapters is 64K so if the
           adapter we are working on demands 64K (it also doesn't support
           paging), then only one adapter can be supported.  */
-       
+
        /* determine how much of total RAM is mapped into PC space */
        ti->mapped_ram_size=1<<((((readb(ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)) >>2) & 0x03) + 4);
        ti->page_mask=0;
@@ -479,7 +479,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
                                pg_size, ti->mapped_ram_size);
                                ti->page_mask = 0;    /* reset paging */
                } else {
-                       ti->mapped_ram_size=ti->avail_shared_ram; 
+                       ti->mapped_ram_size=ti->avail_shared_ram;
                        DPRINTK("Shared RAM paging enabled. Page size : %uK\n",
                                ((ti->page_mask^ 0xff)+1)>>2);
                }
@@ -543,7 +543,7 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
 
        trdev_init(dev);
        tok_init_card(dev);
-       
+
        return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 }
 
@@ -551,10 +551,10 @@ static int ibmtr_probe1(struct device *dev, int PIOaddr)
 
 unsigned char get_sram_size(struct tok_info *adapt_info)
 {
-               
+
        unsigned char avail_sram_code;
        static unsigned char size_code[]={ 0,16,32,64,127,128 };
-       
+
        /* Adapter gives
           'F' -- use RRR bits 3,2
           'E' -- 8kb   'D' -- 16kb
@@ -563,7 +563,7 @@ unsigned char get_sram_size(struct tok_info *adapt_info)
           (WARNING ... must zero top bytes in INIT */
 
        avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
-       if (avail_sram_code) 
+       if (avail_sram_code)
                return size_code[avail_sram_code];
        else  /* for code 'F', must compute size from RRR(3,2) bits */
                return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
@@ -585,7 +585,7 @@ int trdev_init(struct device *dev)
 
 #ifndef MODULE
   tr_setup(dev);
-#endif 
+#endif
 
 
   return 0;
@@ -593,48 +593,48 @@ int trdev_init(struct device *dev)
 
 
 
-static int tok_open(struct device *dev) 
+static int tok_open(struct device *dev)
 {
        struct tok_info *ti=(struct tok_info *)dev->priv;
-       
+
        if (ti->open_status==CLOSED) tok_init_card(dev);
-       
+
        if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
-       
+
        if (ti->open_status==SUCCESS) {
                dev->tbusy=0;
                dev->interrupt=0;
                dev->start=1;
                /* NEED to see smem size *AND* reset high 512 bytes if needed */
-               
+
                MOD_INC_USE_COUNT;
-               
+
                return 0;
        } else return -EAGAIN;
-       
+
 }
 
-static int tok_close(struct device *dev) 
+static int tok_close(struct device *dev)
 {
-       
+
        struct tok_info *ti=(struct tok_info *) dev->priv;
-       
-       writeb(DIR_CLOSE_ADAPTER, 
+
+       writeb(DIR_CLOSE_ADAPTER,
               ti->srb + offsetof(struct srb_close_adapter, command));
        writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-       
+
        ti->open_status=CLOSED;
-       
-       sleep_on(&ti->wait_for_tok_int);                
-       
+
+       sleep_on(&ti->wait_for_tok_int);
+
        if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
                DPRINTK("close adapter failed: %02X\n",
                        (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
-               
+
         dev->start = 0;
        DPRINTK("Adapter closed.\n");
        MOD_DEC_USE_COUNT;
-       
+
        return 0;
 }
 
@@ -643,13 +643,13 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
        unsigned char status;
        struct tok_info *ti;
        struct device *dev;
-       
+
 #if TR_VERBOSE
        DPRINTK("Int from tok_driver, dev : %p\n",dev);
 #endif
        dev = (struct device *)(irq2dev_map[irq]);
        ti  = (struct tok_info *) dev->priv;
-       
+
        /* Disable interrupts till processing is finished */
        dev->interrupt=1;
        writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
@@ -659,16 +659,16 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                 outb(0,ti->adapter_int_enable);
        else
                outb(0,ti->global_int_enable);
-               
+
 
        switch (ti->do_tok_int) {
-               
+
              case NOT_FIRST:
-               
+
                /*  Begin the regular interrupt handler HERE inline to avoid
                    the extra levels of logic and call depth for the
                    original solution.   */
-               
+
                status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
                #ifdef PCMCIA
                /* Check if the PCMCIA card was pulled. */
@@ -688,48 +688,48 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                 }
                #endif
 
-               
+
                if (status & ADAP_CHK_INT) {
-                       
+
                        int i;
                        __u32 check_reason;
 
                        check_reason=ti->mmio + ntohs(readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN));
-                       
+
                        DPRINTK("Adapter check interrupt\n");
                        DPRINTK("8 reason bytes follow: ");
                        for(i=0; i<8; i++, check_reason++)
-                               printk("%02X ", (int)readb(check_reason));      
+                               printk("%02X ", (int)readb(check_reason));
                        printk("\n");
-                       
+
                        writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
                        writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
                        dev->interrupt=0;
-                       
+
                }       else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
                                 & (TCR_INT | ERR_INT | ACCESS_INT)) {
-                       
-                       DPRINTK("adapter error: ISRP_EVEN : %02x\n", 
+
+                       DPRINTK("adapter error: ISRP_EVEN : %02x\n",
                                (int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
                        writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
                               ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
                        writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
                        dev->interrupt=0;
 
-               } else if (status 
+               } else if (status
                           & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
                        /* SRB, ASB, ARB or SSB response */
-                       
+
                        if (status & SRB_RESP_INT) { /* SRB response */
-                               
+
                                switch(readb(ti->srb)) { /* SRB command check */
-                                       
+
                                      case XMIT_DIR_FRAME: {
                                              unsigned char xmit_ret_code;
-                                             
+
                                              xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
                                              if (xmit_ret_code != 0xff) {
-                                                     DPRINTK("error on xmit_dir_frame request: %02X\n", 
+                                                     DPRINTK("error on xmit_dir_frame request: %02X\n",
                                                              xmit_ret_code);
                                                      if (ti->current_skb) {
                                                              dev_kfree_skb(ti->current_skb, FREE_WRITE);
@@ -740,10 +740,10 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                              }
                                      }
                                      break;
-                                     
+
                                      case XMIT_UI_FRAME: {
                                              unsigned char xmit_ret_code;
-                                             
+
                                              xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
                                              if (xmit_ret_code != 0xff) {
                                                      DPRINTK("error on xmit_ui_frame request: %02X\n",
@@ -757,22 +757,22 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                              }
                                      }
                                      break;
-                                     
+
                                      case DIR_OPEN_ADAPTER: {
                                              unsigned char open_ret_code;
                                              __u16 open_error_code;
-                                             
+
                                              ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
                                              ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
                                              ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
                                              ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
                                              ti->current_skb=NULL;
-                                             
+
                                              open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
                                              open_error_code = ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));
 
                                              if (open_ret_code==7) {
-                                                     
+
                                                      if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
                                                              DPRINTK("open failed: Adapter speed must match ring "
                                                                      "speed if Automatic Ring Speed Save is disabled\n");
@@ -782,41 +782,41 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                                              DPRINTK("retrying open to adjust to ring speed\n");
                                                      else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
                                                              DPRINTK("No signal detected for Auto Speed Detection\n");
-                                                     else DPRINTK("Unrecoverable error: error code = %04x\n", 
+                                                     else DPRINTK("Unrecoverable error: error code = %04x\n",
                                                                   open_error_code);
-                                                     
+
                                              } else if (!open_ret_code) {
 #if !TR_NEWFORMAT
                                                      DPRINTK("board opened...\n");
 #else
                                                      DPRINTK("Adapter initialized and opened.\n");
 #endif
-                                                     writeb(~(SRB_RESP_INT), 
+                                                     writeb(~(SRB_RESP_INT),
                                                             ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-                                                     writeb(~(CMD_IN_SRB), 
+                                                     writeb(~(CMD_IN_SRB),
                                                             ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
                                                      open_sap(EXTENDED_SAP,dev);
-                                                     
+
                                                      /* YdW probably hates me */
                                                      goto skip_reset;
                                              } else
                                                      DPRINTK("open failed: ret_code = %02X, retrying\n",
                                                              open_ret_code);
-                                             
+
                                              if (ti->open_status != FAILURE) {
                                                      tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
                                                      tr_timer.data=(unsigned long)dev;
                                                      tr_timer.next=tr_timer.prev=NULL;
                                                      add_timer(&tr_timer);
                                              }
-                                             
+
                                      }
                                      break;
-                                     
+
                                      case DIR_CLOSE_ADAPTER:
                                        wake_up(&ti->wait_for_tok_int);
                                        break;
-                                       
+
                                      case DLC_OPEN_SAP:
                                        if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
                                                DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
@@ -832,9 +832,9 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                                wake_up(&ti->wait_for_reset);
                                        }
                                        break;
-                                       
+
                                      case DIR_INTERRUPT:
-                                     case DIR_MOD_OPEN_PARAMS: 
+                                     case DIR_MOD_OPEN_PARAMS:
                                      case DIR_SET_GRP_ADDR:
                                      case DIR_SET_FUNC_ADDR:
                                      case DLC_CLOSE_SAP:
@@ -843,7 +843,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                                        (int)readb(ti->srb+offsetof(struct srb_interrupt, command)),
                                                        (int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
                                        break;
-                                       
+
                                      case DIR_READ_LOG:
                                        if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
                                                DPRINTK("error on dir_read_log: %02X\n",
@@ -854,96 +854,96 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                                        "A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
                                                        "Receive congestion count %02X, Frame copied errors %02X\n"
                                                        "Frequency errors %02X, Token errors %02X\n",
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    line_errors)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    internal_errors)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    burst_errors)),
                                                        (int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    abort_delimiters)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    lost_frames)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                                    recv_congest_count)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    frame_copied_errors)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                    frequency_errors)),
-                                                       (int)readb(ti->srb+offsetof(struct srb_read_log, 
+                                                       (int)readb(ti->srb+offsetof(struct srb_read_log,
                                                                                                    token_errors)));
                                        dev->tbusy=0;
                                        break;
-                                       
+
                                      default:
                                        DPRINTK("Unknown command %02X encountered\n",
                                                (int)readb(ti->srb));
-                                       
+
                                } /* SRB command check */
-                               
+
                                writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
                                writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-                               
+
                          skip_reset:
                        } /* SRB response */
-                       
+
                        if (status & ASB_FREE_INT) { /* ASB response */
-                               
+
                                switch(readb(ti->asb)) { /* ASB command check */
-                                       
+
                                      case REC_DATA:
                                      case XMIT_UI_FRAME:
                                      case XMIT_DIR_FRAME:
                                        break;
-                                       
+
                                      default:
                                        DPRINTK("unknown command in asb %02X\n",
                                                (int)readb(ti->asb));
-                                       
+
                                } /* ASB command check */
-                               
+
                                if (readb(ti->asb+2)!=0xff) /* checks ret_code */
-                                   DPRINTK("ASB error %02X in cmd %02X\n", 
+                                   DPRINTK("ASB error %02X in cmd %02X\n",
                                            (int)readb(ti->asb+2),(int)readb(ti->asb));
                                writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
-                               
+
                        } /* ASB response */
-                       
+
                        if (status & ARB_CMD_INT) { /* ARB response */
-                               
+
                                switch (readb(ti->arb)) { /* ARB command check */
-                                       
+
                                      case DLC_STATUS:
-                                       DPRINTK("DLC_STATUS new status: %02X on station %02X\n", 
+                                       DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
                                                ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
-                                               ntohs(readw(ti->arb 
+                                               ntohs(readw(ti->arb
                                                                            +offsetof(struct arb_dlc_status, station_id))));
                                        break;
-                                       
+
                                      case REC_DATA:
                                        tr_rx(dev);
                                        break;
-                                       
+
                                      case RING_STAT_CHANGE: {
                                              unsigned short ring_status;
-                                             
+
                                              ring_status=ntohs(readw(ti->arb
                                                                      +offsetof(struct arb_ring_stat_change, ring_status)));
-                                             
+
                                              if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
-                                                     
+
                                                      DPRINTK("Signal loss/Lobe fault\n");
-                                                     DPRINTK("We try to reopen the adapter.\n");       
+                                                     DPRINTK("We try to reopen the adapter.\n");
                                                      tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
                                                      tr_timer.data=(unsigned long)dev;
                                                      tr_timer.next=tr_timer.prev=NULL;
                                                      add_timer(&tr_timer);
-                                                     
-                                             } else if (ring_status & (HARD_ERROR | XMIT_BEACON 
+
+                                             } else if (ring_status & (HARD_ERROR | XMIT_BEACON
                                                                                        | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
                                                      DPRINTK("New ring status: %02X\n", ring_status);
-                                             
+
                                              if (ring_status & LOG_OVERFLOW) {
                                                      if (dev->tbusy)
                                                               ti->readlog_pending = 1;
@@ -952,50 +952,50 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
                                              }
                                      }
                                      break;
-                                     
+
                                      case XMIT_DATA_REQ:
                                        tr_tx(dev);
                                        break;
-                                       
+
                                      default:
-                                       DPRINTK("Unknown command %02X in arb\n", 
+                                       DPRINTK("Unknown command %02X in arb\n",
                                                (int)readb(ti->arb));
                                        break;
-                                       
+
                                } /* ARB command check */
-                               
+
                                writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
                                writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-                               
+
                        } /* ARB response */
-                       
+
                        if (status & SSB_RESP_INT) { /* SSB response */
-                                               
+
                                switch (readb(ti->ssb)) { /* SSB command check */
-                                       
+
                                      case XMIT_DIR_FRAME:
                                      case XMIT_UI_FRAME:
                                        if (readb(ti->ssb+2)) /* checks ret_code */
-                                               DPRINTK("xmit ret_code: %02X xmit error code: %02X\n", 
-                                                       (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));          
+                                               DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",
+                                                       (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));
                                        else ti->tr_stats.tx_packets++;
                                        break;
-                                       
+
                                      case XMIT_XID_CMD:
                                        DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));
-                                       
+
                                      default:
                                        DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));
-                                       
+
                                } /* SSB command check */
-                               
+
                                writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
                                writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-                               
+
                        } /* SSB response */
-                       
+
                }        /* SRB, ARB, ASB or SSB response */
-               
+
                dev->interrupt=0;
                writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
                break;
@@ -1003,24 +1003,24 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
              case FIRST_INT:
                initial_tok_int(dev);
                break;
-               
+
              default:
                DPRINTK("Unexpected interrupt from tr adapter\n");
 
        }
 }
 
-static void initial_tok_int(struct device *dev) 
+static void initial_tok_int(struct device *dev)
 {
 
        __u32 encoded_addr;
        __u32 hw_encoded_addr;
        struct tok_info *ti;
-       
+
        ti=(struct tok_info *) dev->priv;
-       
+
        ti->do_tok_int=NOT_FIRST;
-       
+
 #ifndef TR_NEWFORMAT
        DPRINTK("Initial tok int received\n");
 #endif
@@ -1036,7 +1036,7 @@ static void initial_tok_int(struct device *dev)
 
        dev->mem_start = ti->sram;
        dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1;
-       
+
 #if TR_VERBOSE
        {
                int i;
@@ -1045,28 +1045,28 @@ static void initial_tok_int(struct device *dev)
                printk("\n");
        }
 #endif
-       
-       hw_encoded_addr = readw(ti->init_srb 
+
+       hw_encoded_addr = readw(ti->init_srb
                                + offsetof(struct srb_init_response, encoded_address));
-       
-#if !TR_NEWFORMAT              
+
+#if !TR_NEWFORMAT
        DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
        DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
                ntohs(hw_encoded_addr));
 #endif
-       
+
        encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
-       
+
 #if !TR_NEWFORMAT
-       DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, 
+       DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr,
                ntohs(hw_encoded_addr), encoded_addr);
 #else
        DPRINTK("Initial interrupt : shared RAM located at %08x.\n", ti->sram);
-#endif 
-       
+#endif
+
        ti->auto_ringspeedsave=readb(ti->init_srb
                                     +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
-       
+
 #if !TR_NEWFORMAT
        for(i=0;i<TR_ALEN;i++) {
                dev->dev_addr[i]=readb(encoded_addr + i);
@@ -1074,114 +1074,114 @@ static void initial_tok_int(struct device *dev)
        }
        printk("\n");
 #endif
-       
+
        tok_open_adapter((unsigned long)dev);
 }
 
-static int tok_init_card(struct device *dev) 
+static int tok_init_card(struct device *dev)
 {
        struct tok_info *ti;
        short PIOaddr;
        int i;
        PIOaddr = dev->base_addr;
        ti=(struct tok_info *) dev->priv;
-       
+
        /* Special processing for first interrupt after reset */
        ti->do_tok_int=FIRST_INT;
-       
+
        /* Reset adapter */
        dev->tbusy=1; /* nothing can be done before reset and open completed */
-       
+
 #ifdef ENABLE_PAGING
        if(ti->page_mask)
                writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
 #endif
-       
+
        writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
-       
+
 #if !TR_NEWFORMAT
        DPRINTK("resetting card\n");
 #endif
-       
+
        outb(0, PIOaddr+ADAPTRESET);
        for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
        outb(0,PIOaddr+ADAPTRESETREL);
-       
+
 #if !TR_NEWFORMAT
        DPRINTK("card reset\n");
 #endif
-       
+
        ti->open_status=IN_PROGRESS;
        writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-       return 0;       
+       return 0;
 }
 
-static void open_sap(unsigned char type,struct device *dev) 
+static void open_sap(unsigned char type,struct device *dev)
 {
        int i;
        struct tok_info *ti=(struct tok_info *) dev->priv;
-       
+
        SET_PAGE(ti->srb);
        for (i=0; i<sizeof(struct dlc_open_sap); i++)
                writeb(0, ti->srb+i);
-       
+
        writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
-       writew(htons(MAX_I_FIELD), 
+       writew(htons(MAX_I_FIELD),
               ti->srb + offsetof(struct dlc_open_sap, max_i_field));
-       writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, 
+       writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY,
               ti->srb + offsetof(struct dlc_open_sap, sap_options));
-       writeb(SAP_OPEN_STATION_CNT, 
+       writeb(SAP_OPEN_STATION_CNT,
               ti->srb + offsetof(struct dlc_open_sap, station_count));
        writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
-       
+
        writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 
 }
 
-void tok_open_adapter(unsigned long dev_addr) 
+void tok_open_adapter(unsigned long dev_addr)
 {
-       
+
        struct device *dev=(struct device *)dev_addr;
        struct tok_info *ti;
        int i;
-       
+
        ti=(struct tok_info *) dev->priv;
-       
+
 #if !TR_NEWFORMAT
        DPRINTK("now opening the board...\n");
 #endif
-       
+
        writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
        writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
-       
+
        for (i=0; i<sizeof(struct dir_open_adapter); i++)
                writeb(0, ti->init_srb+i);
-       
-       writeb(DIR_OPEN_ADAPTER, 
+
+       writeb(DIR_OPEN_ADAPTER,
               ti->init_srb + offsetof(struct dir_open_adapter, command));
-       writew(htons(OPEN_PASS_BCON_MAC), 
+       writew(htons(OPEN_PASS_BCON_MAC),
               ti->init_srb + offsetof(struct dir_open_adapter, open_options));
-       writew(htons(NUM_RCV_BUF), 
+       writew(htons(NUM_RCV_BUF),
               ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
-       writew(htons(RCV_BUF_LEN), 
+       writew(htons(RCV_BUF_LEN),
               ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
-       writew(htons(DHB_LENGTH), 
+       writew(htons(DHB_LENGTH),
               ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
-       writeb(NUM_DHB, 
+       writeb(NUM_DHB,
               ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
-       writeb(DLC_MAX_SAP, 
+       writeb(DLC_MAX_SAP,
               ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
-       writeb(DLC_MAX_STA, 
+       writeb(DLC_MAX_STA,
               ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
-       
+
        ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
-       
+
        writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
        writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-       
+
 }
 
-static void tr_tx(struct device *dev) 
+static void tr_tx(struct device *dev)
 {
        struct tok_info *ti=(struct tok_info *) dev->priv;
        struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
@@ -1190,21 +1190,21 @@ static void tr_tx(struct device *dev)
        unsigned char xmit_command;
        int i;
        struct trllc    *llc;
-       
+
        if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
                DPRINTK("ASB not free !!!\n");
-       
+
        /* in providing the transmit interrupts,
           is telling us it is ready for data and
           providing a shared memory address for us
           to stuff with data.  Here we compute the
           effective address where we will place data.*/
-       dhb=ti->sram 
+       dhb=ti->sram
                +ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
        llc = (struct trllc *) &(ti->current_skb->data[sizeof(struct trh_hdr)]);
-       
+
        xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
-       
+
        writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
        writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)),
               ti->asb + offsetof(struct asb_xmit_resp, station_id));
@@ -1212,23 +1212,23 @@ static void tr_tx(struct device *dev)
        writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)),
               ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
        writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
-       
+
        if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
-               
-               writew(htons(0x11), 
+
+               writew(htons(0x11),
                       ti->asb + offsetof(struct asb_xmit_resp, frame_length));
                writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
                writeb(AC, dhb);
                writeb(LLC_FRAME, dhb+1);
-               
+
                for (i=0; i<TR_ALEN; i++) writeb((int)0x0FF, dhb+i+2);
                for (i=0; i<TR_ALEN; i++) writeb(0, dhb+i+TR_ALEN+2);
-               
+
                writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
                return;
-               
+
        }
-       
+
        /* the token ring packet is copied from sk_buff to the adapter
           buffer identified in the command data received with the
           interrupt.  The sk_buff area was set up with a maximum
@@ -1236,20 +1236,20 @@ static void tr_tx(struct device *dev)
           out the extra (all) rif fields.   */
        /* nb/dwm .... I re-arranged code here to avoid copy of extra
           bytes, ended up with fewer statements as well. */
-       
+
        /* TR arch. identifies if RIF present by high bit of source
           address.  So here we check if RIF present */
 
        if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
                hdr_len=sizeof(struct trh_hdr)-18;
-               
+
 #if TR_VERBOSE
                DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
                        ti->current_skb->len-18);
 #endif
        } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
                  +sizeof(struct trh_hdr)-18;
-       
+
        /* header length including rif is computed above, now move the data
           and set fields appropriately. */
 #if USE_MEMCPY
@@ -1258,22 +1258,22 @@ static void tr_tx(struct device *dev)
        for (i=0; i<hdr_len; i++)
                writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
 #endif
-       
+
        writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
        writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
               ti->asb + offsetof(struct asb_xmit_resp, frame_length));
-       
+
        /*  now copy the actual packet data next to hdr */
 #if USE_MEMCPY
        memcpy_toio(dhb + hdr_len,
-                   ti->current_skb->data + sizeof(struct trh_hdr), 
+                   ti->current_skb->data + sizeof(struct trh_hdr),
                    ti->current_skb->len - sizeof(struct trh_hdr));
 #else
        for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
                writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
                       dhb+i);
 #endif
-       
+
        writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
        dev->tbusy=0;
        dev_kfree_skb(ti->current_skb,FREE_WRITE);
@@ -1282,11 +1282,11 @@ static void tr_tx(struct device *dev)
        if (ti->readlog_pending) tr_readlog(dev);
 }
 
-static void tr_rx(struct device *dev) 
+static void tr_rx(struct device *dev)
 {
        int i;
        struct tok_info *ti=(struct tok_info *) dev->priv;
-       __u32 rbuffer;  
+       __u32 rbuffer;
        __u32 llc;
        unsigned char *data;
        unsigned int rbuffer_len, lan_hdr_len;
@@ -1294,29 +1294,29 @@ static void tr_rx(struct device *dev)
        struct sk_buff *skb;
        unsigned int skb_size = 0;
        int     is8022 = 0;
-       
+
        rbuffer=(ti->sram
                 +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
-       
+
        if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
                DPRINTK("ASB not free !!!\n");
-       
-       writeb(REC_DATA, 
+
+       writeb(REC_DATA,
               ti->asb + offsetof(struct asb_rec, command));
        writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)),
               ti->asb + offsetof(struct asb_rec, station_id));
        writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)),
               ti->asb + offsetof(struct asb_rec, rec_buf_addr));
-       
+
        lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
-       
+
        llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
-       
+
 #if TR_VERBOSE
        DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
                (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
        DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc,
-               ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), 
+               ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))),
                ti->sram);
        DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
                "ethertype: %04X\n",
@@ -1327,9 +1327,9 @@ static void tr_rx(struct device *dev)
                (int)readb(llc + offsetof(struct trllc, protid)+2),
                (int)readw(llc + offsetof(struct trllc, ethertype)));
 #endif
-       
+
        if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
-#if !TR_FILTERNONUI            
+#if !TR_FILTERNONUI
                DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
                        (int)readb(llc + offsetof(struct trllc, llc))
 #endif
@@ -1338,20 +1338,20 @@ static void tr_rx(struct device *dev)
                        writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
                        return;
                        }
-               
+
                if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
                    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
                        is8022 = 1;
                }
-                       
+
 #if TR_VERBOSE
                if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
                    (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
-                       
+
                        __u32 trhhdr;
-                       
+
                        trhhdr=(rbuffer+offsetof(struct rec_buf,data));
-                       
+
                        DPRINTK("Probably non-IP frame received.\n");
                        DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
                                "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -1371,34 +1371,34 @@ static void tr_rx(struct device *dev)
                                (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
                }
 #endif
-               
+
                arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
                skb_size = arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr);
                if (is8022) {
                        skb_size += sizeof(struct trllc);
                }
-               
+
                if (!(skb=dev_alloc_skb(skb_size))) {
-                       DPRINTK("out of memory. frame dropped.\n");     
+                       DPRINTK("out of memory. frame dropped.\n");
                        ti->tr_stats.rx_dropped++;
                        writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
                        writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
                        return;
                }
-               
+
                skb_put(skb, skb_size);
                skb->dev=dev;
-               
+
                data=skb->data;
 #if USE_MEMCPY
                memcpy_fromio(data, rbuffer + offsetof(struct rec_buf, data), lan_hdr_len);
 #else
-               for (i=0; i<lan_hdr_len; i++) 
+               for (i=0; i<lan_hdr_len; i++)
                        data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
-#endif         
+#endif
                if (lan_hdr_len<sizeof(struct trh_hdr))
                        memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
-               
+
                data+=sizeof(struct trh_hdr);
                rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
                        -lan_hdr_len;
@@ -1408,7 +1408,7 @@ static void tr_rx(struct device *dev)
                        local_llc->ethertype = htons(ETH_P_TR_802_2);
                        data += sizeof(struct trllc);
                }
-               
+
 #if TR_VERBOSE
                DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
 #endif
@@ -1419,7 +1419,7 @@ static void tr_rx(struct device *dev)
                        data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
 #endif
                data+=rbuffer_len;
-               
+
                while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
                        rbuffer=(ti->sram
                                 +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
@@ -1427,58 +1427,58 @@ static void tr_rx(struct device *dev)
                        for (i=0; i<rbuffer_len; i++)
                                data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
                        data+=rbuffer_len;
-                       
+
 #if TR_VERBOSE
-                       DPRINTK("buf_ptr: %d, data =%p\n", 
+                       DPRINTK("buf_ptr: %d, data =%p\n",
                                ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
 #endif
-               } 
-               
+               }
+
                writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
-               
+
                writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-               
+
                ti->tr_stats.rx_packets++;
-               
+
                skb->protocol=tr_type_trans(skb,dev);
                netif_rx(skb);
-               
+
        }
 
-static int tok_send_packet(struct sk_buff *skb, struct device *dev) 
+static int tok_send_packet(struct sk_buff *skb, struct device *dev)
 {
        struct tok_info *ti;
        ti=(struct tok_info *) dev->priv;
-       
+
        if (dev->tbusy) {
                int ticks_waited;
-               
+
                ticks_waited=jiffies - dev->trans_start;
                if (ticks_waited<TR_BUSY_INTERVAL) return 1;
-               
+
                DPRINTK("Arrg. Transmitter busy.\n");
                dev->trans_start+=5; /* we fake the transmission start time... */
                return 1;
        }
-       
+
        /* Donald does this, so we do too. */
        if (skb==NULL) {
                dev_tint(dev);
                return 0;
        }
-       
+
        if (set_bit(0,(void *)&dev->tbusy)!=0)
                DPRINTK("Transmitter access conflict\n");
        else {
                /* Save skb; we'll need it when the adapter asks for the data */
-               ti->current_skb=skb; 
+               ti->current_skb=skb;
                writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
-               writew(ti->exsap_station_id, ti->srb 
+               writew(ti->exsap_station_id, ti->srb
                       +offsetof(struct srb_xmit, station_id));
                writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
                dev->trans_start=jiffies;
        }
-       
+
        return 0;
 }
 
@@ -1513,6 +1513,10 @@ static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24};
 static int irq[IBMTR_MAX_ADAPTERS] = {0,0};
 static int mem[IBMTR_MAX_ADAPTERS] = {0,0};
 
+MODULE_PARM(io, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+
 int init_module(void)
 {
         int i;
@@ -1528,7 +1532,7 @@ int init_module(void)
                dev_ibmtr[i]->irq       = irq[i];
                dev_ibmtr[i]->mem_start = mem[i];
                dev_ibmtr[i]->init      = &ibmtr_probe;
-       
+
                if (register_trdev(dev_ibmtr[i]) != 0) {
                        kfree_s(dev_ibmtr[i], sizeof(struct dev));
                        dev_ibmtr[i] = NULL;
@@ -1553,7 +1557,7 @@ void cleanup_module(void)
                         free_irq(dev_ibmtr[i]->irq, NULL);
                         irq2dev_map[dev_ibmtr[i]->irq] = NULL;
                         release_region(dev_ibmtr[i]->base_addr, IBMTR_IO_EXTENT);
-                        kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info)); 
+                        kfree_s(dev_ibmtr[i]->priv, sizeof(struct tok_info));
                         kfree_s(dev_ibmtr[i], sizeof(struct dev));
                         dev_ibmtr[i] = NULL;
                 }
index c19ac12104a9848c1c155e84667e47ffe9c11c4a..400d04d3d285ad6ca9753f86e92ae777129f21d7 100644 (file)
@@ -75,6 +75,7 @@ typedef struct ax25_ctrl {
 
 static ax25_ctrl_t **ax25_ctrls = NULL;
 int ax25_maxdev = AX25_MAXDEV;         /* Can be overridden with insmod! */
+MODULE_PARM(ax25_maxdev, "i");
 
 static struct tty_ldisc        ax_ldisc;
 static struct tty_driver mkiss_driver;
index ea5593513adf3f0aaf14fca74038a145c4421359..0c538eded7b5777609d81f0be85078f33d3af855 100644 (file)
@@ -158,10 +158,10 @@ struct netdev_entry netcard_drv =
 {"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist};
 #else
 
-/* 
- * Note that at boot, this probe only picks up one card at a time, even for 
- * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI 
- * ne2k card.  This keeps things consistent regardless of the bus type of 
+/*
+ * Note that at boot, this probe only picks up one card at a time, even for
+ * multiple PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI
+ * ne2k card.  This keeps things consistent regardless of the bus type of
  * the card.
  */
 
@@ -177,7 +177,7 @@ int ne_probe(struct device *dev)
 
 #ifdef CONFIG_PCI
     /* Then look for any installed PCI clones */
-    if (pcibios_present() && (ne_probe_pci(dev) == 0)) 
+    if (pcibios_present() && (ne_probe_pci(dev) == 0))
        return 0;
 #endif
 
@@ -205,7 +205,7 @@ static int ne_probe_pci(struct device *dev)
                unsigned char pci_bus, pci_device_fn;
                unsigned int pci_ioaddr;
                int pci_index;
-               
+
                for (pci_index = 0; pci_index < 8; pci_index++) {
                        if (pcibios_find_device (pci_clone_list[i].vendor,
                                        pci_clone_list[i].dev_id, pci_index,
@@ -281,7 +281,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
     /* A user with a poor card that fails to ack the reset, or that
        does not have a valid 0x57,0x57 signature can still use this
        without having to recompile. Specifying an i/o address along
-       with an otherwise unused dev->mem_end value of "0xBAD" will 
+       with an otherwise unused dev->mem_end value of "0xBAD" will
        cause the driver to skip these parts of the probe. */
 
     bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
@@ -339,13 +339,13 @@ static int ne_probe1(struct device *dev, int ioaddr)
 
     /* At this point, wordlength *only* tells us if the SA_prom is doubled
        up or not because some broken PCI cards don't respect the byte-wide
-       request in program_seq above, and hence don't have doubled up values. 
+       request in program_seq above, and hence don't have doubled up values.
        These broken cards would otherwise be detected as an ne1000.  */
 
     if (wordlength == 2)
        for (i = 0; i < 16; i++)
                SA_prom[i] = SA_prom[i+i];
-    
+
     if (pci_irq_line || ioaddr >= 0x400)
        wordlength = 2;         /* Catch broken PCI cards mentioned above. */
 
@@ -419,7 +419,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
        printk(" failed to detect IRQ line.\n");
        return EAGAIN;
     }
-    
+
     /* Snarf the interrupt now.  There's no point in waiting since we cannot
        share and the board will usually be enabled. */
     {
@@ -438,7 +438,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
        free_irq(dev->irq, NULL);
        return -ENOMEM;
     }
+
     request_region(ioaddr, NE_IO_EXTENT, name);
 
     for(i = 0; i < ETHER_ADDR_LEN; i++) {
@@ -733,6 +733,10 @@ static int io[MAX_NE_CARDS] = { 0, };
 static int irq[MAX_NE_CARDS]  = { 0, };
 static int bad[MAX_NE_CARDS]  = { 0, };        /* 0xbad = bad sig or no reset ack */
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+
 /* This is set up so that no ISA autoprobe takes place. We can't guarantee
 that the ne2k probe is the last 8390 based probe to take place (as it
 is at boot) and so the probe will get confused by any other 8390 cards.
index 4dd1a5ab589877dc0f2f637cb110524db49cf6ee..8f4cd4e288a8c9744426d406a411544574676ac0 100644 (file)
@@ -1,9 +1,9 @@
-/* 
+/*
  * net-3-driver for the NI5210 card (i82586 Ethernet chip)
  *
  * This is an extension to the Linux operating system, and is covered by the
  * same Gnu Public License that covers that work.
- * 
+ *
  * Alphacode 0.82 (96/09/29) for Linux 2.0.0 (or later)
  * Copyrights (c) 1994,1995,1996 by M.Hipp (Michael.Hipp@student.uni-tuebingen.de)
  *    [feel free to mail ....]
  *       insmod ni52.o io=0x360 irq=9 memstart=0xd0000 memend=0xd4000
  *
  * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
- * 
+ *
  * If you find a bug, please report me:
  *   The kernel panic output and any kmsg from the ni52 driver
- *   the ni5210-driver-version and the linux-kernel version 
- *   how many shared memory (memsize) on the netcard, 
+ *   the ni5210-driver-version and the linux-kernel version
+ *   how many shared memory (memsize) on the netcard,
  *   bootprom: yes/no, base_addr, mem_start
  *   maybe the ni5210-card revision and the i82586 version
  *
  *
  * Known Problems:
  *   The internal sysbus seems to be slow. So we often lose packets because of
- *   overruns while receiving from a fast remote host. 
+ *   overruns while receiving from a fast remote host.
  *   This can slow down TCP connections. Maybe the newer ni5210 cards are better.
  *   my experience is, that if a machine sends with more then about 500-600K/s
  *   the fifo/sysbus overflows.
- * 
+ *
  * IMPORTANT NOTE:
  *   On fast networks, it's a (very) good idea to have 16K shared memory. With
- *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote 
+ *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote
  *   machine 'overruns' our system.
  *
  * Known i82586/card problems (I'm sure, there are many more!):
  *   Running the NOP-mode, the i82586 sometimes seems to forget to report
  *   every xmit-interrupt until we restart the CU.
- *   Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit 
- *   in the RBD-Struct which indicates an end of the RBD queue. 
- *   Instead, the RU fetches another (randomly selected and 
- *   usually used) RBD and begins to fill it. (Maybe, this happens only if 
+ *   Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit
+ *   in the RBD-Struct which indicates an end of the RBD queue.
+ *   Instead, the RU fetches another (randomly selected and
+ *   usually used) RBD and begins to fill it. (Maybe, this happens only if
  *   the last buffer from the previous RFD fits exact into the queue and
  *   the next RFD can't fetch an initial RBD. Anyone knows more? )
  *
- * results from ftp performance tests with Linux 1.2.5 
+ * results from ftp performance tests with Linux 1.2.5
  *   send and receive about 350-400 KByte/s (peak up to 460 kbytes/s)
  *   sending in NOP-mode: peak performance up to 530K/s (but better don't run this mode)
  */
 
 /*
- * 29.Sept.96: virt_to_bus changes for new memory scheme 
+ * 29.Sept.96: virt_to_bus changes for new memory scheme
  * 19.Feb.96: more Mcast changes, module support (MH)
  *
  * 18.Nov.95: Mcast changes (AC).
  *
  * 23.April.95: fixed(?) receiving problems by configuring a RFD more
- *              than the number of RBD's. Can maybe cause other problems. 
+ *              than the number of RBD's. Can maybe cause other problems.
  * 18.April.95: Added MODULE support (MH)
  * 17.April.95: MC related changes in init586() and set_multicast_list().
  *              removed use of 'jiffies' in init586() (MH)
  *
  * 19.Sep.94: Added Multicast support (not tested yet) (MH)
- * 
- * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling. 
+ *
+ * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling.
  *            Now, every RFD has exact one RBD. (MH)
  *
  * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
  *
  * 19.Aug.94: changed request_irq() parameter (MH)
- * 
+ *
  * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH)
  *
  * 19.July.94: lotsa cleanups .. (MH)
@@ -96,7 +96,7 @@
  *
  * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
  *
- * < 30.Sep.93: first versions 
+ * < 30.Sep.93: first versions
  */
 
 static int debuglevel = 0; /* debug-printk 0: off 1: a few 2: more */
@@ -143,9 +143,9 @@ static int fifo=0x8;        /* don't change */
 
 sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
 sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12; 
+sizeof(rfd) = 24; sizeof(rbd) = 12;
 sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8; 
+sizeof(nop_cmd) = 8;
 
   * if you don't know the driver, better do not change these values: */
 
@@ -159,7 +159,7 @@ sizeof(nop_cmd) = 8;
 /**************************************************************************/
 
 /* different DELAYs */
-#define DELAY(x) __delay((loops_per_sec>>5)*(x)); 
+#define DELAY(x) __delay((loops_per_sec>>5)*(x));
 #define DELAY_16(); { __delay( (loops_per_sec>>16)+1 ); }
 #define DELAY_18(); { __delay( (loops_per_sec>>18)+1 ); }
 
@@ -234,7 +234,7 @@ struct priv
 };
 
 /**********************************************
- * close device 
+ * close device
  */
 static int ni52_close(struct device *dev)
 {
@@ -252,21 +252,21 @@ static int ni52_close(struct device *dev)
 }
 
 /**********************************************
- * open device 
+ * open device
  */
 static int ni52_open(struct device *dev)
 {
   ni_disint();
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   ni_enaint();
 
-  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL)) 
+  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL))
   {
     ni_reset586();
     return -EAGAIN;
-  }  
+  }
   irq2dev_map[dev->irq] = dev;
 
   dev->interrupt = 0;
@@ -279,7 +279,7 @@ static int ni52_open(struct device *dev)
 }
 
 /**********************************************
- * Check to see if there's an 82586 out there. 
+ * Check to see if there's an 82586 out there.
  */
 static int check586(struct device *dev,char *where,unsigned size)
 {
@@ -298,7 +298,7 @@ static int check586(struct device *dev,char *where,unsigned size)
   p->scp->sysbus = SYSBUSVAL;        /* 1 = 8Bit-Bus, 0 = 16 Bit */
   if(p->scp->sysbus != SYSBUSVAL)
     return 0;
-  
+
   iscp_addrs[0] = bus_to_virt((unsigned long)where);
   iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
 
@@ -321,11 +321,11 @@ static int check586(struct device *dev,char *where,unsigned size)
 }
 
 /******************************************************************
- * set iscp at the right place, called by ni52_probe1 and open586. 
+ * set iscp at the right place, called by ni52_probe1 and open586.
  */
 void alloc586(struct device *dev)
 {
-  struct priv *p =  (struct priv *) dev->priv; 
+  struct priv *p =  (struct priv *) dev->priv;
 
   ni_reset586();
   DELAY(1);
@@ -345,7 +345,7 @@ void alloc586(struct device *dev)
   ni_reset586();
   ni_attn586();
 
-  DELAY(1); 
+  DELAY(1);
 
   if(p->iscp->busy)
     printk("%s: Init-Problems (alloc).\n",dev->name);
@@ -380,7 +380,7 @@ int ni52_probe(struct device *dev)
     int ioaddr = *port;
     if (check_region(ioaddr, NI52_TOTAL_SIZE))
       continue;
-    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || 
+    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
         !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
       continue;
 
@@ -395,11 +395,11 @@ int ni52_probe(struct device *dev)
     int ioaddr = dev->base_addr;
     if (check_region(ioaddr, NI52_TOTAL_SIZE))
       continue;
-    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) || 
+    if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
         !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
       continue;
     if (ni52_probe1(dev, ioaddr) == 0)
-      return 0;    
+      return 0;
   }
 #endif
 
@@ -424,7 +424,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
 
   request_region(ioaddr,NI52_TOTAL_SIZE,"ni5210");
 
-  /* 
+  /*
    * check (or search) IO-Memory, 8K and 16K
    */
 #ifdef MODULE
@@ -451,7 +451,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
       }
     }
   }
-  else  
+  else
   {
    static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000,
                               0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 };
@@ -473,7 +473,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
   dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
 #endif
 
-  dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL); 
+  dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
   if(dev->priv == NULL)
   {
     printk("%s: Ooops .. can't allocate private driver memory.\n",dev->name);
@@ -481,7 +481,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
   }
                                   /* warning: we don't free it on errors */
   memset((char *) dev->priv,0,sizeof(struct priv));
-  
+
   ((struct priv *) (dev->priv))->memtop = bus_to_virt(dev->mem_start) + size;
   ((struct priv *) (dev->priv))->base =  (unsigned long) bus_to_virt(dev->mem_start) + size - 0x01000000;
   alloc586(dev);
@@ -501,7 +501,7 @@ static int ni52_probe1(struct device *dev,int ioaddr)
     ni_attn586();
     if(!(dev->irq = autoirq_report(2)))
     {
-      printk("?autoirq, Failed to detect IRQ line!\n"); 
+      printk("?autoirq, Failed to detect IRQ line!\n");
       return 1;
     }
     printk("IRQ %d (autodetected).\n",dev->irq);
@@ -525,11 +525,11 @@ static int ni52_probe1(struct device *dev,int ioaddr)
   dev->tbusy = 0;
   dev->interrupt = 0;
   dev->start = 0;
-  
+
   return 0;
 }
 
-/********************************************** 
+/**********************************************
  * init the chip (ni52-interrupt should be disabled?!)
  * needs a correct 'allocated' memory
  */
@@ -575,7 +575,7 @@ static int init586(struct device *dev)
        dev->flags|=IFF_PROMISC;
   }
   cfg_cmd->carr_coll  = 0x00;
+
   p->scb->cbl_offset = make16(cfg_cmd);
   p->scb->cmd_ruc = 0;
 
@@ -587,7 +587,7 @@ static int init586(struct device *dev)
   if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
   {
     printk("%s: configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
     /*
@@ -610,11 +610,11 @@ static int init586(struct device *dev)
 
   if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
     printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
-    return 1; 
+    return 1;
   }
 
-   /* 
-    * TDR, wire check .. e.g. no resistor e.t.c 
+   /*
+    * TDR, wire check .. e.g. no resistor e.t.c
     */
   tdr_cmd = (struct tdr_cmd_struct *)ptr;
 
@@ -641,13 +641,13 @@ static int init586(struct device *dev)
     p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
     ni_attn586(); /* ack the interrupts */
 
-    if(result & TDR_LNK_OK) 
+    if(result & TDR_LNK_OK)
       ;
     else if(result & TDR_XCVR_PRB)
       printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
     else if(result & TDR_ET_OPN)
       printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
-    else if(result & TDR_ET_SRT) 
+    else if(result & TDR_ET_SRT)
     {
       if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
         printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
@@ -703,7 +703,7 @@ static int init586(struct device *dev)
   }
 #endif
 
-  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */ 
+  ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
 
   /*
    * alloc xmit-buffs / init xmit_cmds
@@ -716,11 +716,11 @@ static int init586(struct device *dev)
     ptr = (char *) ptr + XMIT_BUFF_SIZE;
     p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
     ptr = (char *) ptr + sizeof(struct tbd_struct);
-    if((void *)ptr > (void *)p->iscp) 
+    if((void *)ptr > (void *)p->iscp)
     {
       printk("%s: not enough shared-mem for your configuration!\n",dev->name);
       return 1;
-    }   
+    }
     memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
     memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
     p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
@@ -731,7 +731,7 @@ static int init586(struct device *dev)
     p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
   }
 
-  p->xmit_count = 0; 
+  p->xmit_count = 0;
   p->xmit_last  = 0;
 #ifndef NO_NOPCOMMANDS
   p->nop_point  = 0;
@@ -763,11 +763,11 @@ static int init586(struct device *dev)
 }
 
 /******************************************************
- * This is a helper routine for ni52_rnr_int() and init586(). 
+ * This is a helper routine for ni52_rnr_int() and init586().
  * It sets up the Receive Frame Area (RFA).
  */
 
-static void *alloc_rfa(struct device *dev,void *ptr) 
+static void *alloc_rfa(struct device *dev,void *ptr)
 {
   volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
   volatile struct rbd_struct *rbd;
@@ -854,7 +854,7 @@ static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
       else
       {
         printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
-        ni52_rnr_int(dev); 
+        ni52_rnr_int(dev);
       }
     }
 
@@ -989,7 +989,7 @@ static void ni52_rcv_int(struct device *dev)
 
 #ifdef 0
   if(!at_least_one)
-  { 
+  {
     int i;
     volatile struct rfd_struct *rfds=p->rfd_top;
     volatile struct rbd_struct *rbds;
@@ -1001,7 +1001,7 @@ static void ni52_rcv_int(struct device *dev)
       rfds = (struct rfd_struct *) make32(rfds->next);
     }
     printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
-    printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);  
+    printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
   }
   old_at_least = at_least_one;
 #endif
@@ -1022,7 +1022,7 @@ static void ni52_rnr_int(struct device *dev)
 
   WAIT_4_SCB_CMD();    /* wait for the last cmd, WAIT_4_FULLSTAT?? */
   p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
-  ni_attn586(); 
+  ni_attn586();
   WAIT_4_SCB_CMD_RUC();    /* wait for accept cmd. */
 
   alloc_rfa(dev,(char *)p->rfd_first);
@@ -1054,18 +1054,18 @@ static void ni52_xmt_int(struct device *dev)
     p->stats.tx_packets++;
     p->stats.collisions += (status & TCMD_MAXCOLLMASK);
   }
-  else 
+  else
   {
     p->stats.tx_errors++;
     if(status & TCMD_LATECOLL) {
       printk("%s: late collision detected.\n",dev->name);
       p->stats.collisions++;
-    } 
+    }
     else if(status & TCMD_NOCARRIER) {
       p->stats.tx_carrier_errors++;
       printk("%s: no carrier detected.\n",dev->name);
-    } 
-    else if(status & TCMD_LOSTCTS) 
+    }
+    else if(status & TCMD_LOSTCTS)
       printk("%s: loss of CTS detected.\n",dev->name);
     else if(status & TCMD_UNDERRUN) {
       p->stats.tx_fifo_errors++;
@@ -1074,11 +1074,11 @@ static void ni52_xmt_int(struct device *dev)
     else if(status & TCMD_MAXCOLL) {
       printk("%s: Max. collisions exceeded.\n",dev->name);
       p->stats.collisions += 16;
-    } 
+    }
   }
 
 #if (NUM_XMIT_BUFFS > 1)
-  if( (++p->xmit_last) == NUM_XMIT_BUFFS) 
+  if( (++p->xmit_last) == NUM_XMIT_BUFFS)
     p->xmit_last = 0;
 #endif
 
@@ -1088,7 +1088,7 @@ static void ni52_xmt_int(struct device *dev)
 
 /***********************************************************
  * (re)start the receiver
- */ 
+ */
 
 static void startrecv586(struct device *dev)
 {
@@ -1103,7 +1103,7 @@ static void startrecv586(struct device *dev)
 }
 
 /******************************************************
- * send frame 
+ * send frame
  */
 
 static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
@@ -1222,7 +1222,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
     next_nop = (p->nop_point + 1) & 0x1;
     p->xmit_buffs[0]->size = TBD_LAST | len;
 
-    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link 
+    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link
                                 = make16((p->nop_cmds[next_nop]));
     p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
 
@@ -1233,7 +1233,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
 #  endif
 #else
     p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
-    if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) 
+    if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
       next_nop = 0;
 
     p->xmit_cmds[p->xmit_count]->cmd_status  = 0;
@@ -1244,9 +1244,9 @@ static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
     p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
     dev->trans_start = jiffies;
     p->xmit_count = next_nop;
+
     {
-      long flags; 
+      long flags;
       save_flags(flags);
       cli();
       if(p->xmit_count != p->xmit_last)
@@ -1261,7 +1261,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
 }
 
 /*******************************************
- * Someone wanna have the statistics 
+ * Someone wanna have the statistics
  */
 
 static struct enet_statistics *ni52_get_stats(struct device *dev)
@@ -1287,7 +1287,7 @@ static struct enet_statistics *ni52_get_stats(struct device *dev)
 }
 
 /********************************************************
- * Set MC list ..  
+ * Set MC list ..
  */
 static void set_multicast_list(struct device *dev)
 {
@@ -1301,7 +1301,7 @@ static void set_multicast_list(struct device *dev)
 
   ni_disint();
   alloc586(dev);
-  init586(dev);  
+  init586(dev);
   startrecv586(dev);
   ni_enaint();
 
@@ -1321,6 +1321,11 @@ int io=0x300;
 long memstart=0; /* e.g 0xd0000 */
 long memend=0;   /* e.g 0xd4000 */
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(memstart, "l");
+MODULE_PARM(memend, "l");
+
 int init_module(void)
 {
   if(io <= 0x0 || !memend || !memstart || irq < 2) {
@@ -1383,7 +1388,5 @@ void ni52_dump(struct device *dev,void *ptr)
 #endif
 
 /*
- * END: linux/drivers/net/ni52.c 
+ * END: linux/drivers/net/ni52.c
  */
-
-
index 75e891477d228beb4c7afddbc47549dd9b1d9205..b2fc38b9ae8457dccae0eb5867ce5345ab16b45e 100644 (file)
@@ -2,9 +2,9 @@
  * ni6510 (am7990 'lance' chip) driver for Linux-net-3
  * BETAcode v0.71 (96/09/29) for 2.0.0 (or later)
  * copyrights (c) 1994,1995,1996 by M.Hipp
- * 
- * This driver can handle the old ni6510 board and the newer ni6510 
- * EtherBlaster. (probably it also works with every full NE2100 
+ *
+ * This driver can handle the old ni6510 board and the newer ni6510
+ * EtherBlaster. (probably it also works with every full NE2100
  * compatible card)
  *
  * To compile as module, type:
@@ -40,7 +40,7 @@
  * simple performance test: (486DX-33/Ni6510-EB receives from 486DX4-100/Ni6510-EB)
  *    average: FTP -> 8384421 bytes received in 8.5 seconds
  *           (no RCV_VIA_SKB,no XMT_VIA_SKB,PARANOIA_CHECK,4 XMIT BUFS, 8 RCV_BUFFS)
- *    peak: FTP -> 8384421 bytes received in 7.5 seconds 
+ *    peak: FTP -> 8384421 bytes received in 7.5 seconds
  *           (RCV_VIA_SKB,XMT_VIA_SKB,no PARANOIA_CHECK,1(!) XMIT BUF, 16 RCV BUFFS)
  */
 
@@ -84,7 +84,7 @@
 
 /*
  * the current setting allows an acceptable performance
- * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in 
+ * for 'RCV_PARANOIA_CHECK' read the 'known problems' part in
  * the header of this file
  * 'invert' the defines for max. performance. This may cause DMA problems
  * on some boards (e.g on my ASUS SP3G)
  */
 #if 1
 #define RMDNUM 16
-#define RMDNUMMASK 0x80000000 
+#define RMDNUMMASK 0x80000000
 #else
 #define RMDNUM 8
 #define RMDNUMMASK 0x60000000 /* log2(RMDNUM)<<29 */
 #define L_CONFIG  0x05
 #define L_BUSIF   0x06
 
-/* 
+/*
  * to access the lance/am7990-regs, you have to write
  * reg-number into L_ADDRREG, then you can access it using L_DATAREG
  */
@@ -193,11 +193,11 @@ static struct card {
 };
 #define NUM_CARDS 3
 
-struct priv 
+struct priv
 {
   struct rmd rmdhead[RMDNUM];
   struct tmd tmdhead[TMDNUM];
-  struct init_block ib; 
+  struct init_block ib;
   int rmdnum;
   int tmdnum,tmdlast;
 #ifdef RCV_VIA_SKB
@@ -216,7 +216,7 @@ struct priv
   int cmdr_addr;
   int cardno;
   int features;
-}; 
+};
 
 static int  ni65_probe1(struct device *dev,int);
 static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs);
@@ -246,11 +246,11 @@ static void ni65_set_performance(struct priv *p)
 
   if( !(cards[p->cardno].config & 0x02) )
     return;
+
   outw(80,PORT+L_ADDRREG);
   if(inw(PORT+L_ADDRREG) != 80)
     return;
+
   writereg( (csr80 & 0x3fff) ,80); /* FIFO watermarks */
   outw(0,PORT+L_ADDRREG);
   outw((short)isa0,PORT+L_BUSIF); /* write ISA 0: DMA_R : isa0 * 50ns */
@@ -269,7 +269,7 @@ static int ni65_open(struct device *dev)
   int irqval = request_irq(dev->irq, &ni65_interrupt,0,
                         cards[p->cardno].cardname,NULL);
   if (irqval) {
-    printk ("%s: unable to get IRQ %d (irqval=%d).\n", 
+    printk ("%s: unable to get IRQ %d (irqval=%d).\n",
               dev->name,dev->irq, irqval);
     return -EAGAIN;
   }
@@ -318,12 +318,12 @@ static int ni65_close(struct device *dev)
   dev->tbusy = 1;
   dev->start = 0;
   MOD_DEC_USE_COUNT;
-  return 0; 
+  return 0;
 }
 
-/* 
- * Probe The Card (not the lance-chip) 
- */ 
+/*
+ * Probe The Card (not the lance-chip)
+ */
 #ifdef MODULE
 static
 #endif
@@ -337,7 +337,7 @@ int ni65_probe(struct device *dev)
   else if (dev->base_addr > 0)         /* Don't probe at all. */
      return -ENXIO;
 
-  for (port = ports; *port; port++) 
+  for (port = ports; *port; port++)
   {
     if (ni65_probe1(dev, *port) == 0)
        return 0;
@@ -347,12 +347,12 @@ int ni65_probe(struct device *dev)
 }
 
 /*
- * this is the real card probe .. 
+ * this is the real card probe ..
  */
 static int ni65_probe1(struct device *dev,int ioaddr)
 {
   int i,j;
-  struct priv *p; 
+  struct priv *p;
 
   for(i=0;i<NUM_CARDS;i++) {
     if(check_region(ioaddr, cards[i].total_size))
@@ -464,8 +464,8 @@ static int ni65_probe1(struct device *dev,int ioaddr)
     return -EAGAIN;
   }
 
-  /* 
-   * Grab the region so we can find another board. 
+  /*
+   * Grab the region so we can find another board.
    */
   request_region(ioaddr,cards[p->cardno].total_size,cards[p->cardno].cardname);
 
@@ -487,9 +487,9 @@ static int ni65_probe1(struct device *dev,int ioaddr)
 }
 
 /*
- * set lance register and trigger init 
+ * set lance register and trigger init
  */
-static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode) 
+static void ni65_init_lance(struct priv *p,unsigned char *daddr,int filter,int mode)
 {
   int i;
   u32 pib;
@@ -566,8 +566,8 @@ static int ni65_alloc_buffer(struct device *dev)
   unsigned char *ptr;
   struct priv *p;
   int i;
-  /* 
+
+  /*
    * we need 8-aligned memory ..
    */
   ptr = ni65_alloc_mem(dev,"BUFFER",sizeof(struct priv)+8,0);
@@ -611,7 +611,7 @@ static int ni65_alloc_buffer(struct device *dev)
 }
 
 /*
- * free buffers and private struct 
+ * free buffers and private struct
  */
 static void ni65_free_buffer(struct priv *p)
 {
@@ -673,7 +673,7 @@ static void ni65_stop_start(struct device *dev,struct priv *p)
           break;
       }
     }
-    
+
     for(i=0;i<TMDNUM;i++) {
       struct tmd *tmdp = p->tmdhead + i;
 #ifdef XMT_VIA_SKB
@@ -708,12 +708,12 @@ static void ni65_stop_start(struct device *dev,struct priv *p)
     if(!p->lock)
       dev->tbusy = (p->tmdnum || !p->xmit_queued) ? 0 : 1;
     dev->trans_start = jiffies;
-  } 
+  }
   else
     writedatareg(CSR0_STRT | csr0);
 }
 
-/* 
+/*
  * init lance (write init-values .. init-buffers) (open-helper)
  */
 static int ni65_lance_reinit(struct device *dev)
@@ -726,7 +726,7 @@ static int ni65_lance_reinit(struct device *dev)
 
    disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
    set_dma_mode(dev->dma,DMA_MODE_CASCADE);
-   enable_dma(dev->dma); 
+   enable_dma(dev->dma);
 
    outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
    if( (i=readreg(CSR0) ) != 0x4)
@@ -764,17 +764,17 @@ static int ni65_lance_reinit(struct device *dev)
      rmdp->mlen = 0;
      rmdp->u.s.status = RCV_OWN;
    }
-   
+
    if(dev->flags & IFF_PROMISC)
      ni65_init_lance(p,dev->dev_addr,0x00,M_PROM);
    else if(dev->mc_count || dev->flags & IFF_ALLMULTI)
      ni65_init_lance(p,dev->dev_addr,0xff,0x0);
-   else 
+   else
      ni65_init_lance(p,dev->dev_addr,0x00,0x00);
 
   /*
    * ni65_set_lance_mem() sets L_ADDRREG to CSR0
-   * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED 
+   * NOW, WE WILL NEVER CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED
    */
 
    if(inw(PORT+L_DATAREG) & CSR0_IDON)  {
@@ -787,9 +787,9 @@ static int ni65_lance_reinit(struct device *dev)
    disable_dma(dev->dma);
    return 0; /* ->Error */
 }
-/* 
- * interrupt handler  
+
+/*
+ * interrupt handler
  */
 static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
@@ -975,7 +975,7 @@ static void ni65_xmit_intr(struct device *dev,int csr0)
  */
 static void ni65_recv_intr(struct device *dev,int csr0)
 {
-  struct rmd *rmdp; 
+  struct rmd *rmdp;
   int rmdstat,len;
   int cnt=0;
   struct priv *p = (struct priv *) dev->priv;
@@ -984,7 +984,7 @@ static void ni65_recv_intr(struct device *dev,int csr0)
   while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
   {
     cnt++;
-    if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */ 
+    if( (rmdstat & (RCV_START | RCV_END | RCV_ERR)) != (RCV_START | RCV_END) ) /* error or oversized? */
     {
       if(!(rmdstat & RCV_ERR)) {
         if(rmdstat & RCV_START)
@@ -1001,7 +1001,7 @@ static void ni65_recv_intr(struct device *dev,int csr0)
           p->stats.rx_frame_errors++;
         if(rmdstat & RCV_OFLO)
           p->stats.rx_over_errors++;
-        if(rmdstat & RCV_CRC) 
+        if(rmdstat & RCV_CRC)
           p->stats.rx_crc_errors++;
         if(rmdstat & RCV_BUF_ERR)
           p->stats.rx_fifo_errors++;
@@ -1128,7 +1128,7 @@ static int ni65_send_packet(struct sk_buff *skb, struct device *dev)
     else {
       save_flags(flags);
       cli();
+
       tmdp = p->tmdhead + p->tmdnum;
       tmdp->u.buffer = (u32) virt_to_bus(skb->data);
       p->tmd_skb[p->tmdnum] = skb;
@@ -1187,6 +1187,10 @@ static int irq=0;
 static int io=0;
 static int dma=0;
 
+MODULE_PARM(irq, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(dma, "i");
+
 int init_module(void)
 {
 #if 0
@@ -1222,7 +1226,5 @@ void cleanup_module(void)
 #endif /* MODULE */
 
 /*
- * END of ni65.c 
+ * END of ni65.c
  */
-
-
index 2233c78a014144376ada8fb6d0d374831b121a2c..f2799b3dd74811d0bbdfd2e7688f1223233a69b0 100644 (file)
@@ -20,7 +20,7 @@
  *               - added message if driver loaded as a module but no
  *                 interfaces present.
  *               - release claimed I/O ports if malloc() fails during init.
- *             
+ *
  *             Niibe Yutaka
  *               - Module initialization.  You can specify I/O addr and IRQ:
  *                     # insmod plip.o io=0x3bc irq=7
@@ -44,7 +44,7 @@
  *     Crynwr packet driver, Peter Bauer changed the protocol again
  *     back to original protocol.
  *
- *     This version follows original PLIP protocol. 
+ *     This version follows original PLIP protocol.
  *     So, this PLIP can't communicate the PLIP of Linux v1.0.
  */
 
@@ -187,7 +187,7 @@ struct plip_local {
                        unsigned char lsb;
 #else
 #error "Please fix the endianness defines in <asm/byteorder.h>"
-#endif                                         
+#endif
                } b;
                unsigned short h;
        } length;
@@ -553,7 +553,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
        case PLIP_PK_DATA:
                lbuf = rcv->skb->data;
                do
-                       if (plip_receive(nibble_timeout, status_addr, 
+                       if (plip_receive(nibble_timeout, status_addr,
                                         &rcv->nibble, &lbuf[rcv->byte]))
                                return TIMEOUT;
                while (++rcv->byte < rcv->length.h);
@@ -605,7 +605,7 @@ plip_receive_packet(struct device *dev, struct net_local *nl,
        return OK;
 }
 
-/* PLIP_SEND --- send a byte (two nibbles) 
+/* PLIP_SEND --- send a byte (two nibbles)
    Returns OK on success, TIMEOUT when timeout    */
 inline static int
 plip_send(unsigned short nibble_timeout, unsigned short data_addr,
@@ -625,7 +625,7 @@ plip_send(unsigned short nibble_timeout, unsigned short data_addr,
                data_addr++;
                while (1) {
                        c0 = inb(data_addr);
-                       if ((c0 & 0x80) == 0) 
+                       if ((c0 & 0x80) == 0)
                                break;
                        if (--cx == 0)
                                return TIMEOUT;
@@ -1048,7 +1048,7 @@ plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
 {
        struct net_local *nl = (struct net_local *) dev->priv;
        struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
-       
+
        switch(pc->pcmd) {
        case PLIP_GET_TIMEOUT:
                pc->trigger = nl->trigger;
@@ -1068,24 +1068,27 @@ plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
 static int io[] = {0, 0, 0};
 static int irq[] = {0, 0, 0};
 
+MODULE_PARM(io, "1-3i");
+MODULE_PARM(irq, "1-3i");
+
 static struct device dev_plip[] = {
        {
                "plip0",
                0, 0, 0, 0,             /* memory */
                0x3BC, 5,               /* base, irq */
-               0, 0, 0, NULL, plip_init 
+               0, 0, 0, NULL, plip_init
        },
        {
                "plip1",
                0, 0, 0, 0,             /* memory */
                0x378, 7,               /* base, irq */
-               0, 0, 0, NULL, plip_init 
+               0, 0, 0, NULL, plip_init
        },
        {
                "plip2",
                0, 0, 0, 0,             /* memory */
                0x278, 2,               /* base, irq */
-               0, 0, 0, NULL, plip_init 
+               0, 0, 0, NULL, plip_init
        }
 };
 
@@ -1120,7 +1123,7 @@ init_module(void)
                return 0;
 
        /* No parameters.  Default action is probing all interfaces. */
-       for (i=0; i < 3; i++) { 
+       for (i=0; i < 3; i++) {
                if (register_netdev(&dev_plip[i]) == 0)
                        devices++;
        }
index 06bb554177e94c262d1426369b3c73cbe87232c2..fe2c21ebda46a966d43d3a34296027b9e3b20c20 100644 (file)
@@ -165,6 +165,9 @@ static int  rcv_proto_ccp (struct ppp *, __u16, __u8 *, int);
 static int  flag_time = OPTIMIZE_FLAG_TIME;
 static int  max_dev   = PPP_MAX_DEV;
 
+MODULE_PARM(flag_time, "i");
+MODULE_PARM(max_dev, "i");
+
 /*
  * The "main" procedure to the ppp device
  */
index f530f47e1dc0160b5fb1494036d4b8c3d7359bb8..30c40104c44078d1a3eff046df1db94464236e66 100644 (file)
@@ -90,7 +90,9 @@ typedef struct slip_ctrl {
        struct device   dev;            /* the device                   */
 } slip_ctrl_t;
 static slip_ctrl_t     **slip_ctrls = NULL;
+
 int slip_maxdev = SL_NRUNIT;           /* Can be overridden with insmod! */
+MODULE_PARM(slip_maxdev, "i");
 
 static struct tty_ldisc        sl_ldisc;
 
@@ -291,7 +293,7 @@ static void sl_changedmtu(struct slip *sl)
                }
        }
        sl->mtu      = dev->mtu;
-       
+
        sl->buffsize = len;
 
        restore_flags(flags);
@@ -571,11 +573,11 @@ sl_open(struct device *dev)
        sl->xbits    = 0;
 #endif
        sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
-#ifdef CONFIG_SLIP_SMART       
+#ifdef CONFIG_SLIP_SMART
        sl->keepalive=0;                /* no keepalive by default = VSV */
        init_timer(&sl->keepalive_timer);       /* initialize timer_list struct */
        sl->keepalive_timer.data=(unsigned long)sl;
-       sl->keepalive_timer.function=sl_keepalive;      
+       sl->keepalive_timer.function=sl_keepalive;
        sl->outfill=0;                  /* & outfill too */
        init_timer(&sl->outfill_timer);
        sl->outfill_timer.data=(unsigned long)sl;
@@ -617,7 +619,7 @@ sl_close(struct device *dev)
        sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
        dev->tbusy = 1;
        dev->start = 0;
-       
+
 /*     dev->flags &= ~IFF_UP; */
 
        return 0;
@@ -709,7 +711,7 @@ slip_open(struct tty_struct *tty)
        if ((err = sl_open(sl->dev)))  {
                return err;
        }
-       
+
        MOD_INC_USE_COUNT;
 
        /* Done.  We have linked the TTY line to a channel. */
@@ -734,7 +736,7 @@ slip_close(struct tty_struct *tty)
        }
 
        (void) dev_close(sl->dev);
-       
+
        tty->disc_data = 0;
        sl->tty = NULL;
        /* VSV = very important to remove timers */
@@ -1016,7 +1018,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
                }
                get_user(tmp,(int *)arg);
                 if (tmp > 255) /* max for unchar */
-                       return -EINVAL; 
+                       return -EINVAL;
                if ((sl->keepalive = (unchar) tmp) != 0) {
                        sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
                        add_timer(&sl->keepalive_timer);
@@ -1057,7 +1059,7 @@ slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
                put_user(sl->outfill, (int *)arg);
                return 0;
        /* VSV changes end */
-#endif 
+#endif
 
        /* Allow stty to read, but not set, the serial port */
        case TCGETS:
@@ -1099,15 +1101,15 @@ int slip_init_ctrl_dev(struct device *dummy)
 #endif
 #ifdef CONFIG_SLIP_SMART
        printk(KERN_INFO "SLIP linefill/keepalive option.\n");
-#endif 
+#endif
 
        slip_ctrls = (slip_ctrl_t **) kmalloc(sizeof(void*)*slip_maxdev, GFP_KERNEL);
-       if (slip_ctrls == NULL) 
+       if (slip_ctrls == NULL)
        {
                printk("SLIP: Can't allocate slip_ctrls[] array!  Uaargh! (-> No SLIP available)\n");
                return -ENOMEM;
        }
-       
+
        /* Clear the pointer array, we allocate devices when we need them */
        memset(slip_ctrls, 0, sizeof(void*)*slip_maxdev); /* Pointers */
 
@@ -1152,11 +1154,11 @@ slip_init(struct device *dev)
          return -ENODEV;
 
        /* Set up the "SLIP Control Block". (And clear statistics) */
-       
+
        memset(sl, 0, sizeof (struct slip));
        sl->magic  = SLIP_MAGIC;
        sl->dev    = dev;
-       
+
        /* Finish setting up the DEVICE info. */
        dev->mtu                = SL_MTU;
        dev->hard_start_xmit    = sl_xmit;
@@ -1195,16 +1197,16 @@ cleanup_module(void)
 {
        int i;
 
-       if (slip_ctrls != NULL) 
+       if (slip_ctrls != NULL)
        {
-               for (i = 0; i < slip_maxdev; i++)  
+               for (i = 0; i < slip_maxdev; i++)
                {
                        if (slip_ctrls[i])
                        {
                                /*
                                 * VSV = if dev->start==0, then device
                                 * unregistered while close proc.
-                                */ 
+                                */
                                if (slip_ctrls[i]->dev.start)
                                        unregister_netdev(&(slip_ctrls[i]->dev));
 
@@ -1215,7 +1217,7 @@ cleanup_module(void)
                kfree(slip_ctrls);
                slip_ctrls = NULL;
        }
-       if ((i = tty_register_ldisc(N_SLIP, NULL)))  
+       if ((i = tty_register_ldisc(N_SLIP, NULL)))
        {
                printk("SLIP: can't unregister line discipline (err = %d)\n", i);
        }
@@ -1227,7 +1229,7 @@ cleanup_module(void)
  * This is start of the code for multislip style line checking
  * added by Stanislav Voronyi. All changes before marked VSV
  */
+
 static void sl_outfill(unsigned long sls)
 {
        struct slip *sl=(struct slip *)sls;
@@ -1247,7 +1249,7 @@ static void sl_outfill(unsigned long sls)
 #endif
                        /* put END into tty queue. Is it right ??? */
                        if (!test_bit(0, (void *) &sl->dev->tbusy))
-                       { 
+                       {
                                /* if device busy no outfill */
                                sl->tty->driver.write(sl->tty, 0, &s, 1);
                        }
index e0bae0d4a1639fecb60bd47d93582ee298b54050..b2721cfa99abf931ec8cf2fab90d1bd7723075b6 100644 (file)
@@ -1,7 +1,7 @@
 /* smc-ultra.c: A SMC Ultra ethernet driver for linux. */
 /*
     Most of this driver, except for ultramca_probe is nearly
-    verbatim from smc-ultra.c by Donald Becker. The rest is 
+    verbatim from smc-ultra.c by Donald Becker. The rest is
     written and copyright 1996 by David Weis, weisd3458@uni.edu
 
     This is a driver for the SMC Ultra and SMC EtherEZ ethercards.
@@ -46,10 +46,10 @@ int ultramca_probe(struct device *dev);
 static int ultramca_open(struct device *dev);
 static void ultramca_reset_8390(struct device *dev);
 static void ultramca_get_8390_hdr(struct device *dev,
-                                  struct e8390_pkt_hdr *hdr, 
+                                  struct e8390_pkt_hdr *hdr,
                                   int ring_page);
 static void ultramca_block_input(struct device *dev, int count,
-                                 struct sk_buff *skb, 
+                                 struct sk_buff *skb,
                                  int ring_offset);
 static void ultramca_block_output(struct device *dev, int count,
                                   const unsigned char *buf,
@@ -74,18 +74,18 @@ int ultramca_probe(struct device *dev)
        unsigned char pos2, pos3, pos4, pos5;
        int i;
 
-       if( (slot=mca_find_adapter(0x61c8,0)) != MCA_NOTFOUND) 
+       if( (slot=mca_find_adapter(0x61c8,0)) != MCA_NOTFOUND)
        {
 #ifndef MODULE
                mca_set_adapter_name( slot, "SMC Elite/A (8013EP/A)" );
 #endif
-       } 
-       else if( (slot=mca_find_adapter(0x61c9,0)) != MCA_NOTFOUND) 
+       }
+       else if( (slot=mca_find_adapter(0x61c9,0)) != MCA_NOTFOUND)
        {
 #ifndef MODULE
                mca_set_adapter_name( slot, "SMC Elite10T/A (8013WP/A)" );
 #endif
-       } 
+       }
        else
                return -ENODEV;
 
@@ -99,9 +99,9 @@ int ultramca_probe(struct device *dev)
 
        dev->mem_start = 0;
        num_pages = 40;
-       for (i = 0; i < 15; i++) 
+       for (i = 0; i < 15; i++)
        {
-               if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) 
+               if (mem_table[i].mem_index == (pos3 & ~MEM_MASK))
                {
                        dev->mem_start = mem_table[i].mem_start;
                        num_pages = mem_table[i].num_pages;
@@ -121,42 +121,42 @@ int ultramca_probe(struct device *dev)
 
        /*
         *      Switch from the station address to the alternate register set and
-        *      read the useful registers there. 
+        *      read the useful registers there.
         */
 
        outb(0x80 | reg4, ioaddr + 4);
 
        /*
-        *      Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. 
+        *      Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot.
         */
 
        outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
-  
+
        /*
         *      Switch back to the station address register set so that the MS-DOS driver
-        *      can find the card after a warm boot. 
+        *      can find the card after a warm boot.
         */
 
        outb(reg4, ioaddr + 4);
 
        /*
-        *      Allocate dev->priv and fill in 8390 specific dev fields. 
+        *      Allocate dev->priv and fill in 8390 specific dev fields.
         */
 
-       if (ethdev_init(dev)) 
+       if (ethdev_init(dev))
        {
                printk (", no memory for dev->priv.\n");
                return -ENOMEM;
        }
+
        /*
-        *      OK, we are certain this is going to work.  Setup the device. 
+        *      OK, we are certain this is going to work.  Setup the device.
         */
 
        request_region(ioaddr, ULTRA_IO_EXTENT, "smc-mca");
 
        /*
-        *      The 8390 isn't at the base address, so fake the offset 
+        *      The 8390 isn't at the base address, so fake the offset
         */
 
        dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
@@ -168,7 +168,7 @@ int ultramca_probe(struct device *dev)
        ei_status.stop_page = num_pages;
 
        dev->rmem_start = dev->mem_start + TX_PAGES*256;
-       dev->mem_end = dev->rmem_end = 
+       dev->mem_end = dev->rmem_end =
        dev->mem_start + (ei_status.stop_page - START_PG)*256;
 
        printk(", IRQ %d memory %#lx-%#lx.\n", dev->irq, dev->mem_start, dev->mem_end-1);
@@ -198,7 +198,7 @@ static int ultramca_open(struct device *dev)
 
        /*
         *      Set the early receive warning level in window 0 high enough not
-        *      to receive ERW interrupts. 
+        *      to receive ERW interrupts.
         */
 
        /*
@@ -250,7 +250,7 @@ static void ultramca_block_input(struct device *dev, int count, struct sk_buff *
 {
        unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8);
 
-       if (xfer_start + count > dev->rmem_end) 
+       if (xfer_start + count > dev->rmem_end)
        {
                /* We must wrap the input move. */
                int semi_count = dev->rmem_end - xfer_start;
@@ -305,7 +305,7 @@ static int ultramca_close_card(struct device *dev)
 #define NAMELEN     8   /* # of chars for storing dev->name */
 static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, };
 
-static struct device dev_ultra[MAX_ULTRA_CARDS] = 
+static struct device dev_ultra[MAX_ULTRA_CARDS] =
 {
        {
                NULL,       /* assign a chunk of namelist[] below */
@@ -318,6 +318,9 @@ static struct device dev_ultra[MAX_ULTRA_CARDS] =
 static int io[MAX_ULTRA_CARDS] = { 0, };
 static int irq[MAX_ULTRA_CARDS]  = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRA_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 
@@ -325,23 +328,23 @@ int init_module(void)
 {
        int this_dev, found = 0;
 
-       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) 
+       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++)
        {
                struct device *dev = &dev_ultra[this_dev];
                dev->name = namelist+(NAMELEN*this_dev);
                dev->irq = irq[this_dev];
                dev->base_addr = io[this_dev];
                dev->init = ultra_probe;
-               if (io[this_dev] == 0)  
-               {       
-                       if (this_dev != 0) 
+               if (io[this_dev] == 0)
+               {
+                       if (this_dev != 0)
                                break; /* only autoprobe 1st one */
                        printk(KERN_NOTICE "smc-mca.c: Presently autoprobing (not recommended) for a single card.\n");
                }
-               if (register_netdev(dev) != 0) 
+               if (register_netdev(dev) != 0)
                {
                        printk(KERN_WARNING "smc-mca.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
-                       if (found != 0) 
+                       if (found != 0)
                                return 0;   /* Got at least one. */
                        return -ENXIO;
                }
@@ -354,10 +357,10 @@ void cleanup_module(void)
 {
        int this_dev;
 
-       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) 
+       for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++)
        {
                struct device *dev = &dev_ultra[this_dev];
-               if (dev->priv != NULL) 
+               if (dev->priv != NULL)
                {
                        /* NB: ultra_close_card() does free_irq + irq2dev */
                        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
index 5b3968580303d2ce65f94344b2ae711f9143de62..72dff7ec05ef9fcae4c3e0985087a4f99e90cf54 100644 (file)
@@ -19,7 +19,7 @@
        8390.c.  The code in this file is responsible for
 
                ultra_probe()           Detecting and initializing the card.
-               ultra_probe1()  
+               ultra_probe1()
 
                ultra_open()            The card-specific details of starting, stopping
                ultra_reset_8390()      and resetting the 8390 NIC core.
@@ -69,13 +69,13 @@ int ultra_probe1(struct device *dev, int ioaddr);
 
 static int ultra_open(struct device *dev);
 static void ultra_reset_8390(struct device *dev);
-static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
                                                int ring_page);
 static void ultra_block_input(struct device *dev, int count,
                                                  struct sk_buff *skb, int ring_offset);
 static void ultra_block_output(struct device *dev, int count,
                                                        const unsigned char *buf, const start_page);
-static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
                                                int ring_page);
 static void ultra_pio_input(struct device *dev, int count,
                                                  struct sk_buff *skb, int ring_offset);
@@ -201,7 +201,7 @@ int ultra_probe1(struct device *dev, int ioaddr)
                printk (", no memory for dev->priv.\n");
                 return -ENOMEM;
         }
+
        /* OK, we are certain this is going to work.  Setup the device. */
        request_region(ioaddr, ULTRA_IO_EXTENT, model_name);
 
@@ -357,7 +357,7 @@ ultra_block_output(struct device *dev, int count, const unsigned char *buf,
    must be always be rewritten between each read/write direction change.
    This is no problem for us, as the 8390 code ensures that we are single
    threaded. */
-static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, 
+static void ultra_pio_get_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
                                                int ring_page)
 {
        int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
@@ -434,6 +434,9 @@ static struct device dev_ultra[MAX_ULTRA_CARDS] = {
 static int io[MAX_ULTRA_CARDS] = { 0, };
 static int irq[MAX_ULTRA_CARDS]  = { 0, };
 
+MODULE_PARM(io, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_PARM(MAX_ULTRA_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
index dac1b98313245c98c0592af3099c1386ebd7d972..be393398f82441d631af4acdfcd034a5b2bcccd0 100644 (file)
@@ -1,24 +1,24 @@
 /*------------------------------------------------------------------------
  . smc9194.c
- . This is a driver for SMC's 9000 series of Ethernet cards. 
+ . This is a driver for SMC's 9000 series of Ethernet cards.
  .
  . Copyright (C) 1996 by Erik Stahlman
  . This software may be used and distributed according to the terms
  . of the GNU Public License, incorporated herein by reference.
  .
- . "Features" of the SMC chip:  
- .   4608 byte packet memory. ( for the 91C92.  Others have more ) 
+ . "Features" of the SMC chip:
+ .   4608 byte packet memory. ( for the 91C92.  Others have more )
  .   EEPROM for configuration
  .   AUI/TP selection  ( mine has 10Base2/10BaseT select )
  .
  . Arguments:
  .     io               = for the base address
- .     irq      = for the IRQ 
- .     ifport = 0 for autodetect, 1 for TP, 2 for AUI ( or 10base2 )   
+ .     irq      = for the IRQ
+ .     ifport = 0 for autodetect, 1 for TP, 2 for AUI ( or 10base2 )
  .
- . author:  
+ . author:
  .     Erik Stahlman                           ( erik@vt.edu )
- .   
+ .
  . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
  .
  . Sources:
  .    o   ( a LOT of advice from Becker as well )
  .
  . History:
- .     12/07/95  Erik Stahlman  written, got receive/xmit handled 
+ .     12/07/95  Erik Stahlman  written, got receive/xmit handled
  .     01/03/96  Erik Stahlman  worked out some bugs, actually usable!!! :-)
- .     01/06/96  Erik Stahlman  cleaned up some, better testing, etc 
+ .     01/06/96  Erik Stahlman  cleaned up some, better testing, etc
  .     01/29/96  Erik Stahlman  fixed autoirq, added multicast
  .     02/01/96  Erik Stahlman  1. disabled all interrupts in smc_reset
- .                              2. got rid of post-decrementing bug -- UGH.  
+ .                              2. got rid of post-decrementing bug -- UGH.
  .     02/13/96  Erik Stahlman  Tried to fix autoirq failure.  Added more
  .                              descriptive error messages.
  .     02/15/96  Erik Stahlman  Fixed typo that caused detection failure
- .     02/23/96  Erik Stahlman  Modified it to fit into kernel tree  
+ .     02/23/96  Erik Stahlman  Modified it to fit into kernel tree
  .                              Added support to change hardware address
  .                              Cleared stats on opens
  .     02/26/96  Erik Stahlman  Trial support for Kernel 1.2.13
  .                              Kludge for automatic IRQ detection
- .     03/04/96  Erik Stahlman  Fixed kernel 1.3.70 + 
- .                              Fixed bug reported by Gardner Buchanan in 
+ .     03/04/96  Erik Stahlman  Fixed kernel 1.3.70 +
+ .                              Fixed bug reported by Gardner Buchanan in
  .                                smc_enable, with outw instead of outb
  .     03/06/96  Erik Stahlman  Added hardware multicast from Peter Cammaert
  ----------------------------------------------------------------------------*/
 
 static const char *version =
-       "smc9194.c:v0.12 03/06/96 by Erik Stahlman (erik@vt.edu)\n";  
+       "smc9194.c:v0.12 03/06/96 by Erik Stahlman (erik@vt.edu)\n";
 
 #ifdef MODULE
 #include <linux/module.h>
 #include <linux/version.h>
-#endif 
+#endif
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -76,52 +76,52 @@ static const char *version =
 
 #include "smc9194.h"
 /*------------------------------------------------------------------------
- .  
- . Configuration options, for the experienced user to change. 
+ .
+ . Configuration options, for the experienced user to change.
  .
  -------------------------------------------------------------------------*/
 
-/* 
- . this is for kernels > 1.2.70 
+/*
+ . this is for kernels > 1.2.70
 */
-#define REALLY_NEW_KERNEL 
+#define REALLY_NEW_KERNEL
 #ifndef REALLY_NEW_KERNEL
 #define free_irq( x, y ) free_irq( x )
 #define request_irq( x, y, z, u, v ) request_irq( x, y, z, u )
 #endif
 
 /*
- . Do you want to use this with old kernels.  
- . WARNING: this is not well tested.  
+ . Do you want to use this with old kernels.
+ . WARNING: this is not well tested.
 #define SUPPORT_OLD_KERNEL
 */
 
 
 /*
  . Do you want to use 32 bit xfers?  This should work on all chips, as
- . the chipset is designed to accommodate them.   
+ . the chipset is designed to accommodate them.
 */
 #define USE_32_BIT 1
 
-/* 
+/*
  .the SMC9194 can be at any of the following port addresses.  To change,
- .for a slightly different card, you can add it to the array.  Keep in 
+ .for a slightly different card, you can add it to the array.  Keep in
  .mind that the array must end in zero.
 */
 static unsigned int smc_portlist[] =
    { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
          0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0};
 
-/* 
- . Wait time for memory to be free.  This probably shouldn't be 
- . tuned that much, as waiting for this means nothing else happens 
- . in the system 
+/*
+ . Wait time for memory to be free.  This probably shouldn't be
+ . tuned that much, as waiting for this means nothing else happens
+ . in the system
 */
 #define MEMORY_WAIT_TIME 16
 
 /*
  . DEBUGGING LEVELS
- . 
+ .
  . 0 for normal operation
  . 1 for slightly more details
  . >2 for various levels of increasingly useless information
@@ -131,13 +131,13 @@ static unsigned int smc_portlist[] =
 #define SMC_DEBUG 0
 
 #if (SMC_DEBUG > 2 )
-#define PRINTK3(x) printk x 
-#else 
-#define PRINTK3(x) 
+#define PRINTK3(x) printk x
+#else
+#define PRINTK3(x)
 #endif
 
-#if SMC_DEBUG > 1 
-#define PRINTK2(x) printk x 
+#if SMC_DEBUG > 1
+#define PRINTK2(x) printk x
 #else
 #define PRINTK2(x)
 #endif
@@ -146,7 +146,7 @@ static unsigned int smc_portlist[] =
 #define PRINTK(x) printk x
 #else
 #define PRINTK(x)
-#endif 
+#endif
 
 
 /* the older versions of the kernel cannot support autoprobing */
@@ -157,30 +157,30 @@ static unsigned int smc_portlist[] =
 
 /*------------------------------------------------------------------------
  .
- . The internal workings of the driver.  If you are changing anything 
- . here with the SMC stuff, you should have the datasheet and known 
- . what you are doing.  
- .  
+ . The internal workings of the driver.  If you are changing anything
+ . here with the SMC stuff, you should have the datasheet and known
+ . what you are doing.
+ .
  -------------------------------------------------------------------------*/
 #define CARDNAME "SMC9194"
 
 #ifdef SUPPORT_OLD_KERNEL
 char kernel_version[] = UTS_RELEASE;
-#endif 
+#endif
 
-/* store this information for the driver.. */ 
+/* store this information for the driver.. */
 struct smc_local {
        /*
           these are things that the kernel wants me to keep, so users
           can find out semi-useless statistics of how well the card is
-          performing 
+          performing
        */
        struct enet_statistics stats;
-       
-       /* 
+
+       /*
           If I have to wait until memory is available to send
           a packet, I will store the skbuff here, until I get the
-          desired memory.  Then, I'll send it out and free it.    
+          desired memory.  Then, I'll send it out and free it.
        */
        struct sk_buff * saved_skb;
 
@@ -196,14 +196,14 @@ struct smc_local {
 /*-----------------------------------------------------------------
  .
  .  The driver can be entered at any of the following entry points.
- . 
+ .
  .------------------------------------------------------------------  */
 
 /*
- . This is called by  register_netdev().  It is responsible for 
- . checking the portlist for the SMC9000 series chipset.  If it finds 
+ . This is called by  register_netdev().  It is responsible for
+ . checking the portlist for the SMC9000 series chipset.  If it finds
  . one, then it will initialize the device, find the hardware information,
- . and sets up the appropriate device parameters.   
+ . and sets up the appropriate device parameters.
  . NOTE: Interrupts are *OFF* when this procedure is called.
  .
  . NB:This shouldn't be static since it is referred to externally.
@@ -212,32 +212,32 @@ int smc_init(struct device *dev);
 
 /*
  . The kernel calls this function when someone wants to use the device,
- . typically 'ifconfig ethX up'.   
+ . typically 'ifconfig ethX up'.
 */
 static int smc_open(struct device *dev);
 
 /*
  . This is called by the kernel to send a packet out into the net.  it's
  . responsible for doing a best-effort send, but if it's simply not possible
- . to send it, the packet gets dropped. 
-*/  
+ . to send it, the packet gets dropped.
+*/
 static int smc_send_packet(struct sk_buff *skb, struct device *dev);
 
-/* 
+/*
  . This is called by the kernel in response to 'ifconfig ethX down'.  It
- . is responsible for cleaning up everything that the open routine 
- . does, and maybe putting the card into a powerdown state. 
+ . is responsible for cleaning up everything that the open routine
+ . does, and maybe putting the card into a powerdown state.
 */
 static int smc_close(struct device *dev);
 
 /*
- . This routine allows the proc file system to query the driver's 
- . statistics.  
+ . This routine allows the proc file system to query the driver's
+ . statistics.
 */
 static struct enet_statistics * smc_query_statistics( struct device *dev);
 
 /*
- . Finally, a call to set promiscuous mode ( for TCPDUMP and related 
+ . Finally, a call to set promiscuous mode ( for TCPDUMP and related
  . programs ) and multicast modes.
 */
 #ifdef SUPPORT_OLD_KERNEL
@@ -245,43 +245,43 @@ static void smc_set_multicast_list(struct device *dev, int num_addrs,
                                 void *addrs);
 #else
 static void smc_set_multicast_list(struct device *dev);
-#endif 
+#endif
 
 /*---------------------------------------------------------------
- . 
- . Interrupt level calls.. 
+ .
+ . Interrupt level calls..
  .
  ----------------------------------------------------------------*/
 
 /*
- . Handles the actual interrupt 
+ . Handles the actual interrupt
 */
 #ifdef REALLY_NEW_KERNEL
 static void smc_interrupt(int irq, void *, struct pt_regs *regs);
 #else
 static void smc_interrupt(int irq, struct pt_regs *regs);
-#endif 
+#endif
 /*
  . This is a separate procedure to handle the receipt of a packet, to
- . leave the interrupt code looking slightly cleaner 
-*/ 
+ . leave the interrupt code looking slightly cleaner
+*/
 inline static void smc_rcv( struct device *dev );
 /*
  . This handles a TX interrupt, which is only called when an error
- . relating to a packet is sent.  
+ . relating to a packet is sent.
 */
 inline static void smc_tx( struct device * dev );
 
 /*
  ------------------------------------------------------------
- . 
+ .
  . Internal routines
  .
  ------------------------------------------------------------
 */
 
 /*
- . Test if a given location contains a chip, trying to cause as 
+ . Test if a given location contains a chip, trying to cause as
  . little damage as possible if it's not a SMC chip.
 */
 static int smc_probe( int ioaddr );
@@ -289,26 +289,26 @@ static int smc_probe( int ioaddr );
 /*
  . this routine initializes the cards hardware, prints out the configuration
  . to the system log as well as the vanity message, and handles the setup
- . of a device parameter. 
+ . of a device parameter.
  . It will give an error if it can't initialize the card.
 */
-static int smc_initcard( struct device *, int ioaddr ); 
+static int smc_initcard( struct device *, int ioaddr );
 
 /*
  . A rather simple routine to print out a packet for debugging purposes.
-*/ 
-#if SMC_DEBUG > 2 
+*/
+#if SMC_DEBUG > 2
 static void print_packet( byte *, int );
-#endif  
+#endif
 
 #define tx_done(dev) 1
 
-/* this is called to actually send the packet to the chip */ 
+/* this is called to actually send the packet to the chip */
 static void smc_hardware_send_packet( struct device * dev );
 
 /* Since I am not sure if I will have enough room in the chip's ram
- . to store the packet, I call this routine, which either sends it 
- . now, or generates an interrupt when the card is ready for the 
+ . to store the packet, I call this routine, which either sends it
+ . now, or generates an interrupt when the card is ready for the
  . packet */
 static int  smc_wait_to_send_packet( struct sk_buff * skb, struct device *dev );
 
@@ -328,7 +328,7 @@ static int smc_findirq( int ioaddr );
 #endif
 
 /*
-  this routine will set the hardware multicast table to the specified 
+  this routine will set the hardware multicast table to the specified
   values given it by the higher level routines
 */
 #ifndef SUPPORT_OLD_KERNEL
@@ -339,66 +339,66 @@ static int crc32( char *, int );
 #ifdef SUPPORT_OLD_KERNEL
 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
                        unsigned long *mem_startp );
-#endif 
+#endif
 
 /*
  . Function: smc_reset( int ioaddr )
  . Purpose:
  .     This sets the SMC91xx chip to its normal state, hopefully from whatever
- .     mess that any other DOS driver has put it in.   
- . 
+ .     mess that any other DOS driver has put it in.
+ .
  . Maybe I should reset more registers to defaults in here?  SOFTRESET  should
- . do that for me.  
- . 
+ . do that for me.
+ .
  . Method:
- .     1.  send a SOFT RESET 
+ .     1.  send a SOFT RESET
  .     2.  wait for it to finish
  .     3.  enable autorelease mode
  .     4.  reset the memory management unit
  .     5.  clear all interrupts
  .
-*/  
-static void smc_reset( int ioaddr ) 
-{ 
+*/
+static void smc_reset( int ioaddr )
+{
        /* This resets the registers mostly to defaults, but doesn't
           affect EEPROM.  That seems unnecessary */
        SMC_SELECT_BANK( 0 );
-       outw( RCR_SOFTRESET, ioaddr + RCR ); 
-       
+       outw( RCR_SOFTRESET, ioaddr + RCR );
+
        /* this should pause enough for the chip to be happy */
        SMC_DELAY( );
 
-       /* Set the transmit and receive configuration registers to 
+       /* Set the transmit and receive configuration registers to
           default values */
        outw( RCR_CLEAR, ioaddr + RCR );
        outw( TCR_CLEAR, ioaddr + TCR );
 
        /* set the control register to automatically
-          release successfully transmitted packets, to make the best 
+          release successfully transmitted packets, to make the best
           use out of our limited memory */
        SMC_SELECT_BANK( 1 );
-       outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );  
+       outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );
 
        /* Reset the MMU */
        SMC_SELECT_BANK( 2 );
        outw( MC_RESET, ioaddr + MMU_CMD );
 
-       /* Note:  It doesn't seem that waiting for the MMU busy is needed here, 
+       /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
           but this is a place where future chipsets _COULD_ break.  Be wary
           of issuing another MMU command right after this */
 
        outb( 0, ioaddr + INT_MASK );
 }
 
-/* 
+/*
  . Function: smc_enable
  . Purpose: let the chip talk to the outside work
- . Method: 
+ . Method:
  .     1.  Enable the transmitter
  .     2.  Enable the receiver
  .     3.  Enable interrupts
 */
-static void smc_enable( int ioaddr ) 
+static void smc_enable( int ioaddr )
 {
        SMC_SELECT_BANK( 0 );
        /* see the header file for options in TCR/RCR NORMAL*/
@@ -408,23 +408,23 @@ static void smc_enable( int ioaddr )
        /* now, enable interrupts */
        SMC_SELECT_BANK( 2 );
        outb( SMC_INTERRUPT_MASK, ioaddr + INT_MASK );
-}      
-       
+}
+
 /*
  . Function: smc_shutdown
  . Purpose:  closes down the SMC91xxx chip.
- . Method:   
+ . Method:
  .     1. zero the interrupt mask
  .     2. clear the enable receive flag
  .     3. clear the enable xmit flags
  .
- . TODO: 
+ . TODO:
  .   (1) maybe utilize power down mode.
  .     Why not yet?  Because while the chip will go into power down mode,
  .     the manual says that it will wake up in response to any I/O requests
  .     in the register space.   Empirical results do not show this working.
 */
-static void smc_shutdown( int ioaddr ) 
+static void smc_shutdown( int ioaddr )
 {
        /* no more interrupts for me */
        SMC_SELECT_BANK( 2 );
@@ -434,30 +434,30 @@ static void smc_shutdown( int ioaddr )
        SMC_SELECT_BANK( 0 );
        outb( RCR_CLEAR, ioaddr + RCR );
        outb( TCR_CLEAR, ioaddr + TCR );
-#if 0 
+#if 0
        /* finally, shut the chip down */
-       SMC_SELECT_BANK( 1 ); 
+       SMC_SELECT_BANK( 1 );
        outw( inw( ioaddr + CONTROL ), CTL_POWERDOWN, ioaddr + CONTROL  );
-#endif 
+#endif
 }
 
 
-#ifndef SUPPORT_OLD_KERNEL 
-/* 
+#ifndef SUPPORT_OLD_KERNEL
+/*
  . Function: smc_setmulticast( int ioaddr, int count, dev_mc_list * adds )
  . Purpose:
  .    This sets the internal hardware table to filter out unwanted multicast
- .    packets before they take up memory.  
- .    
+ .    packets before they take up memory.
+ .
  .    The SMC chip uses a hash table where the high 6 bits of the CRC of
- .    address are the offset into the table.  If that bit is 1, then the 
+ .    address are the offset into the table.  If that bit is 1, then the
  .    multicast packet is accepted.  Otherwise, it's dropped silently.
- .  
+ .
  .    To use the 6 bits as an offset into the table, the high 3 bits are the
  .    number of the 8 bit register, while the low 3 bits are the bit within
  .    that register.
  .
- . This routine is based very heavily on the one provided by Peter Cammaert. 
+ . This routine is based very heavily on the one provided by Peter Cammaert.
 */
 
 
@@ -465,35 +465,35 @@ static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs
        int                     i;
        unsigned char           multicast_table[ 8 ];
        struct dev_mc_list      * cur_addr;
-       /* table for flipping the order of 3 bits */  
+       /* table for flipping the order of 3 bits */
        unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
-       /* start with a table of all zeros: reject all */       
+       /* start with a table of all zeros: reject all */
        memset( multicast_table, 0, sizeof( multicast_table ) );
 
        cur_addr = addrs;
        for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next  ) {
                int position;
-               
+
                /* do we have a pointer here? */
-               if ( !cur_addr ) 
+               if ( !cur_addr )
                        break;
                /* make sure this is a multicast address - shouldn't this
-                  be a given if we have it here ? */   
-               if ( !( *cur_addr->dmi_addr & 1 ) )     
-                       continue;       
+                  be a given if we have it here ? */
+               if ( !( *cur_addr->dmi_addr & 1 ) )
+                       continue;
 
-               /* only use the low order bits */       
+               /* only use the low order bits */
                position = crc32( cur_addr->dmi_addr, 6 ) & 0x3f;
-                               
+
                /* do some messy swapping to put the bit in the right spot */
-               multicast_table[invert3[position&7]] |= 
+               multicast_table[invert3[position&7]] |=
                                        (1<<invert3[(position>>3)&7]);
 
        }
        /* now, the table can be loaded into the chipset */
        SMC_SELECT_BANK( 3 );
-       
+
        for ( i = 0; i < 8 ; i++ ) {
                outb( multicast_table[i], ioaddr + MULTICAST1 + i );
        }
@@ -501,20 +501,20 @@ static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs
 
 /*
   Finds the CRC32 of a set of bytes.
-  Again, from Peter Cammaert's code. 
+  Again, from Peter Cammaert's code.
 */
-static int crc32( char * s, int length ) { 
+static int crc32( char * s, int length ) {
        /* indices */
        int perByte;
        int perBit;
        /* crc polynomial for Ethernet */
        const unsigned long poly = 0xedb88320;
        /* crc value - preinitialized to all 1's */
-       unsigned long crc_value = 0xffffffff; 
+       unsigned long crc_value = 0xffffffff;
 
        for ( perByte = 0; perByte < length; perByte ++ ) {
                unsigned char   c;
-       
+
                c = *(s++);
                for ( perBit = 0; perBit < 8; perBit++ ) {
                        crc_value = (crc_value>>1)^
@@ -523,16 +523,16 @@ static int crc32( char * s, int length ) {
                }
        }
        return  crc_value;
-} 
+}
 
-#endif 
+#endif
 
 
-/* 
- . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * ) 
- . Purpose: 
+/*
+ . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct device * )
+ . Purpose:
  .    Attempt to allocate memory for a packet, if chip-memory is not
- .    available, then tell the card to generate an interrupt when it 
+ .    available, then tell the card to generate an interrupt when it
  .    is available.
  .
  . Algorithm:
@@ -540,18 +540,18 @@ static int crc32( char * s, int length ) {
  . o   if the saved_skb is not currently null, then drop this packet
  .     on the floor.  This should never happen, because of TBUSY.
  . o   if the saved_skb is null, then replace it with the current packet,
- . o   See if I can sending it now. 
+ . o   See if I can sending it now.
  . o   (NO): Enable interrupts and let the interrupt handler deal with it.
  . o   (YES):Send it now.
 */
 static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev )
-{ 
+{
        struct smc_local *lp    = (struct smc_local *)dev->priv;
        unsigned short ioaddr   = dev->base_addr;
        word                    length;
        unsigned short          numPages;
-       word                    time_out;       
-       
+       word                    time_out;
+
        if ( lp->saved_skb) {
                /* THIS SHOULD NEVER HAPPEN. */
                lp->stats.tx_aborted_errors++;
@@ -561,54 +561,54 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev )
        lp->saved_skb = skb;
 
        length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-               
+
        /*
-       . the MMU wants the number of pages to be the number of 256 bytes 
-       . 'pages', minus 1 ( since a packet can't ever have 0 pages :) ) 
+       . the MMU wants the number of pages to be the number of 256 bytes
+       . 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
        */
        numPages = length / 256;
 
        if (numPages > 7 ) {
                printk(CARDNAME": Far too big packet error. \n");
-               /* freeing the packet is a good thing here... but should                
+               /* freeing the packet is a good thing here... but should
                 . any packets of this size get down here?   */
                dev_kfree_skb (skb, FREE_WRITE);
                lp->saved_skb = NULL;
                /* this IS an error, but, i don't want the skb saved */
-               return 0; 
+               return 0;
        }
        /* either way, a packet is waiting now */
        lp->packets_waiting++;
-        
+
        /* now, try to allocate the memory */
        SMC_SELECT_BANK( 2 );
        outw( MC_ALLOC | numPages, ioaddr + MMU_CMD );
        /*
        . Performance Hack
-       .  
+       .
        . wait a short amount of time.. if I can send a packet now, I send
        . it now.  Otherwise, I enable an interrupt and wait for one to be
-       . available. 
+       . available.
        .
        . I could have handled this a slightly different way, by checking to
        . see if any memory was available in the FREE MEMORY register.  However,
        . either way, I need to generate an allocation, and the allocation works
-       . no matter what, so I saw no point in checking free memory.   
-       */ 
+       . no matter what, so I saw no point in checking free memory.
+       */
        time_out = MEMORY_WAIT_TIME;
-       do { 
+       do {
                word    status;
 
                status = inb( ioaddr + INTERRUPT );
-               if ( status & IM_ALLOC_INT ) { 
+               if ( status & IM_ALLOC_INT ) {
                        /* acknowledge the interrupt */
                        outb( IM_ALLOC_INT, ioaddr + INTERRUPT );
-                       break;  
+                       break;
                }
        } while ( -- time_out );
 
        if ( !time_out ) {
-               /* oh well, wait until the chip finds memory later */ 
+               /* oh well, wait until the chip finds memory later */
                SMC_ENABLE_INT( IM_ALLOC_INT );
                PRINTK2((CARDNAME": memory allocation deferred. \n"));
                /* it's deferred, but I'll handle it later */
@@ -616,38 +616,38 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct device * dev )
        }
        /* or YES! I can send the packet now.. */
        smc_hardware_send_packet(dev);
-       
+
        return 0;
-}      
+}
 
 /*
  . Function:  smc_hardware_send_packet(struct device * )
- . Purpose:    
- .     This sends the actual packet to the SMC9xxx chip.   
- . 
+ . Purpose:
+ .     This sends the actual packet to the SMC9xxx chip.
+ .
  . Algorithm:
- .     First, see if a saved_skb is available.    
+ .     First, see if a saved_skb is available.
  .             ( this should NOT be called if there is no 'saved_skb'
  .     Now, find the packet number that the chip allocated
- .     Point the data pointers at it in memory 
+ .     Point the data pointers at it in memory
  .     Set the length word in the chip's memory
  .     Dump the packet to chip memory
  .     Check if a last byte is needed ( odd length packet )
- .             if so, set the control flag right 
- .     Tell the card to send it 
+ .             if so, set the control flag right
+ .     Tell the card to send it
  .     Enable the transmit interrupt, so I know if it failed
  .     Free the kernel data if I actually sent it.
 */
-static void smc_hardware_send_packet( struct device * dev ) 
+static void smc_hardware_send_packet( struct device * dev )
 {
        struct smc_local *lp = (struct smc_local *)dev->priv;
        byte                    packet_no;
        struct sk_buff *        skb = lp->saved_skb;
-       word                    length; 
+       word                    length;
        unsigned short          ioaddr;
        byte                    * buf;
 
-       ioaddr = dev->base_addr;        
+       ioaddr = dev->base_addr;
 
        if ( !skb ) {
                PRINTK((CARDNAME": In XMIT with no packet to send \n"));
@@ -657,8 +657,8 @@ static void smc_hardware_send_packet( struct device * dev )
        buf = skb->data;
 
        /* If I get here, I _know_ there is a packet slot waiting for me */
-       packet_no = inb( ioaddr + PNR_ARR + 1 ); 
-       if ( packet_no & 0x80 ) { 
+       packet_no = inb( ioaddr + PNR_ARR + 1 );
+       if ( packet_no & 0x80 ) {
                /* or isn't there?  BAD CHIP! */
                printk(KERN_DEBUG CARDNAME": Memory allocation failed. \n");
                kfree(skb);
@@ -670,7 +670,7 @@ static void smc_hardware_send_packet( struct device * dev )
        /* we have a packet address, so tell the card to use it */
        outb( packet_no, ioaddr + PNR_ARR );
 
-       /* point to the beginning of the packet */      
+       /* point to the beginning of the packet */
        outw( PTR_AUTOINC , ioaddr + POINTER );
 
        PRINTK3((CARDNAME": Trying to xmit packet of length %x\n", length ));
@@ -678,36 +678,36 @@ static void smc_hardware_send_packet( struct device * dev )
        print_packet( buf, length );
 #endif
 
-       /* send the packet length ( +6 for status, length and ctl byte ) 
-          and the status word ( set to zeros ) */ 
+       /* send the packet length ( +6 for status, length and ctl byte )
+          and the status word ( set to zeros ) */
 #ifdef USE_32_BIT
        outl(  (length +6 ) << 16 , ioaddr + DATA_1 );
 #else
-       outw( 0, ioaddr + DATA_1 );      
-       /* send the packet length ( +6 for status words, length, and ctl*/              
+       outw( 0, ioaddr + DATA_1 );
+       /* send the packet length ( +6 for status words, length, and ctl*/
        outb( (length+6) & 0xFF,ioaddr + DATA_1 );
        outb( (length+6) >> 8 , ioaddr + DATA_1 );
-#endif 
+#endif
 
-       /* send the actual data 
-        . I _think_ it's faster to send the longs first, and then 
-        . mop up by sending the last word.  It depends heavily 
-        . on alignment, at least on the 486.  Maybe it would be 
+       /* send the actual data
+        . I _think_ it's faster to send the longs first, and then
+        . mop up by sending the last word.  It depends heavily
+        . on alignment, at least on the 486.  Maybe it would be
         . a good idea to check which is optimal?  But that could take
-        . almost as much time as is saved? 
-       */      
-#ifdef USE_32_BIT 
-       if ( length & 0x2  ) {  
-               outsl(ioaddr + DATA_1, buf,  length >> 2 ); 
+        . almost as much time as is saved?
+       */
+#ifdef USE_32_BIT
+       if ( length & 0x2  ) {
+               outsl(ioaddr + DATA_1, buf,  length >> 2 );
                outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1);
        }
        else
-               outsl(ioaddr + DATA_1, buf,  length >> 2 ); 
+               outsl(ioaddr + DATA_1, buf,  length >> 2 );
 #else
        outsw(ioaddr + DATA_1 , buf, (length ) >> 1);
 #endif
        /* Send the last byte, if there is one.   */
-       
+
        if ( (length & 1) == 0 ) {
                outw( 0, ioaddr + DATA_1 );
        } else {
@@ -721,7 +721,7 @@ static void smc_hardware_send_packet( struct device * dev )
        /* and let the chipset deal with it */
        outw( MC_ENQUEUE , ioaddr + MMU_CMD );
 
-       PRINTK2((CARDNAME": Sent packet of length %d \n",length)); 
+       PRINTK2((CARDNAME": Sent packet of length %d \n",length));
 
        lp->saved_skb = NULL;
        dev_kfree_skb (skb, FREE_WRITE);
@@ -737,38 +737,38 @@ static void smc_hardware_send_packet( struct device * dev )
 
 /*-------------------------------------------------------------------------
  |
- | smc_init( struct device * dev )  
- |   Input parameters: 
+ | smc_init( struct device * dev )
+ |   Input parameters:
  |     dev->base_addr == 0, try to find all possible locations
  |     dev->base_addr == 1, return failure code
  |     dev->base_addr == 2, always allocate space,  and return success
- |     dev->base_addr == <anything else>   this is the address to check 
+ |     dev->base_addr == <anything else>   this is the address to check
  |
- |   Output: 
+ |   Output:
  |     0 --> there is a device
- |     anything else, error 
- | 
+ |     anything else, error
+ |
  ---------------------------------------------------------------------------
-*/ 
+*/
 int smc_init(struct device *dev)
 {
        int i;
        int base_addr = dev ? dev->base_addr : 0;
 
        /*  try a specific location */
-       if (base_addr > 0x1ff)  {                
-               int     error; 
+       if (base_addr > 0x1ff)  {
+               int     error;
                error = smc_probe(base_addr);
                if ( 0 == error ) {
                        return smc_initcard( dev, base_addr );
                }
-               return error; 
+               return error;
        } else {
                if ( 0 != base_addr ) {
                        return -ENXIO;
                }
        }
-       
+
        /* check every ethernet address */
        for (i = 0; smc_portlist[i]; i++) {
                int ioaddr = smc_portlist[i];
@@ -778,8 +778,8 @@ int smc_init(struct device *dev)
                        continue;
 
                /* check this specific address */
-               if ( smc_probe( ioaddr ) == 0)  {  
-                       return smc_initcard( dev, ioaddr  ); 
+               if ( smc_probe( ioaddr ) == 0)  {
+                       return smc_initcard( dev, ioaddr  );
                }
        }
 
@@ -789,19 +789,19 @@ int smc_init(struct device *dev)
 
 #ifndef NO_AUTOPROBE
 /*----------------------------------------------------------------------
- . smc_findirq 
- . 
- . This routine has a simple purpose -- make the SMC chip generate an 
+ . smc_findirq
+ .
+ . This routine has a simple purpose -- make the SMC chip generate an
  . interrupt, so an auto-detect routine can detect it, and find the IRQ,
  ------------------------------------------------------------------------
 */
-int smc_findirq( int ioaddr ) 
+int smc_findirq( int ioaddr )
 {
        int     timeout = 20;
 
 
        /* I have to do a STI() here, because this is called from
-          a routine that does an CLI during this process, making it 
+          a routine that does an CLI during this process, making it
           rather difficult to get interrupts for auto detection */
        sti();
 
@@ -813,16 +813,16 @@ int smc_findirq( int ioaddr )
         * when done.
         */
 
-         
-       SMC_SELECT_BANK(2);     
+
+       SMC_SELECT_BANK(2);
        /* enable ALLOCation interrupts ONLY */
-       outb( IM_ALLOC_INT, ioaddr + INT_MASK );        
+       outb( IM_ALLOC_INT, ioaddr + INT_MASK );
 
        /*
-        . Allocate 512 bytes of memory.  Note that the chip was just 
+        . Allocate 512 bytes of memory.  Note that the chip was just
         . reset so all the memory is available
        */
-       outw( MC_ALLOC | 1, ioaddr + MMU_CMD );         
+       outw( MC_ALLOC | 1, ioaddr + MMU_CMD );
 
        /*
         . Wait until positive that the interrupt has been generated
@@ -832,7 +832,7 @@ int smc_findirq( int ioaddr )
 
                int_status = inb( ioaddr + INTERRUPT );
 
-               if ( int_status & IM_ALLOC_INT )        
+               if ( int_status & IM_ALLOC_INT )
                        break;          /* got the interrupt */
                timeout--;
        }
@@ -843,13 +843,13 @@ int smc_findirq( int ioaddr )
 
        /* DELAY HERE!
           On a fast machine, the status might change before the interrupt
-          is given to the processor.  This means that the interrupt was 
-          never detected, and autoirq_report fails to report anything.  
-          This should fix autoirq_* problems. 
+          is given to the processor.  This means that the interrupt was
+          never detected, and autoirq_report fails to report anything.
+          This should fix autoirq_* problems.
        */
        SMC_DELAY();
-       SMC_DELAY();            
-       
+       SMC_DELAY();
+
        /* and disable all interrupts again */
        outb( 0, ioaddr + INT_MASK );
 
@@ -858,29 +858,29 @@ int smc_findirq( int ioaddr )
        cli();
 
        /* and return what I found */
-       return autoirq_report( 0 );     
+       return autoirq_report( 0 );
 }
 #endif
+
 /*----------------------------------------------------------------------
  . Function: smc_probe( int ioaddr )
- . 
- . Purpose:  
+ .
+ . Purpose:
  .     Tests to see if a given ioaddr points to an SMC9xxx chip.
- .     Returns a 0 on success  
- . 
+ .     Returns a 0 on success
+ .
  . Algorithm:
  .     (1) see if the high byte of BANK_SELECT is 0x33
  .     (2) compare the ioaddr with the base register's address
  .     (3) see if I recognize the chip ID in the appropriate register
- . 
+ .
  .---------------------------------------------------------------------
- */ 
+ */
 
-static int smc_probe( int ioaddr ) 
+static int smc_probe( int ioaddr )
 {
        unsigned int    bank;
-       word    revision_register;      
+       word    revision_register;
        word  base_address_register;
 
        /* First, see if the high byte is 0x33 */
@@ -896,12 +896,12 @@ static int smc_probe( int ioaddr )
                return -ENODEV;
        }
        /* well, we've already written once, so hopefully another time won't
-          hurt.  This time, I need to switch the bank register to bank 1, 
+          hurt.  This time, I need to switch the bank register to bank 1,
           so I can access the base address register */
        SMC_SELECT_BANK(1);
        base_address_register = inw( ioaddr + BASE );
        if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )  {
-               printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)." 
+               printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)."
                        "Probably not a SMC chip\n",
                        ioaddr, base_address_register >> 3 & 0x3E0 );
                /* well, the base address register didn't match.  Must not have
@@ -909,12 +909,12 @@ static int smc_probe( int ioaddr )
                return -ENODEV;
        }
 
-       /*  check if the revision register is something that I recognize.  
-           These might need to be added to later, as future revisions 
+       /*  check if the revision register is something that I recognize.
+           These might need to be added to later, as future revisions
            could be added.  */
        SMC_SELECT_BANK(3);
        revision_register  = inw( ioaddr + REVISION );
-       if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] ) { 
+       if ( !chip_ids[ ( revision_register  >> 4 ) & 0xF  ] ) {
                /* I don't recognize this chip, so... */
                printk(CARDNAME ": IO %x: Unrecognized revision register:"
                        " %x, Contact author. \n", ioaddr, revision_register );
@@ -922,24 +922,24 @@ static int smc_probe( int ioaddr )
                return -ENODEV;
        }
 
-       /* at this point I'll assume that the chip is an SMC9xxx.   
-          It might be prudent to check a listing of MAC addresses 
-          against the hardware address, or do some other tests. */     
+       /* at this point I'll assume that the chip is an SMC9xxx.
+          It might be prudent to check a listing of MAC addresses
+          against the hardware address, or do some other tests. */
        return 0;
 }
 
 /*---------------------------------------------------------------
- . Here I do typical initialization tasks. 
- . 
+ . Here I do typical initialization tasks.
+ .
  . o  Initialize the structure if needed
  . o  print out my vanity message if not done so already
  . o  print out what type of hardware is detected
  . o  print out the ethernet address
- . o  find the IRQ 
- . o  set up my private data 
+ . o  find the IRQ
+ . o  set up my private data
  . o  configure the dev structure with my subroutines
  . o  actually GRAB the irq.
- . o  GRAB the region 
+ . o  GRAB the region
  .-----------------------------------------------------------------
 */
 static int  smc_initcard(struct device *dev, int ioaddr)
@@ -949,8 +949,8 @@ static int  smc_initcard(struct device *dev, int ioaddr)
        static unsigned version_printed = 0;
 
        /* registers */
-       word    revision_register;      
-       word    configuration_register; 
+       word    revision_register;
+       word    configuration_register;
        word    memory_info_register;
        word    memory_cfg_register;
 
@@ -966,10 +966,10 @@ static int  smc_initcard(struct device *dev, int ioaddr)
 #ifndef MODULE
 /* note: the old module interface does not support this call */
                dev = init_etherdev( 0, sizeof( struct smc_local ), 0 );
-#endif 
+#endif
 #else
                dev = init_etherdev(0, 0);
-#endif 
+#endif
                if (dev == NULL)
                        return -ENOMEM;
        }
@@ -984,12 +984,12 @@ static int  smc_initcard(struct device *dev, int ioaddr)
         . Get the MAC address ( bank 1, regs 4 - 9 )
        */
        SMC_SELECT_BANK( 1 );
-       for ( i = 0; i < 6; i += 2 ) { 
+       for ( i = 0; i < 6; i += 2 ) {
                word    address;
 
                address = inw( ioaddr + ADDR0 + i  );
                dev->dev_addr[ i + 1] = address >> 8;
-               dev->dev_addr[ i ] = address & 0xFF;    
+               dev->dev_addr[ i ] = address & 0xFF;
        }
 
        /* get the memory information */
@@ -1000,16 +1000,16 @@ static int  smc_initcard(struct device *dev, int ioaddr)
        memory = ( memory_cfg_register >> 9 )  & 0x7;  /* multiplier */
        memory *= 256 * ( memory_info_register & 0xFF );
 
-       /* 
+       /*
         Now, I want to find out more about the chip.  This is sort of
         redundant, but it's cleaner to have it in both, rather than having
         one VERY long probe procedure.
-       */      
+       */
        SMC_SELECT_BANK(3);
        revision_register  = inw( ioaddr + REVISION );
        version_string = chip_ids[ ( revision_register  >> 4 ) & 0xF  ];
        if ( !version_string ) {
-               /* I shouldn't get here because this call was done before.... */ 
+               /* I shouldn't get here because this call was done before.... */
                return -ENODEV;
        }
 
@@ -1017,7 +1017,7 @@ static int  smc_initcard(struct device *dev, int ioaddr)
        if ( dev->if_port == 0 ) {
                SMC_SELECT_BANK(1);
                configuration_register = inw( ioaddr + CONFIG );
-               if ( configuration_register & CFG_AUI_SELECT )  
+               if ( configuration_register & CFG_AUI_SELECT )
                        dev->if_port = 2;
                else
                        dev->if_port = 1;
@@ -1029,17 +1029,17 @@ static int  smc_initcard(struct device *dev, int ioaddr)
 
        /*
         . If dev->irq is 0, then the device has to be banged on to see
-        . what the IRQ is. 
-        . 
+        . what the IRQ is.
+        .
         . This banging doesn't always detect the IRQ, for unknown reasons.
-        . a workaround is to reset the chip and try again.  
-        .    
+        . a workaround is to reset the chip and try again.
+        .
         . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
         . be what is requested on the command line.   I don't do that, mostly
         . because the card that I have uses a non-standard method of accessing
         . the IRQs, and because this _should_ work in most configurations.
         .
-        . Specifying an IRQ is done with the assumption that the user knows 
+        . Specifying an IRQ is done with the assumption that the user knows
         . what (s)he is doing.  No checking is done!!!!
         .
        */
@@ -1048,14 +1048,14 @@ static int  smc_initcard(struct device *dev, int ioaddr)
                int     trials;
 
                trials = 3;
-               while ( trials-- ) { 
+               while ( trials-- ) {
                        dev->irq = smc_findirq( ioaddr );
-                       if ( dev->irq ) 
+                       if ( dev->irq )
                                break;
                        /* kick the card and try again */
                        smc_reset( ioaddr );
                }
-       } 
+       }
        if (dev->irq == 0 ) {
                printk(CARDNAME": Couldn't autodetect your IRQ. Use irq=xx.\n");
                return -ENODEV;
@@ -1075,12 +1075,12 @@ static int  smc_initcard(struct device *dev, int ioaddr)
        }
 
        /* now, print out the card info, in a short format.. */
-       
+
        printk(CARDNAME ": %s(r:%d) at %#3x IRQ:%d INTF:%s MEM:%db ",
-               version_string, revision_register & 0xF, ioaddr, dev->irq, 
+               version_string, revision_register & 0xF, ioaddr, dev->irq,
                if_string, memory );
        /*
-        . Print the Ethernet address 
+        . Print the Ethernet address
        */
        printk("ADDR: ");
        for (i = 0; i < 5; i++)
@@ -1124,21 +1124,21 @@ static int  smc_initcard(struct device *dev, int ioaddr)
 }
 
 #if SMC_DEBUG > 2
-static void print_packet( byte * buf, int length ) 
-{ 
+static void print_packet( byte * buf, int length )
+{
 #if 0
        int i;
        int remainder;
        int lines;
-       
+
        printk("Packet of length %d \n", length );
        lines = length / 16;
        remainder = length % 16;
 
-       for ( i = 0; i < lines ; i ++ ) { 
+       for ( i = 0; i < lines ; i ++ ) {
                int cur;
 
-               for ( cur = 0; cur < 8; cur ++ ) { 
+               for ( cur = 0; cur < 8; cur ++ ) {
                        byte a, b;
 
                        a = *(buf ++ );
@@ -1157,12 +1157,12 @@ static void print_packet( byte * buf, int length )
        printk("\n");
 #endif
 }
-#endif 
+#endif
 
 
 /*
  * Open and Initialize the board
- * 
+ *
  * Set up everything, reset the card, etc ..
  *
  */
@@ -1170,7 +1170,7 @@ static int smc_open(struct device *dev)
 {
        int     ioaddr = dev->base_addr;
 
-       int     i;      /* used to set hw ethernet address */ 
+       int     i;      /* used to set hw ethernet address */
 
        /* clear out all the junk that was put here before... */
        memset(dev->priv, 0, sizeof(struct smc_local));
@@ -1188,26 +1188,26 @@ static int smc_open(struct device *dev)
        smc_enable( ioaddr );
 
        /* Select which interface to use */
-        
+
        SMC_SELECT_BANK( 1 );
-       if ( dev->if_port == 1 ) {      
-               outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT, 
-                       ioaddr + CONFIG );                                                      
-       } 
-       else if ( dev->if_port == 2 ) { 
-               outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT, 
-                       ioaddr + CONFIG );                                                      
+       if ( dev->if_port == 1 ) {
+               outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT,
+                       ioaddr + CONFIG );
+       }
+       else if ( dev->if_port == 2 ) {
+               outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT,
+                       ioaddr + CONFIG );
        }
 
        /*
                According to Becker, I have to set the hardware address
                at this point, because the (l)user can set it with an
-               ioctl.  Easily done... 
+               ioctl.  Easily done...
        */
        SMC_SELECT_BANK( 1 );
-       for ( i = 0; i < 6; i += 2 ) { 
+       for ( i = 0; i < 6; i += 2 ) {
                word    address;
-               
+
                address = dev->dev_addr[ i + 1 ] << 8 ;
                address  |= dev->dev_addr[ i ];
                outw( address, ioaddr + ADDR0 + i );
@@ -1217,8 +1217,8 @@ static int smc_open(struct device *dev)
 
 /*--------------------------------------------------------
  . Called by the kernel to send a packet out into the void
- . of the net.  This routine is largely based on 
- . skeleton.c, from Becker.   
+ . of the net.  This routine is largely based on
+ . skeleton.c, from Becker.
  .--------------------------------------------------------
 */
 static int smc_send_packet(struct sk_buff *skb, struct device *dev)
@@ -1230,7 +1230,7 @@ static int smc_send_packet(struct sk_buff *skb, struct device *dev)
                if (tickssofar < 5)
                        return 1;
                printk(KERN_WARNING CARDNAME": transmit timed out, %s?\n",
-                       tx_done(dev) ? "IRQ conflict" : 
+                       tx_done(dev) ? "IRQ conflict" :
                        "network cable problem");
                /* "kick" the adaptor */
                smc_reset( dev->base_addr );
@@ -1256,8 +1256,8 @@ static int smc_send_packet(struct sk_buff *skb, struct device *dev)
                printk(KERN_WARNING CARDNAME": Transmitter access conflict.\n");
                dev_kfree_skb (skb, FREE_WRITE);
        } else {
-               /* Well, I want to send the packet.. but I don't know 
-                  if I can send it right now...  */    
+               /* Well, I want to send the packet.. but I don't know
+                  if I can send it right now...  */
                return smc_wait_to_send_packet( skb, dev );
        }
        return 0;
@@ -1270,16 +1270,16 @@ static int smc_send_packet(struct sk_buff *skb, struct device *dev)
  .
  . So:
  .   first, save state of the chipset
- .   branch off into routines to handle each case, and acknowledge 
+ .   branch off into routines to handle each case, and acknowledge
  .         each to the interrupt register
- .   and finally restore state. 
- .  
+ .   and finally restore state.
+ .
  ---------------------------------------------------------------------*/
 #ifdef REALLY_NEW_KERNEL
 static void smc_interrupt(int irq, void * dev_id,  struct pt_regs * regs)
-#else 
+#else
 static void smc_interrupt(int irq, struct pt_regs * regs)
-#endif 
+#endif
 {
        struct device *dev      = (struct device *)(irq2dev_map[irq]);
        int ioaddr              = dev->base_addr;
@@ -1294,21 +1294,21 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
        word    saved_pointer;
 
 
-       
+
        PRINTK3((CARDNAME": SMC interrupt started \n"));
 
        if (dev == NULL) {
-               printk(KERN_WARNING  CARDNAME": irq %d for unknown device.\n", 
+               printk(KERN_WARNING  CARDNAME": irq %d for unknown device.\n",
                        irq);
                return;
        }
 
 /* will Linux let this happen ??  If not, this costs some speed */
-       if ( dev->interrupt ) { 
+       if ( dev->interrupt ) {
                printk(KERN_WARNING CARDNAME": interrupt inside interrupt.\n");
                return;
        }
-               
+
        dev->interrupt = 1;
 
        saved_bank = inw( ioaddr + BANK_SELECT );
@@ -1325,14 +1325,14 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
        timeout = 4;
 
        PRINTK2((KERN_WARNING CARDNAME ": MASK IS %x \n", mask ));
-       do {    
+       do {
                /* read the status flag, and mask it */
                status = inb( ioaddr + INTERRUPT ) & mask;
                if (!status )
                        break;
 
                PRINTK3((KERN_WARNING CARDNAME
-                       ": Handling interrupt status %x \n", status )); 
+                       ": Handling interrupt status %x \n", status ));
 
                if (status & IM_RCV_INT) {
                        /* Got a packet(s). */
@@ -1343,7 +1343,7 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
                        PRINTK2((KERN_WARNING CARDNAME
                                ": TX ERROR handled\n"));
                        smc_tx(dev);
-                       outb(IM_TX_INT, ioaddr + INTERRUPT ); 
+                       outb(IM_TX_INT, ioaddr + INTERRUPT );
                } else if (status & IM_TX_EMPTY_INT ) {
                        /* update stats */
                        SMC_SELECT_BANK( 0 );
@@ -1355,14 +1355,14 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
                        lp->stats.collisions += card_stats & 0xF;
 
                        /* these are for when linux supports these statistics */
-#if 0 
+#if 0
                        card_stats >>= 4;
                        /* deferred */
                        card_stats >>= 4;
                        /* excess deferred */
-#endif 
+#endif
                        SMC_SELECT_BANK( 2 );
-                       PRINTK2((KERN_WARNING CARDNAME 
+                       PRINTK2((KERN_WARNING CARDNAME
                                ": TX_BUFFER_EMPTY handled\n"));
                        outb( IM_TX_EMPTY_INT, ioaddr + INTERRUPT );
                        mask &= ~IM_TX_EMPTY_INT;
@@ -1374,19 +1374,19 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
                                ": Allocation interrupt \n"));
                        /* clear this interrupt so it doesn't happen again */
                        mask &= ~IM_ALLOC_INT;
-               
+
                        smc_hardware_send_packet( dev );
-                       
+
                        /* enable xmit interrupts based on this */
                        mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
 
                        /* and let the card send more packets to me */
                        mark_bh( NET_BH );
 
-                       PRINTK2((CARDNAME": Handoff done successfully.\n"));    
+                       PRINTK2((CARDNAME": Handoff done successfully.\n"));
                } else if (status & IM_RX_OVRN_INT ) {
                        lp->stats.rx_errors++;
-                       lp->stats.rx_fifo_errors++;                     
+                       lp->stats.rx_fifo_errors++;
                        outb( IM_RX_OVRN_INT, ioaddr + INTERRUPT );
                } else if (status & IM_EPH_INT ) {
                        PRINTK((CARDNAME ": UNSUPPORTED: EPH INTERRUPT \n"));
@@ -1394,13 +1394,13 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
                        PRINTK((CARDNAME ": UNSUPPORTED: ERCV INTERRUPT \n"));
                        outb( IM_ERCV_INT, ioaddr + INTERRUPT );
                }
-       } while ( timeout -- ); 
+       } while ( timeout -- );
+
 
-       
        /* restore state register */
        SMC_SELECT_BANK( 2 );
        outb( mask, ioaddr + INT_MASK );
-       
+
        PRINTK3(( KERN_WARNING CARDNAME ": MASK is now %x \n", mask ));
        outw( saved_pointer, ioaddr + POINTER );
 
@@ -1417,10 +1417,10 @@ static void smc_interrupt(int irq, struct pt_regs * regs)
  .
  . There is ( at least ) a packet waiting to be read from
  . chip-memory.
- . 
- . o Read the status 
- . o If an error, record it  
- . o otherwise, read in the packet 
+ .
+ . o Read the status
+ . o If an error, record it
+ . o otherwise, read in the packet
  --------------------------------------------------------------
 */
 static void smc_rcv(struct device *dev)
@@ -1429,8 +1429,8 @@ static void smc_rcv(struct device *dev)
        int     ioaddr = dev->base_addr;
        int     packet_number;
        word    status;
-       word    packet_length; 
-       
+       word    packet_length;
+
        /* assume bank 2 */
 
        packet_number = inw( ioaddr + FIFO_PORTS );
@@ -1441,51 +1441,51 @@ static void smc_rcv(struct device *dev)
                /* don't need to restore anything */
                return;
        }
-               
+
        /*  start reading from the start of the packet */
        outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER );
 
-       /* First two words are status and packet_length */      
+       /* First two words are status and packet_length */
        status          = inw( ioaddr + DATA_1 );
        packet_length   = inw( ioaddr + DATA_1 );
-       
+
        packet_length &= 0x07ff;  /* mask off top bits */
 
        PRINTK2(("RCV: STATUS %4x LENGTH %4x\n", status, packet_length ));
-       /* 
-        . the packet length contains 3 extra words : 
+       /*
+        . the packet length contains 3 extra words :
         . status, length, and an extra word with an odd byte .
        */
-       packet_length -= 6; 
-       
-       if ( !(status & RS_ERRORS ) ){                  
+       packet_length -= 6;
+
+       if ( !(status & RS_ERRORS ) ){
                /* do stuff to make a new packet */
                struct sk_buff  * skb;
                byte            * data;
 
                /* read one extra byte */
-               if ( status & RS_ODDFRAME )     
-                       packet_length++;        
+               if ( status & RS_ODDFRAME )
+                       packet_length++;
 
-               /* set multicast stats */ 
+               /* set multicast stats */
                if ( status & RS_MULTICAST )
                        lp->stats.multicast++;
 
 #ifdef SUPPORT_OLD_KERNEL
                skb = alloc_skb( packet_length + 5, GFP_ATOMIC );
-#else  
-               skb = dev_alloc_skb( packet_length + 5); 
+#else
+               skb = dev_alloc_skb( packet_length + 5);
 #endif
 
-               if ( skb == NULL ) {    
+               if ( skb == NULL ) {
                        printk(KERN_NOTICE CARDNAME
                        ": Low memory, packet dropped.\n");
                        lp->stats.rx_dropped++;
                }
 
-               /* 
+               /*
                 ! This should work without alignment, but it could be
-                ! in the worse case 
+                ! in the worse case
                */
 #ifndef SUPPORT_OLD_KERNEL
                /* TODO: Should I use 32bit alignment here ? */
@@ -1500,42 +1500,42 @@ static void smc_rcv(struct device *dev)
                data = skb_put( skb, packet_length);
 #endif
 #ifdef USE_32_BIT
-               /* QUESTION:  Like in the TX routine, do I want                 
+               /* QUESTION:  Like in the TX routine, do I want
                   to send the DWORDs or the bytes first, or some
                   mixture.  A mixture might improve already slow PIO
                   performance  */
-               PRINTK3((" Reading %d dwords (and %d bytes) \n", 
+               PRINTK3((" Reading %d dwords (and %d bytes) \n",
                        packet_length >> 2, packet_length & 3 ));
-               insl(ioaddr + DATA_1 , data, packet_length >> 2 ); 
+               insl(ioaddr + DATA_1 , data, packet_length >> 2 );
                /* read the left over bytes */
-               insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC), 
+               insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC),
                        packet_length & 0x3  );
 #else
-               PRINTK3((" Reading %d words and %d byte(s) \n", 
+               PRINTK3((" Reading %d words and %d byte(s) \n",
                        (packet_length >> 1 ), packet_length & 1 );
-               if ( packet_length & 1 ) 
-                       *(data++) = inb( ioaddr + DATA_1 ); 
+               if ( packet_length & 1 )
+                       *(data++) = inb( ioaddr + DATA_1 );
                insw(ioaddr + DATA_1 , data, (packet_length + 1 ) >> 1);
                if ( packet_length & 1 ) {
                        data += packet_length & ~1;
-                       *((data++) = inb( ioaddr + DATA_1 ); 
+                       *((data++) = inb( ioaddr + DATA_1 );
                }
-#endif                 
-#if    SMC_DEBUG > 2   
+#endif
+#if    SMC_DEBUG > 2
                        print_packet( data, packet_length );
 #endif
 
 #ifndef SUPPORT_OLD_KERNEL
-               skb->protocol = eth_type_trans(skb, dev ); 
+               skb->protocol = eth_type_trans(skb, dev );
 #endif
                netif_rx(skb);
                lp->stats.rx_packets++;
        } else {
                /* error ... */
                lp->stats.rx_errors++;
-                       
-               if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;  
-               if ( status & (RS_TOOSHORT | RS_TOOLONG ) )  
+
+               if ( status & RS_ALGNERR )  lp->stats.rx_frame_errors++;
+               if ( status & (RS_TOOSHORT | RS_TOOLONG ) )
                        lp->stats.rx_length_errors++;
                if ( status & RS_BADCRC)        lp->stats.rx_crc_errors++;
        }
@@ -1547,22 +1547,22 @@ static void smc_rcv(struct device *dev)
 }
 
 
-/************************************************************************* 
+/*************************************************************************
  . smc_tx
- . 
+ .
  . Purpose:  Handle a transmit error message.   This will only be called
- .   when an error, because of the AUTO_RELEASE mode. 
- . 
+ .   when an error, because of the AUTO_RELEASE mode.
+ .
  . Algorithm:
  .     Save pointer and packet no
  .     Get the packet no from the top of the queue
  .     check if it's valid ( if not, is this an error??? )
- .     read the status word 
+ .     read the status word
  .     record the error
  .     ( resend?  Not really, since we don't want old packets around )
- .     Restore saved values 
- ************************************************************************/ 
-static void smc_tx( struct device * dev ) 
+ .     Restore saved values
+ ************************************************************************/
+static void smc_tx( struct device * dev )
 {
        int     ioaddr = dev->base_addr;
        struct smc_local *lp = (struct smc_local *)dev->priv;
@@ -1578,46 +1578,46 @@ static void smc_tx( struct device * dev )
        packet_no &= 0x7F;
 
        /* select this as the packet to read from */
-       outb( packet_no, ioaddr + PNR_ARR ); 
-       
-       /* read the first word from this packet */      
+       outb( packet_no, ioaddr + PNR_ARR );
+
+       /* read the first word from this packet */
        outw( PTR_AUTOINC | PTR_READ, ioaddr + POINTER );
 
        tx_status = inw( ioaddr + DATA_1 );
        PRINTK3((CARDNAME": TX DONE STATUS: %4x \n", tx_status ));
-       
+
        lp->stats.tx_errors++;
        if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++;
        if ( tx_status & TS_LATCOL  ) {
-               printk(KERN_DEBUG CARDNAME 
+               printk(KERN_DEBUG CARDNAME
                        ": Late collision occurred on last xmit.\n");
                lp->stats.tx_window_errors++;
        }
 #if 0
                if ( tx_status & TS_16COL ) { ... }
-#endif 
+#endif
 
-       if ( tx_status & TS_SUCCESS ) {  
+       if ( tx_status & TS_SUCCESS ) {
                printk(CARDNAME": Successful packet caused interrupt \n");
-       } 
+       }
        /* re-enable transmit */
        SMC_SELECT_BANK( 0 );
        outw( inw( ioaddr + TCR ) | TCR_ENABLE, ioaddr + TCR );
 
-       /* kill the packet */                   
+       /* kill the packet */
        SMC_SELECT_BANK( 2 );
        outw( MC_FREEPKT, ioaddr + MMU_CMD );
 
        /* one less packet waiting for me */
        lp->packets_waiting--;
-               
+
        outb( saved_packet, ioaddr + PNR_ARR );
        return;
 }
 
 /*----------------------------------------------------
  . smc_close
- . 
+ .
  . this makes the board clean up everything that it can
  . and not talk to the outside world.   Caused by
  . an 'ifconfig ethX down'
@@ -1640,8 +1640,8 @@ static int smc_close(struct device *dev)
 }
 
 /*------------------------------------------------------------
- . Get the current statistics. 
- . This may be called with the card open or closed. 
+ . Get the current statistics.
+ . This may be called with the card open or closed.
  .-------------------------------------------------------------*/
 static struct enet_statistics * smc_query_statistics(struct device *dev) {
        struct smc_local *lp = (struct smc_local *)dev->priv;
@@ -1651,52 +1651,52 @@ static struct enet_statistics * smc_query_statistics(struct device *dev) {
 
 /*-----------------------------------------------------------
  . smc_set_multicast_list
- .  
+ .
  . This routine will, depending on the values passed to it,
- . either make it accept multicast packets, go into 
+ . either make it accept multicast packets, go into
  . promiscuous mode ( for TCPDUMP and cousins ) or accept
- . a select set of multicast packets  
+ . a select set of multicast packets
 */
 #ifdef SUPPORT_OLD_KERNEL
-static void smc_set_multicast_list( struct device * dev, 
-                       int num_addrs, void * addrs )   
+static void smc_set_multicast_list( struct device * dev,
+                       int num_addrs, void * addrs )
 #else
-static void smc_set_multicast_list(struct device *dev) 
-#endif 
+static void smc_set_multicast_list(struct device *dev)
+#endif
 {
        short ioaddr = dev->base_addr;
 
        SMC_SELECT_BANK(0);
 #ifdef  SUPPORT_OLD_KERNEL
-       if ( num_addrs < 0 )  
+       if ( num_addrs < 0 )
 #else
-       if ( dev->flags & IFF_PROMISC ) 
-#endif 
+       if ( dev->flags & IFF_PROMISC )
+#endif
                outw( inw(ioaddr + RCR ) | RCR_PROMISC, ioaddr + RCR );
 
-/* BUG?  I never disable promiscuous mode if multicasting was turned on. 
+/* BUG?  I never disable promiscuous mode if multicasting was turned on.
    Now, I turn off promiscuous mode, but I don't do anything to multicasting
-   when promiscuous mode is turned on. 
+   when promiscuous mode is turned on.
 */
 
-       /* Here, I am setting this to accept all multicast packets.  
+       /* Here, I am setting this to accept all multicast packets.
           I don't need to zero the multicast table, because the flag is
-          checked before the table is 
+          checked before the table is
        */
-#ifdef  SUPPORT_OLD_KERNEL 
+#ifdef  SUPPORT_OLD_KERNEL
        else if ( num_addrs > 20 )      /* arbitrary constant */
 #else
-       else if (dev->flags & IFF_ALLMULTI)  
-#endif 
-               outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR ); 
+       else if (dev->flags & IFF_ALLMULTI)
+#endif
+               outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR );
 
        /* We just get all multicast packets even if we only want them
         . from one source.  This will be changed at some future
         . point. */
 #ifdef  SUPPORT_OLD_KERNEL
-       else if (num_addrs > 0 ) { 
+       else if (num_addrs > 0 ) {
 /* the old kernel support will not have hardware multicast support. It would
-   involve more kludges, and make the multicast setting code even worse.  
+   involve more kludges, and make the multicast setting code even worse.
    Instead, just use the ALMUL method.   This is reasonable, considering that
    it is seldom used
 */
@@ -1704,11 +1704,11 @@ static void smc_set_multicast_list(struct device *dev)
                outw( inw( ioadddr + RCR ) | RCR_ALMUL, ioadddr + RCR );
        }
 #else
-       else if (dev->mc_count )  { 
+       else if (dev->mc_count )  {
                /* support hardware multicasting */
-               
-               /* be sure I get rid of flags I might have set */       
-               outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL), 
+
+               /* be sure I get rid of flags I might have set */
+               outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
                        ioaddr + RCR );
                /* NOTE: this has to set the bank, so make sure it is the
                   last thing called.  The bank is set to zero at the top */
@@ -1716,18 +1716,18 @@ static void smc_set_multicast_list(struct device *dev)
        }
 #endif
        else  {
-               outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL), 
+               outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
                        ioaddr + RCR );
 
-               /* 
-                 since I'm disabling all multicast entirely, I need to 
-                 clear the multicast list 
+               /*
+                 since I'm disabling all multicast entirely, I need to
+                 clear the multicast list
                */
                SMC_SELECT_BANK( 3 );
-               outw( 0, ioaddr + MULTICAST1 ); 
-               outw( 0, ioaddr + MULTICAST2 ); 
-               outw( 0, ioaddr + MULTICAST3 ); 
-               outw( 0, ioaddr + MULTICAST4 ); 
+               outw( 0, ioaddr + MULTICAST1 );
+               outw( 0, ioaddr + MULTICAST2 );
+               outw( 0, ioaddr + MULTICAST3 );
+               outw( 0, ioaddr + MULTICAST4 );
        }
 }
 
@@ -1744,12 +1744,16 @@ int io = 0;
 int irq = 0;
 int ifport = 0;
 
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(ifport, "i");
+
 int init_module(void)
 {
        int result;
 
        if (io == 0)
-               printk(KERN_WARNING 
+               printk(KERN_WARNING
                CARDNAME": You shouldn't use auto-probing with insmod!\n" );
 
        /* copy the parameters from insmod into the device structure */
@@ -1776,4 +1780,3 @@ void cleanup_module(void)
 }
 
 #endif /* MODULE */
-
index c78f9acd45bc83ff06f5815b3ec6e25932798692..b5954bb60a9656c736af0786d768fe7d3213b7ed 100644 (file)
@@ -25,7 +25,7 @@
  *
  *
  *  Command line options (insmod command line)
- * 
+ *
  *  hardware hardware type; 0=sbc, 1=wss, any other value invalid
  *  mode     mode type; 0=1200 baud AFSK, 1=9600 baud FSK, any other
  *           value invalid
@@ -33,7 +33,7 @@
  *           0x530 for wss
  *  irq      interrupt number; common values are 7 or 5 for sbc, 11 for wss
  *  dma      dma number; common values are 0 or 1
- * 
+ *
  *
  *  History:
  *   0.1  21.09.96  Started
@@ -83,8 +83,8 @@ static struct device sm_device[NR_PORTS];
 static struct {
        char *mode;
        int iobase, irq, dma, dma2, seriobase, pariobase, midiiobase;
-} sm_ports[NR_PORTS] = { 
-       { NULL, -1, 0, 0, 0, -1, -1, -1 }, 
+} sm_ports[NR_PORTS] = {
+       { NULL, -1, 0, 0, 0, -1, -1, -1 },
 };
 
 /* --------------------------------------------------------------------- */
@@ -138,7 +138,7 @@ static struct {
 
 /* ---------------------------------------------------------------------- */
 /*
- * Information that need to be kept for each board. 
+ * Information that need to be kept for each board.
  */
 
 struct sm_state {
@@ -155,7 +155,7 @@ struct sm_state {
        union {
                long hw[32/sizeof(long)];
        } hw;
-       
+
        /*
         * state of the modem code
         */
@@ -165,7 +165,7 @@ struct sm_state {
        union {
                long d[256/sizeof(long)];
        } d;
-       
+
 #define DIAGDATALEN 64
        struct diag_data {
                unsigned int mode;
@@ -174,7 +174,7 @@ struct sm_state {
                short data[DIAGDATALEN];
        } diag;
 
-       
+
 #ifdef SM_DEBUG
        struct debug_vals {
                unsigned long last_jiffies;
@@ -235,7 +235,7 @@ struct hardware_info {
         */
        int (*open)(struct device *, struct sm_state *);
        int (*close)(struct device *, struct sm_state *);
-       int (*ioctl)(struct device *, struct sm_state *, struct ifreq *, 
+       int (*ioctl)(struct device *, struct sm_state *, struct ifreq *,
                     struct hdlcdrv_ioctl *, int);
        int (*sethw)(struct device *, struct sm_state *, char *);
 };
@@ -254,7 +254,7 @@ static void inline sm_int_freq(struct sm_state *sm)
 {
 #ifdef SM_DEBUG
        unsigned long cur_jiffies = jiffies;
-       /* 
+       /*
         * measure the interrupt frequency
         */
        sm->debug_vals.cur_intcnt++;
@@ -320,7 +320,7 @@ static enum uart check_uart(unsigned int iobase)
        b3 = inb(UART_MSR(iobase)) & 0xf0;
        outb(b1, UART_MCR(iobase));        /* restore old values */
        outb(b2, UART_MSR(iobase));
-       if (b3 != 0x90) 
+       if (b3 != 0x90)
                return c_uart_unknown;
        inb(UART_RBR(iobase));
        inb(UART_RBR(iobase));
@@ -331,7 +331,7 @@ static enum uart check_uart(unsigned int iobase)
                b1 = inb(UART_SCR(iobase));
                outb(0xa5, UART_SCR(iobase));
                b2 = inb(UART_SCR(iobase));
-               if ((b1 != 0x5a) || (b2 != 0xa5)) 
+               if ((b1 != 0x5a) || (b2 != 0xa5))
                        u = c_uart_8250;
        }
        return u;
@@ -395,29 +395,29 @@ static void output_open(struct sm_state *sm)
        enum uart u = c_uart_unknown;
 
        sm->hdrv.ptt_out.flags = 0;
-       if (sm->hdrv.ptt_out.seriobase > 0 && 
+       if (sm->hdrv.ptt_out.seriobase > 0 &&
            sm->hdrv.ptt_out.seriobase <= 0x1000-SER_EXTENT &&
            ((u = check_uart(sm->hdrv.ptt_out.seriobase))) != c_uart_unknown) {
                sm->hdrv.ptt_out.flags |= SP_SER;
                request_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT, "sm ser ptt");
                outb(0, UART_IER(sm->hdrv.ptt_out.seriobase));
                /* 5 bits, 1 stop, no parity, no break, Div latch access */
-               outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase)); 
+               outb(0x80, UART_LCR(sm->hdrv.ptt_out.seriobase));
                outb(0, UART_DLM(sm->hdrv.ptt_out.seriobase));
                outb(1, UART_DLL(sm->hdrv.ptt_out.seriobase)); /* as fast as possible */
                /* LCR and MCR set by output_status */
        }
-       if (sm->hdrv.ptt_out.pariobase > 0 && 
+       if (sm->hdrv.ptt_out.pariobase > 0 &&
            sm->hdrv.ptt_out.pariobase <= 0x1000-LPT_EXTENT &&
            check_lpt(sm->hdrv.ptt_out.pariobase)) {
                sm->hdrv.ptt_out.flags |= SP_PAR;
                request_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT, "sm par ptt");
        }
-       if (sm->hdrv.ptt_out.midiiobase > 0 && 
+       if (sm->hdrv.ptt_out.midiiobase > 0 &&
            sm->hdrv.ptt_out.midiiobase <= 0x1000-MIDI_EXTENT &&
            check_midi(sm->hdrv.ptt_out.midiiobase)) {
                sm->hdrv.ptt_out.flags |= SP_MIDI;
-               request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT, 
+               request_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT,
                               "sm midi ptt");
        }
        output_status(sm);
@@ -444,9 +444,9 @@ static void output_close(struct sm_state *sm)
        output_status(sm);
        if (sm->hdrv.ptt_out.flags & SP_SER)
                release_region(sm->hdrv.ptt_out.seriobase, SER_EXTENT);
-               if (sm->hdrv.ptt_out.flags & SP_PAR) 
+               if (sm->hdrv.ptt_out.flags & SP_PAR)
                release_region(sm->hdrv.ptt_out.pariobase, LPT_EXTENT);
-               if (sm->hdrv.ptt_out.flags & SP_MIDI) 
+               if (sm->hdrv.ptt_out.flags & SP_MIDI)
                release_region(sm->hdrv.ptt_out.midiiobase, MIDI_EXTENT);
        sm->hdrv.ptt_out.flags = 0;
 }
@@ -458,7 +458,7 @@ static void output_close(struct sm_state *sm)
 
 extern inline void diag_trigger(struct sm_state *sm)
 {
-       if (sm->diag.ptr < 0) 
+       if (sm->diag.ptr < 0)
                if (!(sm->diag.flags & SM_DIAGFLAG_DCDGATE) || sm->hdrv.hdlcrx.dcd)
                        sm->diag.ptr = 0;
 }
@@ -469,8 +469,8 @@ extern inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
 {
        int val;
 
-       if ((sm->diag.mode != SM_DIAGMODE_INPUT && 
-            sm->diag.mode != SM_DIAGMODE_DEMOD) || 
+       if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
+            sm->diag.mode != SM_DIAGMODE_DEMOD) ||
            sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
                return;
        val = (sm->diag.mode == SM_DIAGMODE_DEMOD) ? valdemod : valinp;
@@ -486,8 +486,8 @@ extern inline void diag_add(struct sm_state *sm, int valinp, int valdemod)
 
 extern inline void diag_add_one(struct sm_state *sm, int val)
 {
-       if ((sm->diag.mode != SM_DIAGMODE_INPUT && 
-            sm->diag.mode != SM_DIAGMODE_DEMOD) || 
+       if ((sm->diag.mode != SM_DIAGMODE_INPUT &&
+            sm->diag.mode != SM_DIAGMODE_DEMOD) ||
            sm->diag.ptr >= DIAGDATALEN || sm->diag.ptr < 0)
                return;
        /* clip */
@@ -502,7 +502,7 @@ extern inline void diag_add_one(struct sm_state *sm, int val)
 
 static inline void diag_add_constellation(struct sm_state *sm, int vali, int valq)
 {
-       if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) || 
+       if ((sm->diag.mode != SM_DIAGMODE_CONSTELLATION) ||
            sm->diag.ptr >= DIAGDATALEN-1 || sm->diag.ptr < 0)
                return;
        /* clip */
@@ -530,7 +530,7 @@ extern inline unsigned int hweight16(unsigned short w)
 extern inline unsigned int hweight8(unsigned char w)
         __attribute__ ((unused));
 
-extern inline unsigned int hweight32(unsigned int w) 
+extern inline unsigned int hweight32(unsigned int w)
 {
         unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
@@ -564,7 +564,7 @@ extern inline unsigned int gcd(unsigned int x, unsigned int y)
        for (;;) {
                if (!x)
                        return y;
-               if (!y) 
+               if (!y)
                        return x;
                if (x > y)
                        x %= y;
@@ -631,7 +631,7 @@ extern inline unsigned int lcm(unsigned int x, unsigned int y)
 
 static int sm_open(struct device *dev);
 static int sm_close(struct device *dev);
-static int sm_ioctl(struct device *dev, struct ifreq *ifr, 
+static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                    struct hdlcdrv_ioctl *hi, int cmd);
 
 /* --------------------------------------------------------------------- */
@@ -651,7 +651,7 @@ static int sm_open(struct device *dev)
        struct sm_state *sm;
        int err;
 
-       if (!dev || !dev->priv || 
+       if (!dev || !dev->priv ||
            ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
                printk(KERN_ERR "sm_open: invalid device struct\n");
                return -EINVAL;
@@ -666,8 +666,8 @@ static int sm_open(struct device *dev)
                return err;
        output_open(sm);
        MOD_INC_USE_COUNT;
-       printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u\n", 
-              sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name, 
+       printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u\n",
+              sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name,
               sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma);
        return 0;
 }
@@ -679,19 +679,19 @@ static int sm_close(struct device *dev)
        struct sm_state *sm;
        int err = -ENODEV;
 
-       if (!dev || !dev->priv || 
+       if (!dev || !dev->priv ||
            ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
                printk(KERN_ERR "sm_close: invalid device struct\n");
                return -EINVAL;
        }
        sm = (struct sm_state *)dev->priv;
 
-       
+
        if (sm->hwdrv && sm->hwdrv->close)
                err = sm->hwdrv && sm->hwdrv->close(dev, sm);
        output_close(sm);
        MOD_DEC_USE_COUNT;
-       printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n", 
+       printk(KERN_INFO "%s: close %s at iobase 0x%lx irq %u dma %u\n",
               sm_drvname, sm->hwdrv->hw_name, dev->base_addr, dev->irq, dev->dma);
        return err;
 }
@@ -702,7 +702,7 @@ static int sethw(struct device *dev, struct sm_state *sm, char *mode)
 {
        char *cp = strchr(mode, ':');
        const struct hardware_info *hwp = hardware_base;
-       
+
        if (!cp)
                cp = mode;
        else {
@@ -718,7 +718,7 @@ static int sethw(struct device *dev, struct sm_state *sm, char *mode)
                }
                sm->hwdrv = hwp;
        }
-       if (!*cp) 
+       if (!*cp)
                return 0;
        if (sm->hwdrv && sm->hwdrv->sethw)
                return sm->hwdrv->sethw(dev, sm, cp);
@@ -727,7 +727,7 @@ static int sethw(struct device *dev, struct sm_state *sm, char *mode)
 
 /* --------------------------------------------------------------------- */
 
-static int sm_ioctl(struct device *dev, struct ifreq *ifr, 
+static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                    struct hdlcdrv_ioctl *hi, int cmd)
 {
        struct sm_state *sm;
@@ -740,7 +740,7 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
        const struct modem_rx_info *mrp = modem_rx_base;
        const struct hardware_info *hwp = hardware_base;
 
-       if (!dev || !dev->priv || 
+       if (!dev || !dev->priv ||
            ((struct sm_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
                printk(KERN_ERR "sm_ioctl: invalid device struct\n");
                return -EINVAL;
@@ -757,34 +757,34 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                if (sm->hwdrv && sm->hwdrv->ioctl)
                        return sm->hwdrv->ioctl(dev, sm, ifr, hi, cmd);
                return -ENOIOCTLCMD;
-               
+
        case HDLCDRVCTL_GETMODE:
                cp = hi->data.modename;
                if (sm->hwdrv && sm->hwdrv->hw_name)
                        cp += sprintf(cp, "%s:", sm->hwdrv->hw_name);
-               else 
+               else
                        cp += sprintf(cp, "<unspec>:");
                if (sm->mode_tx && sm->mode_tx->name)
                        cp += sprintf(cp, "%s", sm->mode_tx->name);
-               else 
+               else
                        cp += sprintf(cp, "<unspec>");
-               if (!sm->mode_rx || !sm->mode_rx || 
+               if (!sm->mode_rx || !sm->mode_rx ||
                    strcmp(sm->mode_rx->name, sm->mode_tx->name)) {
                        if (sm->mode_rx && sm->mode_rx->name)
                                cp += sprintf(cp, ",%s", sm->mode_rx->name);
-                       else 
+                       else
                                cp += sprintf(cp, ",<unspec>");
                }
                if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
                        return -EFAULT;
                return 0;
-               
+
        case HDLCDRVCTL_SETMODE:
                if (!suser() || dev->start)
                        return -EACCES;
                hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
                return sethw(dev, sm, hi->data.modename);
-               
+
        case HDLCDRVCTL_MODELIST:
                cp = hi->data.modename;
                while (hwp) {
@@ -806,7 +806,7 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                if (copy_to_user(ifr->ifr_data, hi, sizeof(*hi)))
                        return -EFAULT;
                return 0;
-               
+
 #ifdef SM_DEBUG
        case SMCTL_GETDEBUG:
                if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
@@ -815,7 +815,7 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                bi.data.dbg.mod_cycles = sm->debug_vals.mod_cyc;
                bi.data.dbg.demod_cycles = sm->debug_vals.demod_cyc;
                bi.data.dbg.dma_residue = sm->debug_vals.dma_residue;
-               sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc = 
+               sm->debug_vals.mod_cyc = sm->debug_vals.demod_cyc =
                        sm->debug_vals.dma_residue = 0;
                if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
                        return -EFAULT;
@@ -855,7 +855,7 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
                                return -EFAULT;
                        return 0;
                }
-               if (copy_to_user(bi.data.diag.data, sm->diag.data, 
+               if (copy_to_user(bi.data.diag.data, sm->diag.data,
                                 bi.data.diag.datalen * sizeof(short)))
                        return -EFAULT;
                bi.data.diag.flags |= SM_DIAGFLAG_VALID;
@@ -882,7 +882,7 @@ int sm_init(void)
        char set_hw = 1;
        struct sm_state *sm;
        char ifname[HDLCDRV_IFNAMELEN];
-       
+
        printk(sm_drvinfo);
        /*
         * register net devices
@@ -895,7 +895,7 @@ int sm_init(void)
                        set_hw = 0;
                if (!set_hw)
                        sm_ports[i].iobase = sm_ports[i].irq = 0;
-               j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state), 
+               j = hdlcdrv_register_hdlcdrv(dev, &sm_ops, sizeof(struct sm_state),
                                             ifname, sm_ports[i].iobase,
                                             sm_ports[i].irq, sm_ports[i].dma);
                if (!j) {
@@ -933,6 +933,15 @@ int serio = 0;
 int pario = 0;
 int midiio = 0;
 
+MODULE_PARM(mode, "s");
+MODULE_PARM(iobase, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(dma, "i");
+MODULE_PARM(dma2, "i");
+MODULE_PARM(serio, "i");
+MODULE_PARM(pario, "i");
+MODULE_PARM(midiio, "i");
+
 int init_module(void)
 {
        if (mode) {
@@ -972,7 +981,7 @@ void cleanup_module(void)
                        if (sm->hdrv.magic != HDLCDRV_MAGIC)
                                printk(KERN_ERR "sm: invalid magic in "
                                       "cleanup_module\n");
-                       else 
+                       else
                                hdlcdrv_unregister_hdlcdrv(dev);
                }
        }
index 7618a66ef7c184def8acb22932ba474f101b4503..824ca404995bfcdb5e8986f0d8967e006701f96e 100644 (file)
@@ -770,7 +770,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev)
        }
 
        if (skb->len <= 0) {
-               printk ("skb len is %ld\n", skb->len);
+               printk ("skb len is %d\n", skb->len);
                return 0;
        }
 
index 7af3be77a47c0be05c00c93c17a3c75f4f597981..77ac9e05359f95ae9269e3944678a74b9a1ac1f2 100644 (file)
@@ -20,7 +20,7 @@
 
        Paul Gortmaker  : multiple card support for module users, support
                          for non-standard memory sizes.
-                        
+
 
 */
 
@@ -259,7 +259,7 @@ int wd_probe1(struct device *dev, int ioaddr)
        }
 
        /* Allocate dev->priv and fill in 8390 specific dev fields. */
-       if (ethdev_init(dev)) { 
+       if (ethdev_init(dev)) {
                printk (" unable to get memory for dev->priv.\n");
                free_irq(dev->irq, NULL);
                return -ENOMEM;
@@ -452,6 +452,11 @@ static int irq[MAX_WD_CARDS]  = { 0, };
 static int mem[MAX_WD_CARDS] = { 0, };
 static int mem_end[MAX_WD_CARDS] = { 0, };     /* for non std. mem size */
 
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+MODULE_PARM(mem_end, "1-" __MODULE_STRING(MAX_WD_CARDS) "i");
+
 /* This is set up so that only a single autoprobe takes place per call.
 ISA device autoprobes on a running machine are not recommended. */
 int
index df76ab6e182281013d973a50fd5ed12fbd37538b..0416ec0db397fd3909861e939c1b10c6be45a380 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bwtwo.c,v 1.8 1996/11/23 19:54:05 ecd Exp $
+/* $Id: bwtwo.c,v 1.9 1996/12/23 10:15:57 ecd Exp $
  * bwtwo.c: bwtwo console driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index 966213e64a38cb2aa8a1f22c452a3422972caf99..10b1d6182ffd67bbd0297857ddcec1d0a06e3bda 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgfourteen.c,v 1.16 1996/11/22 11:57:06 ecd Exp $
+/* $Id: cgfourteen.c,v 1.17 1996/12/23 10:16:00 ecd Exp $
  * cgfourteen.c: Sun SparcStation console support.
  *
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -15,6 +15,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index 2c1907c3fe78b217a8a0a22f12ae8c791541b432..046f11308786978030b1a48f7f95f5bd46394505 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.19 1996/12/19 08:07:35 davem Exp $
+/* $Id: cgsix.c,v 1.21 1996/12/23 10:16:05 ecd Exp $
  * cgsix.c: cgsix frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -8,6 +8,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index 9779ea6d36c1d8d66384769954b977c9c2a7d020..d09940fb61850d4066c2f9a8502aa9b0a15a9904 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgthree.c,v 1.9 1996/11/13 05:10:21 davem Exp $
+/* $Id: cgthree.c,v 1.10 1996/12/23 10:16:07 ecd Exp $
  * cgtree.c: cg3 frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -9,6 +9,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index 6d46b2d103ce13554700be8b1ad2bd44b7b54d63..78ddb93e79b17e9c65d70f15739adc595d900c8b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fb.h,v 1.19 1996/11/13 05:10:23 davem Exp $
+/* $Id: fb.h,v 1.20 1996/12/23 10:16:08 ecd Exp $
  * fb.h: contains the definitions of the structures that various sun
  *       frame buffer can use to do console driver stuff.
  *
@@ -13,7 +13,6 @@
 #ifndef __SPARC_FB_H_
 #define __SPARC_FB_H_
 
-#include <linux/proc_fs.h>
 #include <linux/init.h>
 
 #define FRAME_BUFFERS    8
index 048f4a31fb94ef2034ff5c7d0a74b1425a87db34..585ee8352c8c2c44a9be329858ca5f6f297588fc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: leo.c,v 1.9 1996/11/27 20:09:59 jj Exp $
+/* $Id: leo.c,v 1.10 1996/12/23 10:16:09 ecd Exp $
  * leo.c: SUNW,leo 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index 545c48de70ca43e5ffa8607b8a5830530122e3b2..cd8e1c2ddefab55c6f0ab383964ed586c39812ee 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: suncons.c,v 1.42 1996/11/27 20:10:06 jj Exp $
+/* $Id: suncons.c,v 1.43 1996/12/23 10:16:12 ecd Exp $
  *
  * suncons.c: Sun SparcStation console support.
  *
@@ -63,6 +63,7 @@
 #include <linux/mm.h>
 #include <linux/types.h>
 #include <linux/version.h>
+#include <linux/proc_fs.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index 76769453571107942e8e49cc34af9b1158a56fb3..7c2e00a2f1825b982fac7f75146c31b0dae025f9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sunfb.c,v 1.18 1996/11/22 11:57:07 ecd Exp $
+/* $Id: sunfb.c,v 1.19 1996/12/23 10:16:15 ecd Exp $
  * sunfb.c: Sun generic frame buffer support.
  *
  * Copyright (C) 1995, 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -21,6 +21,7 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/types.h>
+#include <linux/proc_fs.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
index cd411c314f419127baabee9dac259fa02529babe..652986660ea26f47b1aed811fc23ae2ec7067d40 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tcx.c,v 1.8 1996/11/21 16:57:57 jj Exp $
+/* $Id: tcx.c,v 1.9 1996/12/23 10:16:17 ecd Exp $
  * tcx.c: SUNW,tcx 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -9,6 +9,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/sbus.h>
 #include <asm/io.h>
index cc7a5fde701bce758dd006044ca3cfe7a7d88c9f..4f629973a7a834eaee53b4840a6985efb1cbd6da 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: weitek.c,v 1.6 1996/11/13 05:10:51 davem Exp $
+/* $Id: weitek.c,v 1.7 1996/12/23 10:16:18 ecd Exp $
  * weitek.c: Tadpole P9100/P9000 console driver
  *
  * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
@@ -7,6 +7,7 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/malloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/openprom.h>
 #include <asm/sbus.h>
index ee0f8f5bb6f5c175d77acc40ae5c9b1f05ab40f6..9aef6de8bd1dd99210f5d0f7c54a5cce58070d8a 100644 (file)
@@ -214,18 +214,8 @@ extern Scsi_Device * scsi_devices;
 
 extern int scsi_dev_init (void);
 
-struct scatterlist {
-    char *  address;    /* Location data is to be transferred to */
-    char * alt_address; /* Location of actual if address is a 
-                        * dma indirect buffer.  NULL otherwise */
-    unsigned int length;
-};
-
-#ifdef __alpha__
-# define ISA_DMA_THRESHOLD (~0UL)
-#else
-# define ISA_DMA_THRESHOLD (0x00ffffff)
-#endif
+#include <asm/scatterlist.h>
+
 #define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
 
 
index 4029063d00c188ad4d8ecb65a75118df9a3b955e..eda6449eec8c3e7ee3ce8b2f202920fbaf598f4f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -42,6 +42,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 
 #include <linux/config.h>
 #ifdef CONFIG_KERNELD
@@ -373,6 +374,7 @@ static void exec_mmap(void)
                        return;
                }
                *mm = *current->mm;
+               init_new_context(mm);
                mm->def_flags = 0;      /* should future lockings be kept? */
                mm->count = 1;
                mm->mmap = NULL;
index 3119074072bd5e3adb96389d3f2826bcb60b9c02..288c3cc5c79e6b2a68a7697bfab2a4db6ac8decd 100644 (file)
@@ -294,12 +294,12 @@ struct super_block *fat_read_super(struct super_block *sb,void *data, int silent
                       opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
                       MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : "");
                printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,"
-                      "se=%d,ts=%ld,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
+                      "se=%d,ts=%d,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
                       MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,MSDOS_SB(sb)->fat_length,
                       MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
                       MSDOS_SB(sb)->data_start,
-                      CF_LE_W(*(unsigned short *) &b->sectors),
-                      (unsigned long)b->total_sect,logical_sector_size);
+                      CF_LE_W(get_unaligned((unsigned short *) &b->sectors)),
+                      CF_LE_L(b->total_sect),logical_sector_size);
                printk ("Transaction block size = %d\n",blksize);
        }
        if (MSDOS_SB(sb)->clusters+2 > fat_clusters)
index ede71765f13dbbd5fb5f514a7619d53732aaaa58..00a43cabd7ea38c423478cc16ebf26771e3e9f12 100644 (file)
@@ -2,6 +2,7 @@
  *  dir.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
 #include <linux/mm.h>
 #include <linux/ncp_fs.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include "ncplib_kernel.h"
 
+
 struct ncp_dirent {
        struct nw_info_struct i;
        struct nw_search_sequence s; /* given back for i */
@@ -672,6 +675,11 @@ ncp_init_root(struct ncp_server *server)
        ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
        ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate));
        ncp_date_unix2dos(0, &dummy, &(i->lastAccessDate));
+       i->creationTime = le16_to_cpu(i->creationTime);
+       i->creationDate = le16_to_cpu(i->creationDate);
+       i->modifyTime = le16_to_cpu(i->modifyTime);
+       i->modifyDate = le16_to_cpu(i->modifyDate);
+       i->lastAccessDate = le16_to_cpu(i->lastAccessDate);
        i->nameLen = 0;
        i->entryName[0] = '\0';
 
index 5a95ffb1f3373ae2d7e0d2e7efa782176b9161c4..dc629b3a94370fbd6ac6a46ec2794521b98bac03 100644 (file)
@@ -2,6 +2,7 @@
  *  inode.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -10,6 +11,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 #include <linux/sched.h>
 #include <linux/ncp_fs.h>
@@ -83,7 +85,7 @@ ncp_read_inode(struct inode *inode)
        else
        {
                 inode->i_mode = NCP_SERVER(inode)->m.file_mode;
-               inode->i_size = NCP_ISTRUCT(inode)->dataStreamSize;
+               inode->i_size = le32_to_cpu(NCP_ISTRUCT(inode)->dataStreamSize);
        }
 
         DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
@@ -104,12 +106,12 @@ ncp_read_inode(struct inode *inode)
                 inode->i_blocks = 0;
        }
 
-       inode->i_mtime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->modifyTime,
-                                          NCP_ISTRUCT(inode)->modifyDate);
-       inode->i_ctime = ncp_date_dos2unix(NCP_ISTRUCT(inode)->creationTime,
-                                          NCP_ISTRUCT(inode)->creationDate);
+       inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->modifyTime),
+                                          le16_to_cpu(NCP_ISTRUCT(inode)->modifyDate));
+       inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(NCP_ISTRUCT(inode)->creationTime),
+                                          le16_to_cpu(NCP_ISTRUCT(inode)->creationDate));
        inode->i_atime = ncp_date_dos2unix(0,
-                                          NCP_ISTRUCT(inode)->lastAccessDate);
+                                          le16_to_cpu(NCP_ISTRUCT(inode)->lastAccessDate));
 
         if (S_ISREG(inode->i_mode))
        {
@@ -460,6 +462,8 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
                info_mask |= (DM_CREATE_TIME|DM_CREATE_DATE);
                ncp_date_unix2dos(attr->ia_ctime,
                                  &(info.creationTime), &(info.creationDate));
+               info.creationTime = le16_to_cpu(info.creationTime);
+               info.creationDate = le16_to_cpu(info.creationDate);
        }
 
        if ((attr->ia_valid & ATTR_MTIME) != 0)
@@ -467,6 +471,8 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
                info_mask |= (DM_MODIFY_TIME|DM_MODIFY_DATE);
                ncp_date_unix2dos(attr->ia_mtime,
                                  &(info.modifyTime), &(info.modifyDate));
+               info.modifyTime = le16_to_cpu(info.modifyTime);
+               info.modifyDate = le16_to_cpu(info.modifyDate);
        }
 
        if ((attr->ia_valid & ATTR_ATIME) != 0)
@@ -475,6 +481,7 @@ ncp_notify_change(struct inode *inode, struct iattr *attr)
                info_mask |= (DM_LAST_ACCESS_DATE);
                ncp_date_unix2dos(attr->ia_ctime,
                                  &(dummy), &(info.lastAccessDate));
+               info.lastAccessDate = le16_to_cpu(info.lastAccessDate);
        }
 
        if (info_mask != 0)
index a0c6f5650cf2371be6e23384fd48b7884cb3be94..a26c80381fe1f5b96033cbb94598fe46e65bbc9f 100644 (file)
@@ -2,6 +2,7 @@
  *  ncplib_kernel.c
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -38,7 +39,7 @@ static void
 ncp_add_word(struct ncp_server *server, word x)
 {
        assert_server_locked(server);
-       *(word *)(&(server->packet[server->current_size])) = x;
+       put_unaligned(x, (word *)(&(server->packet[server->current_size])));
        server->current_size += 2;
        return;
 }
@@ -47,7 +48,7 @@ static void
 ncp_add_dword(struct ncp_server *server, dword x)
 {
        assert_server_locked(server);
-       *(dword *)(&(server->packet[server->current_size])) = x;
+       put_unaligned(x, (dword *)(&(server->packet[server->current_size])));
        server->current_size += 4;
        return;
 }
@@ -261,7 +262,7 @@ ncp_obtain_info(struct ncp_server *server,
        ncp_add_byte(server, 6); /* subfunction */
        ncp_add_byte(server, server->name_space[vol_num]);
        ncp_add_byte(server, server->name_space[vol_num]);
-       ncp_add_word(server, 0xff); /* get all */
+       ncp_add_word(server, htons(0xff00)); /* get all */
        ncp_add_dword(server, RIM_ALL);
        ncp_add_handle_path(server, vol_num, dir_base, 1, path);
 
@@ -371,7 +372,7 @@ ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
        ncp_add_byte(server, 7); /* subfunction */
        ncp_add_byte(server, server->name_space[file->volNumber]);
        ncp_add_byte(server, 0); /* reserved */
-       ncp_add_word(server, 0x8006); /* search attribs: all */
+       ncp_add_word(server, htons(0x0680)); /* search attribs: all */
 
        ncp_add_dword(server, info_mask);
        ncp_add_mem(server, info, sizeof(*info));
@@ -393,7 +394,7 @@ ncp_del_file_or_subdir(struct ncp_server *server,
        ncp_add_byte(server, 8); /* subfunction */
        ncp_add_byte(server, server->name_space[dir->volNumber]);
        ncp_add_byte(server, 0); /* reserved */
-       ncp_add_word(server, 0x8006); /* search attribs: all */
+       ncp_add_word(server, ntohs(0x0680)); /* search attribs: all */
        ncp_add_handle_path(server, dir->volNumber,
                            dir->dirEntNum, 1, name);
        
@@ -406,8 +407,8 @@ static inline void
 ConvertToNWfromDWORD ( __u32 sfd , __u8 ret[6] )
 {
     __u16 *dest = (__u16 *) ret;
-    memcpy(&(dest[1]), &sfd, 4);
-    dest[0] = dest[1] + 1;
+    memcpy (ret + 2, &sfd, 4);
+    dest[0] = cpu_to_le16((le16_to_cpu(dest[1]) + le16_to_cpu(1)));
     return;
 }
 
@@ -422,13 +423,13 @@ ncp_open_create_file_or_subdir(struct ncp_server *server,
                               struct nw_file_info *target)
 {
        int result;
-       __u16 search_attribs = 0x0006;
+       __u16 search_attribs = ntohs(0x0600);
        __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber;
 
        if ((create_attributes & aDIR) != 0)
        {
-               search_attribs |= 0x8000;       
-}
+               search_attribs |= ntohs(0x0080);        
+       }
 
        ncp_init_request(server);
        ncp_add_byte(server, 1); /* subfunction */
@@ -546,7 +547,7 @@ ncp_ren_or_mov_file_or_subdir(struct ncp_server *server,
        ncp_add_byte(server, 4); /* subfunction */
        ncp_add_byte(server, server->name_space[old_dir->volNumber]);
        ncp_add_byte(server, 1); /* rename flag */
-       ncp_add_word(server, 0x8006); /* search attributes */
+       ncp_add_word(server, ntohs (0x0680)); /* search attributes */
 
        /* source Handle Path */
        ncp_add_byte(server, old_dir->volNumber);
index f76c2c6661fa614f438773b0acd729eead973877..3f4bd00f65720307438c84afeffdca1feb6d2c42 100644 (file)
@@ -2,6 +2,7 @@
  *  ncplib_kernel.h
  *
  *  Copyright (C) 1995, 1996 by Volker Lendecke
+ *  Modified for big endian by J.F. Chadima and David S. Miller
  *
  */
 
@@ -18,6 +19,8 @@
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include <asm/string.h>
 
 #include <linux/ncp.h>
index 22622f6081bf8a2e32b76025248f5b7b8c56590d..44f5979a33449d9723283fa5179be65d658342cb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: openpromfs.c,v 1.8 1996/12/02 16:04:42 ecd Exp $
+/* $Id: openpromfs.c,v 1.9 1996/12/23 05:54:21 davem Exp $
  * openpromfs.c: /proc/openprom handling routines
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
index 5ffb84f8614d69f016121f7d9c1d148c2d79f95e..3d87796f011cdfa9e747be5845e1576394eb3b24 100644 (file)
@@ -178,17 +178,21 @@ static int do_select(int n, fd_set_buffer *fds)
                for (i = 0 ; i < n ; i++,fd++) {
                        unsigned long bit = BIT(i);
                        unsigned long *in = MEM(i,fds->in);
-                       if (ISSET(bit,__IN(in)) && check(SEL_IN,wait,*fd)) {
+                       struct file * file = *fd;
+
+                       if (!file)
+                               continue;
+                       if (ISSET(bit,__IN(in)) && check(SEL_IN,wait,file)) {
                                SET(bit, __RES_IN(in));
                                retval++;
                                wait = NULL;
                        }
-                       if (ISSET(bit,__OUT(in)) && check(SEL_OUT,wait,*fd)) {
+                       if (ISSET(bit,__OUT(in)) && check(SEL_OUT,wait,file)) {
                                SET(bit, __RES_OUT(in));
                                retval++;
                                wait = NULL;
                        }
-                       if (ISSET(bit,__EX(in)) && check(SEL_EX,wait,*fd)) {
+                       if (ISSET(bit,__EX(in)) && check(SEL_EX,wait,file)) {
                                SET(bit, __RES_EX(in));
                                retval++;
                                wait = NULL;
index ee998a89f13887ace3d937ec27fb06d6f94fa2bf..1fc0cd171d73738c130d0be51515f70d68723801 100644 (file)
@@ -128,7 +128,10 @@ smb_encode_path(struct smb_server *server,
                const char *name, const int len)
 {
        byte *start = p;
-       p = smb_encode_parents(p, dir);
+       if (dir != NULL)
+       {
+               p = smb_encode_parents(p, dir);
+       }
        p = smb_encode_this_name(p, name, len);
        *p++ = 0;
        if (server->protocol <= PROTOCOL_COREPLUS)
@@ -573,7 +576,6 @@ smb_proc_open(struct smb_server *server,
        DPRINTK("smb_proc_open: name=%s\n", name);
 
        smb_lock_server(server);
-       buf = server->packet;
 
        if (entry->opened != 0)
        {
@@ -582,6 +584,7 @@ smb_proc_open(struct smb_server *server,
                return 0;
        }
       retry:
+       buf = server->packet;
        p = smb_setup_header(server, SMBopen, 2, 0);
        WSET(buf, smb_vwv0, 0x42);      /* read/write */
        WSET(buf, smb_vwv1, o_attr);
@@ -732,8 +735,8 @@ smb_proc_create(struct inode *dir, const char *name, int len,
        __u16 fileid;
 
        smb_lock_server(server);
-       buf = server->packet;
       retry:
+       buf = server->packet;
        p = smb_setup_header(server, SMBcreate, 3, 0);
        WSET(buf, smb_vwv0, attr);
        DSET(buf, smb_vwv1, utc2local(ctime));
@@ -764,15 +767,13 @@ smb_proc_mv(struct inode *odir, const char *oname, const int olen,
 {
        char *p;
        struct smb_server *server = SMB_SERVER(odir);
-       char *buf;
        int result;
 
        smb_lock_server(server);
-       buf = server->packet;
 
       retry:
        p = smb_setup_header(server, SMBmv, 1, 0);
-       WSET(buf, smb_vwv0, aSYSTEM | aHIDDEN);
+       WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
        *p++ = 4;
        p = smb_encode_path(server, p, SMB_INOP(odir), oname, olen);
        *p++ = 4;
@@ -825,7 +826,6 @@ smb_proc_rmdir(struct inode *dir, const char *name, const int len)
 
        smb_lock_server(server);
 
-
       retry:
        p = smb_setup_header(server, SMBrmdir, 0, 0);
        *p++ = 4;
@@ -848,15 +848,13 @@ smb_proc_unlink(struct inode *dir, const char *name, const int len)
 {
        char *p;
        struct smb_server *server = SMB_SERVER(dir);
-       char *buf;
        int result;
 
        smb_lock_server(server);
-       buf = server->packet;
 
       retry:
        p = smb_setup_header(server, SMBunlink, 1, 0);
-       WSET(buf, smb_vwv0, aSYSTEM | aHIDDEN);
+       WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
        *p++ = 4;
        p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
        smb_setup_bcc(server, p);
@@ -880,9 +878,9 @@ smb_proc_trunc(struct smb_server *server, word fid, dword length)
        int result;
 
        smb_lock_server(server);
-       buf = server->packet;
 
       retry:
+       buf = server->packet;
        p = smb_setup_header(server, SMBwrite, 5, 0);
        WSET(buf, smb_vwv0, fid);
        WSET(buf, smb_vwv1, 0);
@@ -1011,9 +1009,9 @@ smb_proc_readdir_short(struct smb_server *server, struct inode *dir, int fpos,
        DPRINTK("SMB call  readdir %d @ %d\n", cache_size, fpos);
 
        smb_lock_server(server);
-       buf = server->packet;
 
       retry:
+       buf = server->packet;
        first = 1;
        total_count = 0;
        current_entry = entry;
@@ -1389,11 +1387,11 @@ smb_proc_getattr_core(struct inode *dir, const char *name, int len,
        char *buf;
 
        smb_lock_server(server);
-       buf = server->packet;
 
        DDPRINTK("smb_proc_getattr: %s\n", name);
 
       retry:
+       buf = server->packet;
        p = smb_setup_header(server, SMBgetatr, 0, 0);
        *p++ = 4;
        p = smb_encode_path(server, p, SMB_INOP(dir), name, len);
@@ -1512,9 +1510,9 @@ smb_proc_setattr_core(struct smb_server *server,
        int result;
 
        smb_lock_server(server);
-       buf = server->packet;
 
       retry:
+       buf = server->packet;
        p = smb_setup_header(server, SMBsetatr, 8, 0);
        WSET(buf, smb_vwv0, new_finfo->attr);
        DSET(buf, smb_vwv1, utc2local(new_finfo->f_mtime));
index 59655bc5ac1030ae024830a110624bd42cd7169d..77844e5b0af269bff2c979a4cf790b7ef2d2e128 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be)
  *
- * $Id: ufs_super.c,v 1.20 1996/11/02 18:10:12 ecd Exp $
+ * $Id: ufs_super.c,v 1.21 1996/12/29 20:48:55 davem Exp $
  *
  */
 
diff --git a/include/asm-alpha/current.h b/include/asm-alpha/current.h
new file mode 100644 (file)
index 0000000..9ade4d8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _ALPHA_CURRENT_H
+#define _ALPHA_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.  For an example, see the Sparc implementation where an
+ * entire register is hard locked to contain the value of current.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#endif /* !(_ALPHA_CURRENT_H) */
index a94d1b7ea7ffe2e604e53ea42b4ac1e206e44f4d..6f3f3672ad375de6378331a3ced7adb8249e24b9 100644 (file)
@@ -87,4 +87,7 @@ extern inline void get_mmu_context(struct task_struct *p)
 #endif
 }
 
+#define init_new_context(mm)   do { } while(0)
+#define destroy_context(mm)    do { } while(0)
+
 #endif
index f113dd53529c7709da7c75b7ceac19aa01e0539c..3d4e33bdf45cfb1d8bb592400c9d457fbde0a4fc 100644 (file)
  */
 #define TASK_SIZE (0x40000000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
 /*
  * Bus types
  */
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
new file mode 100644 (file)
index 0000000..9871879
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _ALPHA_SCATTERLIST_H
+#define _ALPHA_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* !(_ALPHA_SCATTERLIST_H) */
index efa0fcb2d97f6a7a5e99697d1f7443991feabbc0..9c534423294c50df826e97b9713934dffb54f7b0 100644 (file)
@@ -85,53 +85,58 @@ struct termio {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-       struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       termios->c_cc[VINTR] = termio->c_cc[_VINTR];
-       termios->c_cc[VQUIT] = termio->c_cc[_VQUIT];
-       termios->c_cc[VERASE]= termio->c_cc[_VERASE];
-       termios->c_cc[VKILL] = termio->c_cc[_VKILL];
-       termios->c_cc[VEOF]  = termio->c_cc[_VEOF];
-       termios->c_cc[VMIN]  = termio->c_cc[_VMIN];
-       termios->c_cc[VEOL]  = termio->c_cc[_VEOL];
-       termios->c_cc[VTIME] = termio->c_cc[_VTIME];
-       termios->c_cc[VEOL2] = termio->c_cc[_VEOL2];
-       termios->c_cc[VSWTC] = termio->c_cc[_VSWTC];
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+       unsigned short __tmp; \
+       get_user(__tmp,&(termio)->x); \
+       *(unsigned short *) &(termios)->x = __tmp; \
 }
 
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+       get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+       get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+       get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+       get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+       get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+       get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+       get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+       get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+       get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+} while(0)
+
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern inline void trans_to_termio(struct termios * termios,
-       struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       termio->c_cc[_VINTR] = termios->c_cc[VINTR];
-       termio->c_cc[_VQUIT] = termios->c_cc[VQUIT];
-       termio->c_cc[_VERASE]= termios->c_cc[VERASE];
-       termio->c_cc[_VKILL] = termios->c_cc[VKILL];
-       termio->c_cc[_VEOF]  = termios->c_cc[VEOF];
-       termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
-       termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
-       termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
-       if (!(termios->c_lflag & ICANON)) {
-               termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-               termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-       }
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line, &(termio)->c_line); \
+       put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+       put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+       put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+       put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+       put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+       put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+       put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+       put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+       if (!((termios)->c_lflag & ICANON)) { \
+               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       } \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-i386/current.h b/include/asm-i386/current.h
new file mode 100644 (file)
index 0000000..01ba3e9
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _I386_CURRENT_H
+#define _I386_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.  For an example, see the Sparc implementation where an
+ * entire register is hard locked to contain the value of current.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#endif /* !(_I386_CURRENT_H) */
index 1f4751cc2ecd33ad8dce646cfb7637e18f4128fc..01b8bfcbacbddc60f6c4b831be86dad67e62aa5b 100644 (file)
@@ -6,4 +6,7 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)   do { } while(0)
+#define destroy_context(mm)    do { } while(0)
+
 #endif
index 55d302ce333e0446549bd8a85553ef3d5e02508c..f3dc8ff762d92a8a9c919bf84b4b135612f6ed15 100644 (file)
@@ -45,6 +45,11 @@ extern unsigned int BIOS_revision;
  */
 #define TASK_SIZE      (0xC0000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
diff --git a/include/asm-i386/scatterlist.h b/include/asm-i386/scatterlist.h
new file mode 100644 (file)
index 0000000..6551ac9
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _I386_SCATTERLIST_H
+#define _I386_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_I386_SCATTERLIST_H) */
index 76551dea9ee53da061ec41a1d061484af1df2457..0125b567880d1a6f943a86ee2f90f4cbaec7aed3 100644 (file)
@@ -21,16 +21,6 @@ struct termio {
        unsigned char c_cc[NCC];        /* control characters */
 };
 
-#ifdef __KERNEL__
-/*     intr=^C         quit=^\         erase=del       kill=^U
-       eof=^D          vtime=\0        vmin=\1         sxtc=\0
-       start=^Q        stop=^S         susp=^Z         eol=\0
-       reprint=^R      discard=^U      werase=^W       lnext=^V
-       eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
 /* modem lines */
 #define TIOCM_LE       0x001
 #define TIOCM_DTR      0x002
@@ -56,36 +46,47 @@ struct termio {
 
 #ifdef __KERNEL__
 
-#include <linux/string.h>
+/*     intr=^C         quit=^\         erase=del       kill=^U
+       eof=^D          vtime=\0        vmin=\1         sxtc=\0
+       start=^Q        stop=^S         susp=^Z         eol=\0
+       reprint=^R      discard=^U      werase=^W       lnext=^V
+       eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
 
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-       struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      (*(unsigned short *)(&x) = (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       memcpy(termios->c_cc, termio->c_cc, NCC);
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+       unsigned short __tmp; \
+       get_user(__tmp,&(termio)->x); \
+       *(unsigned short *) &(termios)->x = __tmp; \
 }
 
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+       SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
+
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-       struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
index 3ed5ab8842065a757e489a9441875973c797b0be..4241771752cfba776190ffe73ee3546738670646 100644 (file)
 #define __NR_iopl              110
 #define __NR_vhangup           111
 #define __NR_idle              112
-#define __NR_vm86              113
+#define __NR_vm86old           113
 #define __NR_wait4             114
 #define __NR_swapoff           115
 #define __NR_sysinfo           116
 #define __NR_mremap            163
 #define __NR_setresuid         164
 #define __NR_getresuid         165
-#define __NR_query_module      166
+#define __NR_vm86              166
+#define __NR_query_module      167
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
 
diff --git a/include/asm-m68k/current.h b/include/asm-m68k/current.h
new file mode 100644 (file)
index 0000000..9d542c7
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.  For an example, see the Sparc implementation where an
+ * entire register is hard locked to contain the value of current.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#endif /* !(_M68K_CURRENT_H) */
index c5def1604750898c16e4309334f15bb365447307..853ce4b71027f9e91e452ac0a4d8f078a9133da3 100644 (file)
@@ -6,4 +6,7 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)   do { } while(0)
+#define destroy_context(mm)    do { } while(0)
+
 #endif
index 408f015e7c714340a3ad778e424e6837ba96f641..1add2d17ffb848ee64be5237c07115b8a707a052 100644 (file)
  */
 #define TASK_SIZE      (0xF0000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
 /*
  * Bus types
  */
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
new file mode 100644 (file)
index 0000000..420beda
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+#ifdef __sparc__
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+#endif
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
index 4bedde47f6f592aab653beafc910dfbf3cd32dc3..4541aabe874f62508d2aea438d9df8500368edce 100644 (file)
@@ -59,31 +59,36 @@ struct termio {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-       struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       memcpy(termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       unsigned short tmp; \
+       get_user(tmp, &(termio)->c_iflag); \
+       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+       get_user(tmp, &(termio)->c_oflag); \
+       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+       get_user(tmp, &(termio)->c_cflag); \
+       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+       get_user(tmp, &(termio)->c_lflag); \
+       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+       get_user((termios)->c_line, &(termio)->c_line); \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-       struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-mips/current.h b/include/asm-mips/current.h
new file mode 100644 (file)
index 0000000..80f435c
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _MIPS_CURRENT_H
+#define _MIPS_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.  For an example, see the Sparc implementation where an
+ * entire register is hard locked to contain the value of current.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#endif /* !(_MIPS_CURRENT_H) */
index b6ba4c03954c28de90cfd3d75f40edb4b71319c8..d685ffb8d85fec3b1b24f93a663563f6282af7d4 100644 (file)
@@ -45,6 +45,11 @@ extern int EISA_bus;
  */
 #define TASK_SIZE      (0x80000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
 /*
  * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
  */
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
new file mode 100644 (file)
index 0000000..9effc1d
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _MIPS_SCATTERLIST_H
+#define _MIPS_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_MIPS_SCATTERLIST_H) */
index 893b98f2a7242328ce145c5f84c875b8ec681207..df016414d7ef8d473f48780241e4e18613fefb7f 100644 (file)
@@ -18,31 +18,36 @@ struct winsize {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-       struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       memcpy(termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       unsigned short tmp; \
+       get_user(tmp, &(termio)->c_iflag); \
+       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+       get_user(tmp, &(termio)->c_oflag); \
+       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+       get_user(tmp, &(termio)->c_cflag); \
+       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+       get_user(tmp, &(termio)->c_lflag); \
+       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+       get_user((termios)->c_line, &(termio)->c_line); \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  */
-extern inline void trans_to_termio(struct termios * termios,
-       struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       memcpy(termio->c_cc, termios->c_cc, NCC);
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line, &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-ppc/current.h b/include/asm-ppc/current.h
new file mode 100644 (file)
index 0000000..d815aaa
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _PPC_CURRENT_H
+#define _PPC_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.  For an example, see the Sparc implementation where an
+ * entire register is hard locked to contain the value of current.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#endif /* !(_PPC_CURRENT_H) */
index 8cee7fb30ca2252400aee0e4ce9a57cea8e680d4..f4bd1e84f0a9bb9c89882e9c57a2c778b2a94633 100644 (file)
@@ -6,5 +6,8 @@
  */
 #define get_mmu_context(x) do { } while (0)
 
+#define init_new_context(mm)   do { } while(0)
+#define destroy_context(mm)    do { } while(0)
+
 #endif
 
index c65884b75d375123e6b6a2410a1f50797647cb20..7ed8c73406f7593b40e506f7a2f1e2221470f7e7 100644 (file)
@@ -85,6 +85,11 @@ extern inline void start_thread(struct pt_regs *, unsigned long, unsigned long )
  */
 #define TASK_SIZE      (0x80000000UL)
 
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+
 struct thread_struct 
 {
   unsigned long        ksp;            /* Kernel stack pointer */
diff --git a/include/asm-ppc/scatterlist.h b/include/asm-ppc/scatterlist.h
new file mode 100644 (file)
index 0000000..80aa3b6
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _PPC_SCATTERLIST_H
+#define _PPC_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+};
+
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#endif /* !(_PPC_SCATTERLIST_H) */
index e3d60b6197c04e508f624d1ddf311cb542377e01..26d88027fe2391050af4f252ac5258443658a391 100644 (file)
@@ -349,53 +349,58 @@ struct termios {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern inline void trans_from_termio(struct termio * termio,
-       struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       termios->c_cc[VINTR] = termio->c_cc[_VINTR];
-       termios->c_cc[VQUIT] = termio->c_cc[_VQUIT];
-       termios->c_cc[VERASE]= termio->c_cc[_VERASE];
-       termios->c_cc[VKILL] = termio->c_cc[_VKILL];
-       termios->c_cc[VEOF]  = termio->c_cc[_VEOF];
-       termios->c_cc[VMIN]  = termio->c_cc[_VMIN];
-       termios->c_cc[VEOL]  = termio->c_cc[_VEOL];
-       termios->c_cc[VTIME] = termio->c_cc[_VTIME];
-       termios->c_cc[VEOL2] = termio->c_cc[_VEOL2];
-       termios->c_cc[VSWTC] = termio->c_cc[_VSWTC];
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       unsigned short tmp; \
+       get_user(tmp, &(termio)->c_iflag); \
+       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+       get_user(tmp, &(termio)->c_oflag); \
+       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+       get_user(tmp, &(termio)->c_cflag); \
+       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+       get_user(tmp, &(termio)->c_lflag); \
+       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+       get_user((termios)->c_line, &(termio)->c_line); \
+       get_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+       get_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+       get_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+       get_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+       get_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+       get_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+       get_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+       get_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       get_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+       get_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern inline void trans_to_termio(struct termios * termios,
-       struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       termio->c_cc[_VINTR] = termios->c_cc[VINTR];
-       termio->c_cc[_VQUIT] = termios->c_cc[VQUIT];
-       termio->c_cc[_VERASE]= termios->c_cc[VERASE];
-       termio->c_cc[_VKILL] = termios->c_cc[VKILL];
-       termio->c_cc[_VEOF]  = termios->c_cc[VEOF];
-       termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
-       termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
-       termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
-       if (1/*!(termios->c_lflag & ICANON)*/) {
-               termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-               termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-       }
-}
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       put_user((termios)->c_cc[VINTR], &(termio)->c_cc[_VINTR]); \
+       put_user((termios)->c_cc[VQUIT], &(termio)->c_cc[_VQUIT]); \
+       put_user((termios)->c_cc[VERASE], &(termio)->c_cc[_VERASE]); \
+       put_user((termios)->c_cc[VKILL], &(termio)->c_cc[_VKILL]); \
+       put_user((termios)->c_cc[VEOF], &(termio)->c_cc[_VEOF]); \
+       put_user((termios)->c_cc[VEOL], &(termio)->c_cc[_VEOL]); \
+       put_user((termios)->c_cc[VEOL2], &(termio)->c_cc[_VEOL2]); \
+       put_user((termios)->c_cc[VSWTC], &(termio)->c_cc[_VSWTC]); \
+       if (1/*!((termios)->c_lflag & ICANON)*/) { \
+               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       } \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
 
 #endif /* __KERNEL__ */
 
index 7da3b700d230996f6108cc293f9538e0680ee9be..9bf9e8ccd78152ab2cca74c09b36771a109b59ed 100644 (file)
@@ -23,9 +23,6 @@ static __inline__ void atomic_add(atomic_t i, atomic_t *v)
 {
        __asm__ __volatile__("
        rd      %%psr, %%g2
-       nop
-       nop
-       nop
        andcc   %%g2, %2, %%g0
        bne     1f
         nop
@@ -54,9 +51,6 @@ static __inline__ void atomic_sub(atomic_t i, atomic_t *v)
 {
        __asm__ __volatile__("
        rd      %%psr, %%g2
-       nop
-       nop
-       nop
        andcc   %%g2, %2, %%g0
        bne     1f
         nop
@@ -85,9 +79,6 @@ static __inline__ int atomic_add_return(atomic_t i, atomic_t *v)
 {
        __asm__ __volatile__("
        rd      %%psr, %%g2
-       nop
-       nop
-       nop
        andcc   %%g2, %3, %%g0
        bne     1f
         nop
@@ -118,9 +109,6 @@ static __inline__ int atomic_sub_return(atomic_t i, atomic_t *v)
 {
        __asm__ __volatile__("
        rd      %%psr, %%g2
-       nop
-       nop
-       nop
        andcc   %%g2, %3, %%g0
        bne     1f
         nop
index 1a1034948f5b17826985539ac6f3b8e730877cda..ccdd92246def2f9d03d0bf69e26071b11c9044ad 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.40 1996/12/23 05:28:49 davem Exp $
+/* $Id: bitops.h,v 1.41 1996/12/28 18:14:25 davem Exp $
  * bitops.h: Bit string operations on the Sparc.
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -104,9 +104,6 @@ extern __inline__ unsigned long set_bit(unsigned long nr, __SMPVOL void *addr)
        mask = 1 << (nr & 31);
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
@@ -143,9 +140,6 @@ extern __inline__ unsigned long clear_bit(unsigned long nr, __SMPVOL void *addr)
        mask = 1 << (nr & 31);
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
@@ -182,9 +176,6 @@ extern __inline__ unsigned long change_bit(unsigned long nr, __SMPVOL void *addr
        mask = 1 << (nr & 31);
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
@@ -335,9 +326,6 @@ extern __inline__ int set_le_bit(int nr,void * addr)
        mask = 1 << (nr & 0x07);
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
@@ -374,9 +362,6 @@ extern __inline__ int clear_le_bit(int nr, void * addr)
        mask = 1 << (nr & 0x07);
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
index f537c5cc3106239028c81ed890f91bd377f1dc5d..f1e694ea62b2bf7a111d0cc67f213ce79647d15e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cache.h,v 1.5 1996/08/29 09:48:06 davem Exp $
+/* $Id: cache.h,v 1.6 1996/12/28 19:55:12 davem Exp $
  * cache.h:  Cache specific code for the Sparc.  These include flushing
  *           and direct tag/data line access.
  *
@@ -10,6 +10,8 @@
 
 #include <asm/asi.h>
 
+#define L1_CACHE_BYTES 32
+
 /* Direct access to the instruction cache is provided through and
  * alternate address space.  The IDC bit must be off in the ICCR on
  * HyperSparcs for these accesses to work.  The code below does not do
diff --git a/include/asm-sparc/current.h b/include/asm-sparc/current.h
new file mode 100644 (file)
index 0000000..254ce56
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _SPARC_CURRENT_H
+#define _SPARC_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+
+/* Sparc rules... */
+register struct task_struct *current asm("g6");
+
+#endif /* !(_SPARC_CURRENT_H) */
index f9074dfae21657bc7b17d27ddfff631db3f2cf04..d104a758cb0cc1ce094b20edb346047d312c40e1 100644 (file)
@@ -9,6 +9,11 @@
 /* Initialize the context related info for a new mm_struct
  * instance.
  */
-#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+extern void (*init_new_context)(struct mm_struct *mm);
+
+/* Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+extern void (*destroy_context)(struct mm_struct *mm);
 
 #endif /* !(__SPARC_MMU_CONTEXT_H) */
index d238f3898a5a97f7550a417302c9b607e2cb6b34..fe45b83263da7039d6c2ae8baaa4df4d166b95f3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.56 1996/12/23 05:28:50 davem Exp $ */
+/* $Id: pgtable.h,v 1.58 1996/12/30 06:17:03 davem Exp $ */
 #ifndef _SPARC_PGTABLE_H
 #define _SPARC_PGTABLE_H
 
@@ -26,10 +26,6 @@ extern void (*quick_kernel_fault)(unsigned long);
    This procedure can be used until the call to mem_init(). */
 extern void *sparc_init_alloc(unsigned long *kbrk, unsigned long size);
 
-/* mmu-specific process creation/cloning/etc hooks. */
-extern void (*mmu_exit_hook)(void);
-extern void (*mmu_flush_hook)(void);
-
 /* translate between physical and virtual addresses */
 extern unsigned long (*mmu_v2p)(unsigned long);
 extern unsigned long (*mmu_p2v)(unsigned long);
@@ -261,8 +257,6 @@ extern void (*pgd_free)(pgd_t *);
 
 extern pgd_t * (*pgd_alloc)(void);
 
-extern void (*pgd_flush)(pgd_t *);
-
 /* Fine grained cache/tlb flushing. */
 
 #ifdef __SMP__
index 882a9b97ab4572abb89757ca2d5bf75d0db057ec..d0b68c8f269cecb9c8639d47d20e3929aec978a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.52 1996/12/03 08:44:56 jj Exp $
+/* $Id: processor.h,v 1.54 1996/12/24 09:19:49 davem Exp $
  * include/asm-sparc/processor.h
  *
  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
@@ -149,9 +149,11 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
                             "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
 }
 
+/* Free all resources held by a thread. */
 #define release_thread(tsk)            do { } while(0)
 
 #ifdef __KERNEL__
+/* Allocation and freeing of basic task resources. */
 extern unsigned long (*alloc_kernel_stack)(struct task_struct *tsk);
 extern void (*free_kernel_stack)(unsigned long stack);
 extern struct task_struct *(*alloc_task_struct)(void);
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
new file mode 100644 (file)
index 0000000..17a4a9f
--- /dev/null
@@ -0,0 +1,16 @@
+/* $Id: scatterlist.h,v 1.1 1996/12/24 07:38:48 davem Exp $ */
+#ifndef _SPARC_SCATTERLIST_H
+#define _SPARC_SCATTERLIST_H
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+};
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif /* !(_SPARC_SCATTERLIST_H) */
index 2cc321d138ae3b61cf155c3d609f655a26134bab..d2e4e7eab49d7e20b36d27fce868177b2d8b0bdd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: signal.h,v 1.29 1996/10/27 08:55:45 davem Exp $ */
+/* $Id: signal.h,v 1.30 1996/12/24 08:59:36 davem Exp $ */
 #ifndef _ASMSPARC_SIGNAL_H
 #define _ASMSPARC_SIGNAL_H
 
@@ -161,17 +161,6 @@ struct sigaction {
        void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
 };
 
-#ifdef __KERNEL__
-
-/* use the following macro to get the size of a sigaction struct
-   when copying to/from userland */
-#define SIGACTION_SIZE(personality) (((personality) & PER_BSD)?\
-                                    sizeof(struct sigaction)-sizeof(void *):\
-                                    sizeof(struct sigaction))
-
-#endif /* __KERNEL__ */
-
-
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(_ASMSPARC_SIGNAL_H) */
index a8c05dd0a222abe3c14b731af15e80644d80f4b8..88621c1c481de1656c600bd566f0fa117284ab1c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.44 1996/12/18 06:56:08 tridge Exp $ */
+/* $Id: system.h,v 1.47 1996/12/30 00:31:12 davem Exp $ */
 #ifndef __SPARC_SYSTEM_H
 #define __SPARC_SYSTEM_H
 
@@ -46,6 +46,7 @@ extern struct linux_romvec *romvec;
  * frames are up to date.
  */
 extern void flush_user_windows(void);
+extern void kill_user_windows(void);
 extern void synchronize_user_stack(void);
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
                   void *fpqueue, unsigned long *fpqdepth);
@@ -88,43 +89,32 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
                switch_to_context(next);                                                \
        task_pc = ((unsigned long) &&here) - 0x8;                                       \
        __asm__ __volatile__(                                                           \
-       "rd\t%%psr, %%g4\n\t"                                                           \
+       "rd     %%psr, %%g4\n\t"                                                        \
+       "std    %%sp, [%%g6 + %3]\n\t"                                                  \
+       "rd     %%wim, %%g5\n\t"                                                        \
+       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
        "nop\n\t"                                                                       \
+       "std    %%g4, [%%g6 + %2]\n\t"                                                  \
+       "ldd    [%1 + %2], %%g4\n\t"                                                    \
+       "mov    %1, %%g6\n\t"                                                           \
+       "st     %1, [%0]\n\t"                                                           \
+       "wr     %%g4, 0x20, %%psr\n\t"                                                  \
        "nop\n\t"                                                                       \
        "nop\n\t"                                                                       \
-       "std\t%%sp, [%%g6 + %3]\n\t"                                                    \
-       "rd\t%%wim, %%g5\n\t"                                                           \
-       "wr\t%%g4, 0x20, %%psr\n\t"                                                     \
+       "ldd    [%%g6 + %3], %%sp\n\t"                                                  \
+       "wr     %%g5, 0x0, %%wim\n\t"                                                   \
+       "ldd    [%%sp + 0x00], %%l0\n\t"                                                \
+       "ldd    [%%sp + 0x38], %%i6\n\t"                                                \
+       "wr     %%g4, 0x0, %%psr\n\t"                                                   \
        "nop\n\t"                                                                       \
        "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "std\t%%g4, [%%g6 + %2]\n\t"                                                    \
-       "mov\t%1, %%g6\n\t"                                                             \
-       "ldd\t[%%g6 + %2], %%g4\n\t"                                                    \
-       "st\t%1, [%0]\n\t"                                                              \
-       "wr\t%%g4, 0x20, %%psr\n\t"                                                     \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "ldd\t[%%g6 + %3], %%sp\n\t"                                                    \
-       "wr\t%%g5, 0x0, %%wim\n\t"                                                      \
-       "ldd\t[%%sp + 0x00], %%l0\n\t"                                                  \
-       "ldd\t[%%sp + 0x08], %%l2\n\t"                                                  \
-       "ldd\t[%%sp + 0x10], %%l4\n\t"                                                  \
-       "ldd\t[%%sp + 0x18], %%l6\n\t"                                                  \
-       "ldd\t[%%sp + 0x20], %%i0\n\t"                                                  \
-       "ldd\t[%%sp + 0x28], %%i2\n\t"                                                  \
-       "ldd\t[%%sp + 0x30], %%i4\n\t"                                                  \
-       "ldd\t[%%sp + 0x38], %%i6\n\t"                                                  \
-       "wr\t%%g4, 0x0, %%psr\n\t"                                                      \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "nop\n\t"                                                                       \
-       "jmpl\t%%o7 + 0x8, %%g0\n\t"                                                    \
+       "jmpl   %%o7 + 0x8, %%g0\n\t"                                                   \
        " nop\n\t" : : "r" (&(current_set[smp_processor_id()])), "r" (next),            \
        "i" ((const unsigned long)(&((struct task_struct *)0)->tss.kpsr)),              \
        "i" ((const unsigned long)(&((struct task_struct *)0)->tss.ksp)),               \
-       "r" (task_pc) : "g4", "g5");                                                    \
+       "r" (task_pc) : "g1", "g2", "g3", "g4", "g5", "g7", "l2", "l3",                 \
+       "l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2",   \
+       "o3");                                                                          \
 here: SWITCH_EXIT } while(0)
 
 /* Changing the IRQ level on the Sparc.   We now avoid writing the psr
@@ -148,9 +138,6 @@ extern __inline__ void cli(void)
 
        __asm__ __volatile__("
                rd      %%psr, %0
-               nop
-               nop
-               nop
                andcc   %0, %1, %%g0
                bne     1f
                 nop
@@ -170,9 +157,6 @@ extern __inline__ void sti(void)
 
        __asm__ __volatile__("
                rd      %%psr, %0
-               nop
-               nop
-               nop
                andcc   %0, %1, %%g0
                be      1f
                 nop
@@ -190,12 +174,7 @@ extern __inline__ unsigned long getipl(void)
 {
        unsigned long retval;
 
-       __asm__ __volatile__("
-               rd      %%psr, %0
-               nop
-               nop
-               nop
-"      : "=r" (retval));
+       __asm__ __volatile__("rd        %%psr, %0" : "=r" (retval));
        return retval;
 }
 
@@ -205,9 +184,6 @@ extern __inline__ unsigned long swap_pil(unsigned long __new_psr)
 
        __asm__ __volatile__("
                rd      %%psr, %0
-               nop
-               nop
-               nop
                and     %0, %4, %1
                and     %3, %4, %2
                xorcc   %1, %2, %%g0
@@ -231,9 +207,6 @@ extern __inline__ unsigned long read_psr_and_cli(void)
 
        __asm__ __volatile__("
                rd      %%psr, %0
-               nop
-               nop
-               nop
                andcc   %0, %1, %%g0
                bne     1f
                 nop
@@ -264,9 +237,6 @@ extern __inline__ unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned
 {
        __asm__ __volatile__("
        rd      %%psr, %%g3
-       nop
-       nop
-       nop
        andcc   %%g3, %3, %%g0
        bne     1f
         nop
index c9b26a890191ecd9f69aa73021da30f7ec4fc444..c893cf32143bd778413a3125da50d447e6da4258 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: termios.h,v 1.21 1996/11/13 02:30:40 davem Exp $ */
+/* $Id: termios.h,v 1.23 1996/12/30 06:17:03 davem Exp $ */
 #ifndef _SPARC_TERMIOS_H
 #define _SPARC_TERMIOS_H
 
@@ -76,8 +76,6 @@ struct winsize {
 #define _VTIME 5
 
 
-#include <linux/string.h>
-
 /*     intr=^C         quit=^\         erase=del       kill=^U
        eof=^D          eol=\0          eol2=\0         sxtc=\0
        start=^Q        stop=^S         susp=^Z         dsusp=^Y
@@ -89,81 +87,72 @@ struct winsize {
 /*
  * Translate a "termio" structure into a "termios". Ugh.
  */
-extern __inline__ void trans_from_termio(struct termio * termio,
-                                        struct termios * termios)
-{
-#define SET_LOW_BITS(x,y)      ((x) = (0xffff0000 & (x)) | (y))
-       SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
-       SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
-       SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
-       SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
-       memcpy (termios->c_cc, termio->c_cc, NCC);
-}
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       unsigned short tmp; \
+       get_user(tmp, &(termio)->c_iflag); \
+       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+       get_user(tmp, &(termio)->c_oflag); \
+       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+       get_user(tmp, &(termio)->c_cflag); \
+       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+       get_user(tmp, &(termio)->c_lflag); \
+       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
 
 /*
  * Translate a "termios" structure into a "termio". Ugh.
  *
  * Note the "fun" _VMIN overloading.
  */
-extern __inline__ void trans_to_termio(struct termios * termios,
-                                      struct termio * termio)
-{
-       termio->c_iflag = termios->c_iflag;
-       termio->c_oflag = termios->c_oflag;
-       termio->c_cflag = termios->c_cflag;
-       termio->c_lflag = termios->c_lflag;
-       termio->c_line  = termios->c_line;
-       memcpy(termio->c_cc, termios->c_cc, NCC);
-       if (!(termios->c_lflag & ICANON)) {
-               termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
-               termio->c_cc[_VTIME] = termios->c_cc[VTIME];
-       }
-}
-
-/* Note that in this case DEST is a user buffer and thus the checking
- * and this ugly macro to avoid header file problems.
- */
-#define termios_to_userland(d, s) \
+#define kernel_termios_to_user_termio(termio, termios) \
 do { \
-       struct termios *dest = (d); \
-       struct termios *source = (s); \
-       put_user(source->c_iflag, &dest->c_iflag); \
-       put_user(source->c_oflag, &dest->c_oflag); \
-       put_user(source->c_cflag, &dest->c_cflag); \
-       put_user(source->c_lflag, &dest->c_lflag); \
-       put_user(source->c_line, &dest->c_line); \
-       copy_to_user(dest->c_cc, source->c_cc, NCCS); \
-       if (!(source->c_lflag & ICANON)){ \
-               put_user(source->c_cc[VMIN], &dest->c_cc[_VMIN]); \
-               put_user(source->c_cc[VTIME], &dest->c_cc[_VTIME]); \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+       if (!((termios)->c_lflag & ICANON)) { \
+               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       } \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) \
+do { \
+       get_user((k)->c_iflag, &(u)->c_iflag); \
+       get_user((k)->c_oflag, &(u)->c_oflag); \
+       get_user((k)->c_cflag, &(u)->c_cflag); \
+       get_user((k)->c_lflag, &(u)->c_lflag); \
+       get_user((k)->c_line,  &(u)->c_line); \
+       copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       if((k)->c_lflag & ICANON) { \
+               get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } else { \
-               put_user(source->c_cc[VEOF], &dest->c_cc[VEOF]); \
-               put_user(source->c_cc[VEOL], &dest->c_cc[VEOL]); \
+               get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } \
 } while(0)
 
-/* termios to termios handling SunOS overloading of eof,eol/vmin,vtime
- * In this case we are only working with kernel buffers so direct
- * accesses are ok.
- */
-extern __inline__ void termios_from_userland(struct termios * source,
-                                            struct termios * dest)
-{
-       dest->c_iflag = source->c_iflag;
-       dest->c_oflag = source->c_oflag;
-       dest->c_cflag = source->c_cflag;
-       dest->c_lflag = source->c_lflag;
-       dest->c_line  = source->c_line;
-       memcpy(dest->c_cc, source->c_cc, NCCS);
-       if (dest->c_lflag & ICANON){
-               dest->c_cc [VEOF] = source->c_cc [VEOF];
-               dest->c_cc [VEOL] = source->c_cc [VEOL];
-       } else {
-               dest->c_cc[VMIN]  = source->c_cc[_VMIN];
-               dest->c_cc[VTIME] = source->c_cc[_VTIME];
-       }
-}
+#define kernel_termios_to_user_termios(u, k) \
+do { \
+       put_user((k)->c_iflag, &(u)->c_iflag); \
+       put_user((k)->c_oflag, &(u)->c_oflag); \
+       put_user((k)->c_cflag, &(u)->c_cflag); \
+       put_user((k)->c_lflag, &(u)->c_lflag); \
+       put_user((k)->c_line, &(u)->c_line); \
+       copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       if(!((k)->c_lflag & ICANON)) { \
+               put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } else { \
+               put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } \
+} while(0)
 
 #endif /* __KERNEL__ */
 
index 34fc6d11e0b155d75bc9c0d8e638783e0fe532c2..8c1658e7481cc8c9c6b02cf7f61d07c8521f12ba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.25 1996/12/18 06:56:10 tridge Exp $ */
+/* $Id: unistd.h,v 1.26 1996/12/29 20:49:14 davem Exp $ */
 #ifndef _SPARC_UNISTD_H
 #define _SPARC_UNISTD_H
 
 #define __NR_aiowait            181 /* SunOS Specific                              */
 #define __NR_aiocancel          182 /* SunOS Specific                              */
 #define __NR_sigpending         183 /* Common                                      */
-/* #define __NR_ni_syscall      184    ENOSYS under SunOS                          */
+#define __NR_query_module       184 /* Linux Specific                              */
 #define __NR_setpgid            185 /* Common                                      */
 #define __NR_pathconf           186 /* SunOS Specific                              */
 #define __NR_fpathconf          187 /* SunOS Specific                              */
index 8813c5c1036302392b26a072a182844e0d9b7d7a..8bdc36ed937fe43765d2ac90f9da31de8a7cb40b 100644 (file)
@@ -1,10 +1,12 @@
-/* $Id: a.out.h,v 1.1 1996/11/20 12:05:19 davem Exp $ */
+/* $Id: a.out.h,v 1.2 1996/12/28 18:39:49 davem Exp $ */
 #ifndef __SPARC64_A_OUT_H__
 #define __SPARC64_A_OUT_H__
 
 #define SPARC_PGSIZE    0x2000        /* Thanks to the sun4 architecture... */
 #define SEGMENT_SIZE    SPARC_PGSIZE  /* whee... */
 
+#ifndef __ASSEMBLY__
+
 struct exec {
        unsigned char a_dynamic:1;      /* A __DYNAMIC is in this image */
        unsigned char a_toolversion:7;
@@ -19,6 +21,8 @@ struct exec {
        unsigned int a_drsize;
 };
 
+#endif __ASSEMBLY__
+
 /* Where in the file does the text information begin? */
 #define N_TXTOFF(x)     (N_MAGIC(x) == ZMAGIC ? 0 : sizeof (struct exec))
 
@@ -41,6 +45,8 @@ struct exec {
 #define N_DRSIZE(a)    ((a).a_drsize)
 #define N_SYMSIZE(a)   ((a).a_syms)
 
+#ifndef __ASSEMBLY__
+
 /*
  * Sparc relocation types
  */
@@ -93,4 +99,6 @@ struct relocation_info /* used when header.a_machtype == M_SPARC */
 
 #endif
 
-#endif /* __SPARC64_A_OUT_H__ */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_A_OUT_H__) */
index 05baf435bf487e113872fa8da095cabedb17554a..23666a685bdaf3291547cbca2588f90ba88b8b86 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.5 1996/12/21 06:09:28 davem Exp $
+/* $Id: bitops.h,v 1.6 1996/12/26 15:36:49 davem Exp $
  * bitops.h: Bit string operations on the V9.
  *
  * Copyright 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -225,10 +225,10 @@ extern __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long
        if (offset >= size)
                return size;
        size -= result;
-       offset &= 31UL;
+       offset &= 63UL;
        if(offset) {
                tmp = *(p++);
-               tmp |= __swab64(~0UL >> (64-offset));
+               tmp |= __swab64((~0UL >> (64-offset)));
                if(size < 64)
                        goto found_first;
                if(~tmp)
@@ -247,9 +247,9 @@ extern __inline__ unsigned long find_next_zero_le_bit(void *addr, unsigned long
        tmp = *p;
 
 found_first:
-       return result + ffz(__swab32(tmp) | (~0UL << size));
+       return result + ffz(__swab64(tmp) | (~0UL << size));
 found_middle:
-       return result + ffz(__swab32(tmp));
+       return result + ffz(__swab64(tmp));
 }
 
 #ifdef __KERNEL__
diff --git a/include/asm-sparc64/bsderrno.h b/include/asm-sparc64/bsderrno.h
new file mode 100644 (file)
index 0000000..52fe880
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: bsderrno.h,v 1.1 1996/12/26 13:25:21 davem Exp $
+ * bsderrno.h: Error numbers for NetBSD binary compatibility
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_BSDERRNO_H
+#define _SPARC64_BSDERRNO_H
+
+#define BSD_EPERM         1      /* Operation not permitted */
+#define BSD_ENOENT        2      /* No such file or directory */
+#define BSD_ESRCH         3      /* No such process */
+#define BSD_EINTR         4      /* Interrupted system call */
+#define BSD_EIO           5      /* Input/output error */
+#define BSD_ENXIO         6      /* Device not configured */
+#define BSD_E2BIG         7      /* Argument list too long */
+#define BSD_ENOEXEC       8      /* Exec format error */
+#define BSD_EBADF         9      /* Bad file descriptor */
+#define BSD_ECHILD        10     /* No child processes */
+#define BSD_EDEADLK       11     /* Resource deadlock avoided */
+#define BSD_ENOMEM        12     /* Cannot allocate memory */
+#define BSD_EACCES        13     /* Permission denied */
+#define BSD_EFAULT        14     /* Bad address */
+#define BSD_ENOTBLK       15     /* Block device required */
+#define BSD_EBUSY         16     /* Device busy */
+#define BSD_EEXIST        17     /* File exists */
+#define BSD_EXDEV         18     /* Cross-device link */
+#define BSD_ENODEV        19     /* Operation not supported by device */
+#define BSD_ENOTDIR       20     /* Not a directory */
+#define BSD_EISDIR        21     /* Is a directory */
+#define BSD_EINVAL        22     /* Invalid argument */
+#define BSD_ENFILE        23     /* Too many open files in system */
+#define BSD_EMFILE        24     /* Too many open files */
+#define BSD_ENOTTY        25     /* Inappropriate ioctl for device */
+#define BSD_ETXTBSY       26     /* Text file busy */
+#define BSD_EFBIG         27     /* File too large */
+#define BSD_ENOSPC        28     /* No space left on device */
+#define BSD_ESPIPE        29     /* Illegal seek */
+#define BSD_EROFS         30     /* Read-only file system */
+#define BSD_EMLINK        31     /* Too many links */
+#define BSD_EPIPE         32     /* Broken pipe */
+#define BSD_EDOM          33     /* Numerical argument out of domain */
+#define BSD_ERANGE        34     /* Result too large */
+#define BSD_EAGAIN        35     /* Resource temporarily unavailable */
+#define BSD_EWOULDBLOCK   EAGAIN /* Operation would block */
+#define BSD_EINPROGRESS   36     /* Operation now in progress */
+#define BSD_EALREADY      37     /* Operation already in progress */
+#define BSD_ENOTSOCK      38     /* Socket operation on non-socket */
+#define BSD_EDESTADDRREQ  39     /* Destination address required */
+#define BSD_EMSGSIZE      40     /* Message too long */
+#define BSD_EPROTOTYPE    41     /* Protocol wrong type for socket */
+#define BSD_ENOPROTOOPT   42     /* Protocol not available */
+#define BSD_EPROTONOSUPPORT  43  /* Protocol not supported */
+#define BSD_ESOCKTNOSUPPORT  44  /* Socket type not supported */
+#define BSD_EOPNOTSUPP    45     /* Operation not supported */
+#define BSD_EPFNOSUPPORT  46     /* Protocol family not supported */
+#define BSD_EAFNOSUPPORT  47     /* Address family not supported by protocol family */
+#define BSD_EADDRINUSE    48     /* Address already in use */
+#define BSD_EADDRNOTAVAIL 49     /* Can't assign requested address */
+#define BSD_ENETDOWN      50     /* Network is down */
+#define BSD_ENETUNREACH   51     /* Network is unreachable */
+#define BSD_ENETRESET     52     /* Network dropped connection on reset */
+#define BSD_ECONNABORTED  53     /* Software caused connection abort */
+#define BSD_ECONNRESET    54     /* Connection reset by peer */
+#define BSD_ENOBUFS       55     /* No buffer space available */
+#define BSD_EISCONN       56     /* Socket is already connected */
+#define BSD_ENOTCONN      57     /* Socket is not connected */
+#define BSD_ESHUTDOWN     58     /* Can't send after socket shutdown */
+#define BSD_ETOOMANYREFS  59     /* Too many references: can't splice */
+#define BSD_ETIMEDOUT     60     /* Operation timed out */
+#define BSD_ECONNREFUSED  61     /* Connection refused */
+#define BSD_ELOOP         62     /* Too many levels of symbolic links */
+#define BSD_ENAMETOOLONG  63     /* File name too long */
+#define BSD_EHOSTDOWN     64     /* Host is down */
+#define BSD_EHOSTUNREACH  65     /* No route to host */
+#define BSD_ENOTEMPTY     66     /* Directory not empty */
+#define BSD_EPROCLIM      67     /* Too many processes */
+#define BSD_EUSERS        68     /* Too many users */
+#define BSD_EDQUOT        69     /* Disc quota exceeded */
+#define BSD_ESTALE        70     /* Stale NFS file handle */
+#define BSD_EREMOTE       71     /* Too many levels of remote in path */
+#define BSD_EBADRPC       72     /* RPC struct is bad */
+#define BSD_ERPCMISMATCH  73     /* RPC version wrong */
+#define BSD_EPROGUNAVAIL  74     /* RPC prog. not avail */
+#define BSD_EPROGMISMATCH 75     /* Program version wrong */
+#define BSD_EPROCUNAVAIL  76     /* Bad procedure for program */
+#define BSD_ENOLCK        77     /* No locks available */
+#define BSD_ENOSYS        78     /* Function not implemented */
+#define BSD_EFTYPE        79     /* Inappropriate file type or format */
+#define BSD_EAUTH         80     /* Authentication error */
+#define BSD_ENEEDAUTH     81     /* Need authenticator */
+#define BSD_ELAST         81     /* Must be equal largest errno */
+
+#endif /* !(_SPARC64_BSDERRNO_H) */
diff --git a/include/asm-sparc64/bugs.h b/include/asm-sparc64/bugs.h
new file mode 100644 (file)
index 0000000..9e2214b
--- /dev/null
@@ -0,0 +1,7 @@
+/*  $Id: bugs.h,v 1.1 1996/12/26 13:25:20 davem Exp $
+ *  include/asm-sparc64/bugs.h:  Sparc probes for various bugs.
+ *
+ *  Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+static void check_bugs(void) { }
index b4040cd4e500200aa79fd1ba82884d6aa28c6900..95a26dfa84c7b672ef46ac5b2a794c0f3c131ebe 100644 (file)
@@ -1,17 +1,17 @@
-/* $Id: byteorder.h,v 1.1 1996/11/20 14:01:53 davem Exp $ */
+/* $Id: byteorder.h,v 1.2 1996/12/26 13:25:23 davem Exp $ */
 #ifndef _SPARC64_BYTEORDER_H
 #define _SPARC64_BYTEORDER_H
 
-#define ntohl(x) x
-#define ntohs(x) x
-#define htonl(x) x
-#define htons(x) x
+extern __inline__ unsigned long int ntohl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int ntohs(unsigned short int x) { return x; }
+extern __inline__ unsigned long int htonl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int htons(unsigned short int x) { return x; }
 
 /* Some programs depend upon these being around. */
-#define __constant_ntohl(x) x
-#define __constant_ntohs(x) x
-#define __constant_htonl(x) x
-#define __constant_htons(x) x
+extern __inline__ unsigned long int __constant_ntohl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int __constant_ntohs(unsigned short int x) { return x; }
+extern __inline__ unsigned long int __constant_htonl(unsigned long int x) { return x; }
+extern __inline__ unsigned short int __constant_htons(unsigned short int x) { return x; }
 
 #ifndef __BIG_ENDIAN
 #define __BIG_ENDIAN 4321
diff --git a/include/asm-sparc64/current.h b/include/asm-sparc64/current.h
new file mode 100644 (file)
index 0000000..8cdfc61
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _SPARC64_CURRENT_H
+#define _SPARC64_CURRENT_H
+
+/* Some architectures may want to do something "clever" here since
+ * this is the most frequently accessed piece of data in the entire
+ * kernel.
+ */
+extern struct task_struct *current_set[NR_CPUS];
+
+/* Sparc rules... */
+register struct task_struct *current asm("g6");
+
+#endif /* !(_SPARC64_CURRENT_H) */
index 732bca1b60016d3712f2698ed4183032183c592b..813128d0ee43c84ff09dbe41f3f3773d61e1c569 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: dma.h,v 1.1 1996/11/20 15:27:38 davem Exp $
+/* $Id: dma.h,v 1.2 1996/12/26 13:25:24 davem Exp $
  * include/asm-sparc64/dma.h
  *
- * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
  */
 
 #ifndef _ASM_SPARC64_DMA_H
@@ -9,7 +9,6 @@
 
 #include <linux/kernel.h>
 
-#include <asm/vac-ops.h>  /* for invalidate's, etc. */
 #include <asm/sbus.h>
 #include <asm/delay.h>
 #include <asm/oplib.h>
@@ -18,7 +17,7 @@
  * things can compile.
  */
 #define MAX_DMA_CHANNELS 8
-#define MAX_DMA_ADDRESS  (~0UL)
+#define MAX_DMA_ADDRESS  ((0x100000000) + PAGE_OFFSET)
 #define DMA_MODE_READ    1
 #define DMA_MODE_WRITE   2
 
@@ -165,40 +164,6 @@ extern unsigned long dvma_init(struct linux_sbus *, unsigned long);
        if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
    } while(0)
 
-/* Pause until counter runs out or BIT isn't set in the DMA condition
- * register.
- */
-extern __inline__ void sparc_dma_pause(struct sparc_dma_registers *regs,
-                                      unsigned long bit)
-{
-       int ctr = 50000;   /* Let's find some bugs ;) */
-
-       /* Busy wait until the bit is not set any more */
-       while((regs->cond_reg&bit) && (ctr>0)) {
-               ctr--;
-               __delay(5);
-       }
-
-       /* Check for bogus outcome. */
-       if(!ctr)
-               panic("DMA timeout");
-}
-
-/* Reset the friggin' thing... */
-#define DMA_RESET(dma) do { \
-       struct sparc_dma_registers *regs = dma->regs;                      \
-       /* Let the current FIFO drain itself */                            \
-       sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN));                         \
-       /* Reset the logic */                                              \
-       regs->cond_reg |= (DMA_RST_SCSI);     /* assert */                 \
-       __delay(400);                         /* let the bits set ;) */    \
-       regs->cond_reg &= ~(DMA_RST_SCSI);    /* de-assert */              \
-       sparc_dma_enable_interrupts(regs);    /* Re-enable interrupts */   \
-       /* Enable FAST transfers if available */                           \
-       if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS;            \
-       dma->running = 0;                                                  \
-} while(0)
-
 #define for_each_dvma(dma) \
         for((dma) = dma_chain; (dma); (dma) = (dma)->next)
 
index 0fff3de9ca5c5b942b0c619bf26352ecfa81bc4d..a81b588b2bb2737965943decabb53fc2483c427b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.1 1996/11/20 15:27:38 davem Exp $ */
+/* $Id: elf.h,v 1.2 1996/12/26 13:25:25 davem Exp $ */
 #ifndef __ASM_SPARC64_ELF_H
 #define __ASM_SPARC64_ELF_H
 
@@ -23,8 +23,8 @@ typedef unsigned long elf_fpregset_t;
 /*
  * These are used to set parameters in the core dumps.
  */
-#define ELF_ARCH       EM_SPARC
-#define ELF_CLASS      ELFCLASS32
+#define ELF_ARCH       EM_SPARC64
+#define ELF_CLASS      ELFCLASS64
 #define ELF_DATA       ELFDATA2MSB;
 
 #define USE_ELF_CORE_DUMP
diff --git a/include/asm-sparc64/head.h b/include/asm-sparc64/head.h
new file mode 100644 (file)
index 0000000..5680053
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id: head.h,v 1.2 1996/12/28 18:39:49 davem Exp $ */
+#ifndef _SPARC64_HEAD_H
+#define _SPARC64_HEAD_H
+
+#define BOOT_KERNEL b sparc64_boot; nop; nop; nop; nop; nop; nop; nop;
+
+#define BTRAP(lvl)
+
+#define BTRAPTL1(lvl)
+
+#define CLEAN_WINDOW                                                   \
+       clr     %o0;    clr     %o1;    clr     %o2;    clr     %o3;    \
+       clr     %o4;    clr     %o5;    clr     %o6;    clr     %o7;    \
+       clr     %l0;    clr     %l1;    clr     %l2;    clr     %l3;    \
+       clr     %l4;    clr     %l5;    clr     %l6;    clr     %l7;    \
+       rdpr %cleanwin, %g1;            add %g1, 1, %g1;                \
+       wrpr %g1, 0x0, %cleanwin;       retry;                          \
+       nop;            nop;            nop;            nop;
+
+#define TRAP(routine)                  \
+       b       etrap;                  \
+        rd     %pc, %g7;               \
+       call    routine;                \
+        add    %sp, REGWIN_SZ, %o0;    \
+       b       rtrap;                  \
+        subcc  %g0, %o0, %g0;          \
+       nop;                            \
+       nop;
+
+#define TRAP_IRQ(routine, level)       \
+       b       etrap;                  \
+        rd     %pc, %g7;               \
+       add     %sp, REGWIN_SZ, %o0;    \
+       call    routine;                \
+        mov    level, %o1;             \
+       b       rtrap;                  \
+        subcc  %g0, %o0, %g0;          \
+       nop;
+
+#endif /* !(_SPARC64_HEAD_H) */
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h
new file mode 100644 (file)
index 0000000..8cea57e
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id: io.h,v 1.1 1996/12/26 13:25:21 davem Exp $ */
+#ifndef __SPARC64_IO_H
+#define __SPARC64_IO_H
+
+#include <linux/kernel.h>
+
+#include <asm/page.h>      /* IO address mapping routines need this */
+#include <asm/system.h>
+
+extern void sun4c_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+extern void srmmu_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
+
+extern __inline__ void mapioaddr(unsigned long physaddr, unsigned long virt_addr,
+                                int bus, int rdonly)
+{
+       switch(sparc_cpu_model) {
+       case sun4c:
+               sun4c_mapioaddr(physaddr, virt_addr, bus, rdonly);
+               break;
+       case sun4m:
+       case sun4d:
+       case sun4e:
+               srmmu_mapioaddr(physaddr, virt_addr, bus, rdonly);
+               break;
+       default:
+               printk("mapioaddr: Trying to map IO space for unsupported machine.\n");
+               printk("mapioaddr: sparc_cpu_model = %d\n", sparc_cpu_model);
+               printk("mapioaddr: Halting...\n");
+               halt();
+       };
+       return;
+}
+
+extern void srmmu_unmapioaddr(unsigned long virt);
+extern void sun4c_unmapioaddr(unsigned long virt);
+
+extern __inline__ void unmapioaddr(unsigned long virt_addr)
+{
+       switch(sparc_cpu_model) {
+       case sun4c:
+               sun4c_unmapioaddr(virt_addr);
+               break;
+       case sun4m:
+       case sun4d:
+       case sun4e:
+               srmmu_unmapioaddr(virt_addr);
+               break;
+       default:
+               printk("unmapioaddr: sparc_cpu_model = %d, halt...\n", sparc_cpu_model);
+               halt();
+       };
+       return;
+}
+
+extern void *sparc_alloc_io (void *, void *, int, char *, int, int);
+extern void sparc_free_io (void *, int);
+extern void *sparc_dvma_malloc (int, char *);
+
+#define virt_to_phys(x) __pa((unsigned long)(x))
+#define phys_to_virt(x) __va((unsigned long)(x))
+
+#endif /* !(__SPARC64_IO_H) */
diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h
new file mode 100644 (file)
index 0000000..7d5f6f8
--- /dev/null
@@ -0,0 +1,73 @@
+/* iommu.h: Definitions for the sun5 IOMMU.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC64_IOMMU_H
+#define _SPARC64_IOMMU_H
+
+#include <asm/page.h>
+
+/* The iommu handles all virtual to physical address translations
+ * that occur between the SYSIO and physical memory.  Access by
+ * the cpu to IO registers and similar go over the UPA so are
+ * translated by the on chip TLB's.  The iommu and the TLB do
+ * not need to have the same translations at all, in fact most
+ * of the time the translations they handle are a disjoint set.
+ * Basically the iommu handles all SYSIO dvma translations.
+ */
+
+/* The IOMMU register set. */
+struct iommu_regs {
+       volatile unsigned long          csr;
+       volatile unsigned long          tsb_base;
+       volatile unsigned long          flush;
+       unsigned char _unused0[PAGE_SIZE - 0x18];
+
+       volatile unsigned long          va_diag;
+       volatile unsigned long          tag_compare;
+       unsigned char _unused1[0x100 - 0x10];
+
+       volatile unsigned long          lru_diag[0x80  / 8];
+       volatile unsigned long          tag_diag[0x80  / 8];
+       volatile unsigned long          ram_diag[0x100 / 8];
+};
+
+#define IOMMU_CTRL_IMPL     0xf000000000000000 /* Implementation                */
+#define IOMMU_CTRL_VERS     0x0f00000000000000 /* Version                       */
+#define IOMMU_CTRL_TSBSZ    0x0000000000070000 /* TSB Size                      */
+#define IOMMU_TSBSZ_1K      0x0000000000000000 /* TSB Table 1024 8-byte entries */
+#define IOMMU_TSBSZ_2K      0x0000000000010000 /* TSB Table 2048 8-byte entries */
+#define IOMMU_TSBSZ_4K      0x0000000000020000 /* TSB Table 4096 8-byte entries */
+#define IOMMU_TSBSZ_8K      0x0000000000030000 /* TSB Table 8192 8-byte entries */
+#define IOMMU_TSBSZ_16K     0x0000000000040000 /* TSB Table 16k 8-byte entries  */
+#define IOMMU_TSBSZ_32K     0x0000000000050000 /* TSB Table 32k 8-byte entries  */
+#define IOMMU_TSBSZ_64K     0x0000000000060000 /* TSB Table 64k 8-byte entries  */
+#define IOMMU_TSBSZ_128K    0x0000000000070000 /* TSB Table 128k 8-byte entries */
+#define IOMMU_CTRL_TBWSZ    0x0000000000000004 /* Assumed page size, 0=8k 1=64k */
+#define IOMMU_CTRL_DENAB    0x0000000000000002 /* Diagnostic mode enable        */
+#define IOMMU_CTRL_ENAB     0x0000000000000001 /* IOMMU Enable                  */
+
+/* The format of an iopte in the page tables, we only use 64k pages. */
+#define IOPTE_VALID         0x8000000000000000 /* IOPTE is valid                   */
+#define IOPTE_64K           0x2000000000000000 /* IOPTE is for 64k page            */
+#define IOPTE_STBUF         0x1000000000000000 /* DVMA can use streaming buffer    */
+#define IOPTE_INTRA         0x0800000000000000 /* XXX what does this thing do?     */
+#define IOPTE_PAGE          0x000001ffffffe000 /* Physical page number (PA[40:13]) */
+#define IOPTE_CACHE         0x0000000000000010 /* Cached (in UPA E-cache)          */
+#define IOPTE_WRITE         0x0000000000000002 /* Writeable                        */
+
+struct iommu_struct {
+       struct iommu_regs *regs;
+       iopte_t *page_table;
+
+       /* For convenience */
+       unsigned long start; /* First managed virtual address */
+       unsigned long end;   /* Last managed virtual address */
+};
+
+extern __inline__ void iommu_invalidate_page(struct iommu_regs *regs, unsigned long page)
+{
+       regs->flush = (page & (PAGE_MASK << 3));
+}
+
+#endif /* !(_SPARC_IOMMU_H) */
diff --git a/include/asm-sparc64/ipc.h b/include/asm-sparc64/ipc.h
new file mode 100644 (file)
index 0000000..6951069
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __SPARC64_IPC_H__
+#define __SPARC64_IPC_H__
+
+/* 
+ * These are used to wrap system calls on the sparc.
+ *
+ * See arch/sparc64/kernel/sys_sparc.c for ugly details..
+ */
+struct ipc_kludge {
+       struct msgbuf *msgp;
+       long msgtyp;
+};
+
+#define SEMOP           1
+#define SEMGET          2
+#define SEMCTL          3
+#define MSGSND         11
+#define MSGRCV         12
+#define MSGGET         13
+#define MSGCTL         14
+#define SHMAT          21
+#define SHMDT          22
+#define SHMGET         23
+#define SHMCTL         24
+
+#define IPCCALL(version,op)    ((version)<<16 | (op))
+
+#endif
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
new file mode 100644 (file)
index 0000000..d5b1115
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id: irq.h,v 1.1 1996/12/26 17:28:13 davem Exp $
+ * irq.h: IRQ registers on the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* XXX Write the sun5 specific code... XXX */
+
+#ifndef _SPARC64_IRQ_H
+#define _SPARC64_IRQ_H
+
+#include <linux/linkage.h>
+
+#include <asm/system.h>     /* For NCPUS */
+
+#define NR_IRQS    15
+
+/* Dave Redman (djhr@tadpole.co.uk)
+ * changed these to function pointers.. it saves cycles and will allow
+ * the irq dependencies to be split into different files at a later date
+ * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
+ */
+extern void (*disable_irq)(unsigned int);
+extern void (*enable_irq)(unsigned int);
+extern void (*clear_clock_irq)( void );
+extern void (*clear_profile_irq)( void );
+extern void (*load_profile_irq)( unsigned int timeout );
+extern void (*init_timers)(void (*lvl10_irq)(int, void *, struct pt_regs *));
+extern void claim_ticker14(void (*irq_handler)(int, void *, struct pt_regs *),
+                          int irq,
+                          unsigned int timeout);
+
+#ifdef __SMP__
+extern void (*set_cpu_int)(int, int);
+extern void (*clear_cpu_int)(int, int);
+extern void (*set_irq_udt)(int);
+#endif
+
+extern int request_fast_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, __const__ char *devname);
+
+#endif
diff --git a/include/asm-sparc64/lsu.h b/include/asm-sparc64/lsu.h
new file mode 100644 (file)
index 0000000..a9f7738
--- /dev/null
@@ -0,0 +1,18 @@
+/* $Id */
+#ifndef _SPARC64_LSU_H
+#define _SPARC64_LSU_H
+
+/* LSU Control Register */
+#define LSU_CONTROL_PM         0x000001fe00000000 /* Phys-watchpoint byte mask     */
+#define LSU_CONTROL_VM         0x00000001fe000000 /* Virt-watchpoint byte mask     */
+#define LSU_CONTROL_PR         0x0000000001000000 /* Phys-read watchpoint enable   */
+#define LSU_CONTROL_PW         0x0000000000800000 /* Phys-write watchpoint enable  */
+#define LSU_CONTROL_VR         0x0000000000400000 /* Virt-read watchpoint enable   */
+#define LSU_CONTROL_VW         0x0000000000200000 /* Virt-write watchpoint enable  */
+#define LSU_CONTROL_FM         0x00000000000ffff0 /* Parity mask enables.          */
+#define LSU_CONTROL_DM         0x0000000000000008 /* Data MMU enable.              */
+#define LSU_CONTROL_IM         0x0000000000000004 /* Instruction MMU enable.       */
+#define LSU_CONTROL_DC         0x0000000000000002 /* Data cache enable.            */
+#define LSU_CONTROL_IC         0x0000000000000001 /* Instruction cache enable.     */
+
+#endif /* !(_SPARC64_LSU_H) */
diff --git a/include/asm-sparc64/mmu_context.h b/include/asm-sparc64/mmu_context.h
new file mode 100644 (file)
index 0000000..43fb99c
--- /dev/null
@@ -0,0 +1,36 @@
+/* $Id: mmu_context.h,v 1.4 1996/12/28 18:39:51 davem Exp $ */
+#ifndef __SPARC64_MMU_CONTEXT_H
+#define __SPARC64_MMU_CONTEXT_H
+
+#include <asm/system.h>
+#include <asm/spitfire.h>
+
+#define NO_CONTEXT     -1
+
+#ifndef __ASSEMBLY__
+
+/* Initialize the context related info for a new mm_struct
+ * instance.
+ */
+#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+
+extern void spitfire_get_new_context(struct mm_struct *mm);
+
+extern __inline__ void get_mmu_context(struct task_struct *tsk)
+{
+       struct mm_struct *mm = tsk->mm;
+
+       if(tsk->mm->context == NO_CONTEXT)
+               spitfire_get_new_context(mm);
+
+       /* Get current set of user windows out of the cpu. */
+       flushw_user();
+
+       /* Jump into new ASN. */
+       spitfire_set_primary_context(mm->context);
+       spitfire_set_secondary_context(mm->context);
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_MMU_CONTEXT_H) */
diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h
new file mode 100644 (file)
index 0000000..d905795
--- /dev/null
@@ -0,0 +1,120 @@
+/* $Id: mostek.h,v 1.1 1996/12/26 13:25:22 davem Exp $
+ * mostek.h:  Describes the various Mostek time of day clock registers.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _SPARC64_MOSTEK_H
+#define _SPARC64_MOSTEK_H
+
+#include <asm/idprom.h>
+
+/*       M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
+ *
+ *                             Data
+ * Address                                                 Function
+ *        Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
+ *   7ff  -     -     -     -    -     -     -     -       Year 00-99
+ *   7fe  0     0     0     -    -     -     -     -      Month 01-12
+ *   7fd  0     0     -     -    -     -     -     -       Date 01-31
+ *   7fc  0     FT    0     0    0     -     -     -        Day 01-07
+ *   7fb  KS    0     -     -    -     -     -     -      Hours 00-23
+ *   7fa  0     -     -     -    -     -     -     -    Minutes 00-59
+ *   7f9  ST    -     -     -    -     -     -     -    Seconds 00-59
+ *   7f8  W     R     S     -    -     -     -     -    Control
+ *
+ *   * ST is STOP BIT
+ *   * W is WRITE BIT
+ *   * R is READ BIT
+ *   * S is SIGN BIT
+ *   * FT is FREQ TEST BIT
+ *   * KS is KICK START BIT
+ */
+
+/* The Mostek 48t02 real time clock and NVRAM chip. The registers
+ * other than the control register are in binary coded decimal. Some
+ * control bits also live outside the control register.
+ */
+
+struct mostek48t02 {
+       volatile char eeprom[2008];     /* This is the eeprom, don't touch! */
+       struct idprom idprom;           /* The idprom lives here. */
+       volatile unsigned char creg;    /* Control register */
+       volatile unsigned char sec;     /* Seconds (0-59) */
+       volatile unsigned char min;     /* Minutes (0-59) */
+       volatile unsigned char hour;    /* Hour (0-23) */
+       volatile unsigned char dow;     /* Day of the week (1-7) */
+       volatile unsigned char dom;     /* Day of the month (1-31) */
+       volatile unsigned char month;   /* Month of year (1-12) */
+       volatile unsigned char year;    /* Year (0-99) */
+};
+
+extern struct mostek48t02 *mstk48t02_regs;
+
+/* Control register values. */
+#define        MSTK_CREG_WRITE 0x80    /* Must set this before placing values. */
+#define        MSTK_CREG_READ  0x40    /* Stop updates to allow a clean read. */
+#define        MSTK_CREG_SIGN  0x20    /* Slow/speed clock in calibration mode. */
+
+/* Control bits that live in the other registers. */
+#define        MSTK_STOP       0x80    /* Stop the clock oscillator. (sec) */
+#define        MSTK_KICK_START 0x80    /* Kick start the clock chip. (hour) */
+#define MSTK_FREQ_TEST 0x40    /* Frequency test mode. (day) */
+
+#define MSTK_YEAR_ZERO       1968   /* If year reg has zero, it is 1968. */
+#define MSTK_CVT_YEAR(yr)  ((yr) + MSTK_YEAR_ZERO)
+
+/* Masks that define how much space each value takes up. */
+#define        MSTK_SEC_MASK   0x7f
+#define        MSTK_MIN_MASK   0x7f
+#define        MSTK_HOUR_MASK  0x3f
+#define        MSTK_DOW_MASK   0x07
+#define        MSTK_DOM_MASK   0x3f
+#define        MSTK_MONTH_MASK 0x1f
+#define        MSTK_YEAR_MASK  0xff
+
+/* Binary coded decimal conversion macros. */
+#define MSTK_REGVAL_TO_DECIMAL(x)  (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
+#define MSTK_DECIMAL_TO_REGVAL(x)  ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
+
+/* Generic register set and get macros for internal use. */
+#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(regs->var & MSTK_ ## mask ## _MASK))
+#define MSTK_SET(regs,var,value,mask) do { regs->var &= ~(MSTK_ ## mask ## _MASK); regs->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
+
+/* Macros to make register access easier on our fingers. These give you
+ * the decimal value of the register requested if applicable. You pass
+ * the a pointer to a 'struct mostek48t02'.
+ */
+#define        MSTK_REG_CREG(regs)     (regs->creg)
+#define        MSTK_REG_SEC(regs)      MSTK_GET(regs,sec,SEC)
+#define        MSTK_REG_MIN(regs)      MSTK_GET(regs,min,MIN)
+#define        MSTK_REG_HOUR(regs)     MSTK_GET(regs,hour,HOUR)
+#define        MSTK_REG_DOW(regs)      MSTK_GET(regs,dow,DOW)
+#define        MSTK_REG_DOM(regs)      MSTK_GET(regs,dom,DOM)
+#define        MSTK_REG_MONTH(regs)    MSTK_GET(regs,month,MONTH)
+#define        MSTK_REG_YEAR(regs)     MSTK_GET(regs,year,YEAR)
+
+#define        MSTK_SET_REG_SEC(regs,value)    MSTK_SET(regs,sec,value,SEC)
+#define        MSTK_SET_REG_MIN(regs,value)    MSTK_SET(regs,min,value,MIN)
+#define        MSTK_SET_REG_HOUR(regs,value)   MSTK_SET(regs,hour,value,HOUR)
+#define        MSTK_SET_REG_DOW(regs,value)    MSTK_SET(regs,dow,value,DOW)
+#define        MSTK_SET_REG_DOM(regs,value)    MSTK_SET(regs,dom,value,DOM)
+#define        MSTK_SET_REG_MONTH(regs,value)  MSTK_SET(regs,month,value,MONTH)
+#define        MSTK_SET_REG_YEAR(regs,value)   MSTK_SET(regs,year,value,YEAR)
+
+
+/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
+ * same (basically) layout of the 48t02 chip except for the extra
+ * NVRAM on board (8 KB against the 48t02's 2 KB).
+ */
+struct mostek48t08 {
+       char offset[6*1024];         /* Magic things may be here, who knows? */
+       struct mostek48t02 regs;     /* Here is what we are interested in.   */
+};
+extern struct mostek48t08 *mstk48t08_regs;
+
+enum sparc_clock_type {        MSTK48T02, MSTK48T08, MSTK_INVALID };
+extern enum sparc_clock_type sp_clock_typ;
+
+#endif /* !(_SPARC64_MOSTEK_H) */
diff --git a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h
new file mode 100644 (file)
index 0000000..c458d46
--- /dev/null
@@ -0,0 +1,56 @@
+/* $Id: namei.h,v 1.1 1996/12/26 13:25:22 davem Exp $
+ * linux/include/asm-sparc64/namei.h
+ *
+ * Routines to handle famous /usr/gnemul/s*.
+ * Included from linux/fs/namei.c
+ */
+
+#ifndef __SPARC64_NAMEI_H
+#define __SPARC64_NAMEI_H
+
+#define SPARC_BSD_EMUL "usr/gnemul/sunos/"
+#define SPARC_SOL_EMUL "usr/gnemul/solaris/"
+
+#define gnemul_namei(pathname, base, follow_links, res_inode) ({                       \
+ if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {       \
+       struct inode *emul_ino;                                                         \
+       int namelen;                                                                    \
+       const char *name;                                                               \
+                                                                                       \
+       while (*pathname == '/')                                                        \
+               pathname++;                                                             \
+       current->fs->root->i_count++;                                                   \
+       if (dir_namei (current->personality & PER_BSD ? SPARC_BSD_EMUL : SPARC_SOL_EMUL,\
+               &namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) {      \
+                       *res_inode = NULL;                                              \
+                       if (_namei (pathname, emul_ino, follow_links, res_inode) >= 0 &&\
+                                       *res_inode)                                     \
+                               return 0;                                               \
+       }                                                                               \
+       base = current->fs->root;                                                       \
+       base->i_count++;                                                                \
+  }                                                                                    \
+})
+
+#define gnemul_open_namei(pathname, flag, mode, res_inode, base) ({                    \
+  if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') {      \
+       struct inode *emul_ino;                                                         \
+       int namelen;                                                                    \
+       const char *name;                                                               \
+                                                                                       \
+       while (*pathname == '/')                                                        \
+               pathname++;                                                             \
+       current->fs->root->i_count++;                                                   \
+       if (dir_namei (current->personality & PER_BSD ? SPARC_BSD_EMUL : SPARC_SOL_EMUL,\
+                 &namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) {    \
+               *res_inode = NULL;                                                      \
+               if (open_namei (pathname, flag, mode, res_inode, emul_ino) >= 0 &&      \
+                               *res_inode)                                             \
+                       return 0;                                                       \
+       }                                                                               \
+       base = current->fs->root;                                                       \
+       base->i_count++;                                                                \
+  }                                                                                    \
+})
+
+#endif /* __SPARC64_NAMEI_H */
diff --git a/include/asm-sparc64/openprom.h b/include/asm-sparc64/openprom.h
new file mode 100644 (file)
index 0000000..c7aa7cf
--- /dev/null
@@ -0,0 +1,210 @@
+/* $Id: openprom.h,v 1.1 1996/12/26 14:22:32 davem Exp $ */
+#ifndef __SPARC64_OPENPROM_H
+#define __SPARC64_OPENPROM_H
+
+/* openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* Empirical constants... */
+#define KADB_DEBUGGER_BEGVM     0xffc00000    /* Where kern debugger is in virt-mem */
+#define        LINUX_OPPROM_BEGVM      0xffd00000
+#define        LINUX_OPPROM_ENDVM      0xfff00000
+#define        LINUX_OPPROM_MAGIC      0x10010407
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+       int (*v0_devopen)(char *device_str);
+       int (*v0_devclose)(int dev_desc);
+       int (*v0_rdblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrblkdev)(int dev_desc, int num_blks, int blk_st, char *buf);
+       int (*v0_wrnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdnetdev)(int dev_desc, int num_bytes, char *buf);
+       int (*v0_rdchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_wrchardev)(int dev_desc, int num_bytes, int dummy, char *buf);
+       int (*v0_seekdev)(int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+       int (*v2_inst2pkg)(int d);      /* Convert ihandle to phandle */
+       char * (*v2_dumb_mem_alloc)(char *va, unsigned sz);
+       void (*v2_dumb_mem_free)(char *va, unsigned sz);
+
+       /* To map devices into virtual I/O space. */
+       char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz);
+       void (*v2_dumb_munmap)(char *virta, unsigned size);
+
+       int (*v2_dev_open)(char *devpath);
+       void (*v2_dev_close)(int d);
+       int (*v2_dev_read)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_seek)(int d, int hi, int lo);
+
+       /* Never issued (multistage load support) */
+       void (*v2_wheee2)(void);
+       void (*v2_wheee3)(void);
+};
+
+struct linux_mlist_v0 {
+       struct linux_mlist_v0 *theres_more;
+       char *start_adr;
+       unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+       struct linux_mlist_v0 **v0_totphys;
+       struct linux_mlist_v0 **v0_prommap;
+       struct linux_mlist_v0 **v0_available; /* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+       char *argv[8];
+       char args[100];
+       char boot_dev[2];
+       int boot_dev_ctrl;
+       int boot_dev_unit;
+       int dev_partition;
+       char *kernel_file_name;
+       void *aieee1;           /* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+       char **bootpath;
+       char **bootargs;
+       int *fd_stdin;
+       int *fd_stdout;
+};
+
+/* The top level PROM vector. */
+struct linux_romvec {
+       /* Version numbers. */
+       unsigned int pv_magic_cookie;
+       unsigned int pv_romvers;
+       unsigned int pv_plugin_revision;
+       unsigned int pv_printrev;
+
+       /* Version 0 memory descriptors. */
+       struct linux_mem_v0 pv_v0mem;
+
+       /* Node operations. */
+       struct linux_nodeops *pv_nodeops;
+
+       char **pv_bootstr;
+       struct linux_dev_v0_funcs pv_v0devops;
+
+       char *pv_stdin;
+       char *pv_stdout;
+#define        PROMDEV_KBD     0               /* input from keyboard */
+#define        PROMDEV_SCREEN  0               /* output to screen */
+#define        PROMDEV_TTYA    1               /* in/out to ttya */
+#define        PROMDEV_TTYB    2               /* in/out to ttyb */
+
+       /* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+       int (*pv_getchar)(void);
+       void (*pv_putchar)(int ch);
+
+       /* Non-blocking variants. */
+       int (*pv_nbgetchar)(void);
+       int (*pv_nbputchar)(int ch);
+
+       void (*pv_putstr)(char *str, int len);
+
+       /* Miscellany. */
+       void (*pv_reboot)(char *bootstr);
+       void (*pv_printf)(__const__ char *fmt, ...);
+       void (*pv_abort)(void);
+       __volatile__ int *pv_ticks;
+       void (*pv_halt)(void);
+       void (**pv_synchook)(void);
+
+       /* Evaluate a forth string, not different proto for V0 and V2->up. */
+       union {
+               void (*v0_eval)(int len, char *str);
+               void (*v2_eval)(char *str);
+       } pv_fortheval;
+
+       struct linux_arguments_v0 **pv_v0bootargs;
+
+       /* Get ether address. */
+       unsigned int (*pv_enaddr)(int d, char *enaddr);
+
+       struct linux_bootargs_v2 pv_v2bootargs;
+       struct linux_dev_v2_funcs pv_v2devops;
+
+       int filler[15];
+
+       /* This one is sun4c/sun4 only. */
+       void (*pv_setctxt)(int ctxt, char *va, int pmeg);
+
+       /* Prom version 3 Multiprocessor routines. This stuff is crazy.
+        * No joke. Calling these when there is only one cpu probably
+        * crashes the machine, have to test this. :-)
+        */
+
+       /* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+        * 'thiscontext' executing at address 'prog_counter'
+        */
+       int (*v3_cpustart)(unsigned int whichcpu, int ctxtbl_ptr,
+                          int thiscontext, char *prog_counter);
+
+       /* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+        * until a resume cpu call is made.
+        */
+       int (*v3_cpustop)(unsigned int whichcpu);
+
+       /* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+        * resume cpu call is made.
+        */
+       int (*v3_cpuidle)(unsigned int whichcpu);
+
+       /* v3_cpuresume() will resume processor 'whichcpu' executing
+        * starting with whatever 'pc' and 'npc' were left at the
+        * last 'idle' or 'stop' call.
+        */
+       int (*v3_cpuresume)(unsigned int whichcpu);
+};
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+       int (*no_nextnode)(int node);
+       int (*no_child)(int node);
+       int (*no_proplen)(int node, char *name);
+       int (*no_getprop)(int node, char *name, char *val);
+       int (*no_setprop)(int node, char *name, char *val, int len);
+       char * (*no_nextprop)(int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     16
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    15
+
+struct linux_prom_registers {
+       int which_io;         /* is this in OBIO space? */
+       char *phys_addr;      /* The physical address of this register */
+       int reg_size;         /* How many bytes does this register take up? */
+};
+
+struct linux_prom_irqs {
+       int pri;    /* IRQ priority */
+       int vector; /* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+       unsigned int ot_child_space;
+       unsigned int ot_child_base;             /* Bus feels this */
+       unsigned int ot_parent_space;
+       unsigned int ot_parent_base;            /* CPU looks from here */
+       unsigned int or_size;
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__SPARC64_OPENPROM_H) */
diff --git a/include/asm-sparc64/openpromio.h b/include/asm-sparc64/openpromio.h
new file mode 100644 (file)
index 0000000..0361c66
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef        _SPARC64_OPENPROMIO_H
+#define        _SPARC64_OPENPROMIO_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * SunOS and Solaris /dev/openprom definitions. The ioctl values
+ * were chosen to be exactly equal to the SunOS equivalents.
+ */
+
+struct openpromio
+{
+       u_int   oprom_size;             /* Actual size of the oprom_array. */
+       char    oprom_array[1];         /* Holds property names and values. */
+};
+
+#define        OPROMMAXPARAM   4096            /* Maximum size of oprom_array. */
+
+#define        OPROMGETOPT             0x20004F01
+#define        OPROMSETOPT             0x20004F02
+#define        OPROMNXTOPT             0x20004F03
+#define        OPROMSETOPT2            0x20004F04
+#define        OPROMNEXT               0x20004F05
+#define        OPROMCHILD              0x20004F06
+#define        OPROMGETPROP            0x20004F07
+#define        OPROMNXTPROP            0x20004F08
+#define        OPROMU2P                0x20004F09
+#define        OPROMGETCONS            0x20004F0A
+#define        OPROMGETFBNAME          0x20004F0B
+#define        OPROMGETBOOTARGS        0x20004F0C
+
+/*
+ * Return values from OPROMGETCONS:
+ */
+
+#define OPROMCONS_NOT_WSCONS    0
+#define OPROMCONS_STDIN_IS_KBD  0x1     /* stdin device is kbd */
+#define OPROMCONS_STDOUT_IS_FB  0x2     /* stdout is a framebuffer */
+#define OPROMCONS_OPENPROM      0x4     /* supports openboot */
+
+
+/*
+ *  NetBSD/OpenBSD /dev/openprom definitions.
+ */
+
+struct opiocdesc
+{
+       int     op_nodeid;              /* PROM Node ID (value-result) */
+       int     op_namelen;             /* Length of op_name. */
+       char    *op_name;               /* Pointer to the property name. */
+       int     op_buflen;              /* Length of op_buf (value-result) */
+       char    *op_buf;                /* Pointer to buffer. */
+};
+
+#define        OPIOCGET        _IOWR('O', 1, struct opiocdesc)
+#define        OPIOCSET        _IOW('O', 2, struct opiocdesc)
+#define        OPIOCNEXTPROP   _IOWR('O', 3, struct opiocdesc)
+#define        OPIOCGETOPTNODE _IOR('O', 4, int)
+#define        OPIOCGETNEXT    _IOWR('O', 5, int)
+#define        OPIOCGETCHILD   _IOWR('O', 6, int)
+
+
+#ifdef __KERNEL__
+int openprom_init(void);
+#endif
+
+
+#endif /* _SPARC64_OPENPROMIO_H */
+
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
new file mode 100644 (file)
index 0000000..6b83e6b
--- /dev/null
@@ -0,0 +1,279 @@
+/* $Id: oplib.h,v 1.2 1996/12/27 08:49:07 jj Exp $
+ * oplib.h:  Describes the interface and available routines in the
+ *           Linux Prom library.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef __SPARC64_OPLIB_H
+#define __SPARC64_OPLIB_H
+
+#include <asm/openprom.h>
+
+/* Enumeration to describe the prom major version we have detected. */
+enum prom_major_version {
+       PROM_V0,      /* Original sun4c V0 prom */
+       PROM_V2,      /* sun4c and early sun4m V2 prom */
+       PROM_V3,      /* sun4m and later, up to sun4d/sun4e machines V3 */
+       PROM_P1275,   /* IEEE compliant ISA based Sun PROM, only sun4u */
+        PROM_AP1000,  /* actually no prom at all */
+};
+
+extern enum prom_major_version prom_vers;
+/* Revision, and firmware revision. */
+extern unsigned int prom_rev, prom_prev;
+
+/* Root node of the prom device tree, this stays constant after
+ * initialization is complete.
+ */
+extern int prom_root_node;
+
+/* The functions... */
+
+/* You must call prom_init() before using any of the library services,
+ * preferably as early as possible.  Pass it the romvec pointer.
+ */
+extern void prom_init(void *cif_handler, void *cif_stack);
+
+/* Boot argument acquisition, returns the boot command line string. */
+extern char *prom_getbootargs(void);
+
+/* Device utilities. */
+
+/* Device operations. */
+
+/* Open the device described by the passed string.  Note, that the format
+ * of the string is different on V0 vs. V2->higher proms.  The caller must
+ * know what he/she is doing!  Returns the device descriptor, an int.
+ */
+extern int prom_devopen(char *device_string);
+
+/* Close a previously opened device described by the passed integer
+ * descriptor.
+ */
+extern int prom_devclose(int device_handle);
+
+/* Do a seek operation on the device described by the passed integer
+ * descriptor.
+ */
+extern void prom_seek(int device_handle, unsigned int seek_hival,
+                     unsigned int seek_lowval);
+
+/* Machine memory configuration routine. */
+
+/* This function returns a V0 format memory descriptor table, it has three
+ * entries.  One for the total amount of physical ram on the machine, one
+ * for the amount of physical ram available, and one describing the virtual
+ * areas which are allocated by the prom.  So, in a sense the physical
+ * available is a calculation of the total physical minus the physical mapped
+ * by the prom with virtual mappings.
+ *
+ * These lists are returned pre-sorted, this should make your life easier
+ * since the prom itself is way too lazy to do such nice things.
+ */
+extern struct linux_mem_v0 *prom_meminfo(void);
+
+/* Miscellaneous routines, don't really fit in any category per se. */
+
+/* Reboot the machine with the command line passed. */
+extern void prom_reboot(char *boot_command);
+
+/* Evaluate the forth string passed. */
+extern void prom_feval(char *forth_string);
+
+/* Enter the prom, with possibility of continuation with the 'go'
+ * command in newer proms.
+ */
+extern void prom_cmdline(void);
+
+/* Enter the prom, with no chance of continuation for the stand-alone
+ * which calls this.
+ */
+extern void prom_halt(void);
+
+/* Set the PROM 'sync' callback function to the passed function pointer.
+ * When the user gives the 'sync' command at the prom prompt while the
+ * kernel is still active, the prom will call this routine.
+ *
+ */
+typedef void (*sync_func_t)(long *cmd);
+extern void prom_setsync(sync_func_t func_ptr);
+
+/* Acquire the IDPROM of the root node in the prom device tree.  This
+ * gets passed a buffer where you would like it stuffed.  The return value
+ * is the format type of this idprom or 0xff on error.
+ */
+extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
+
+/* Get the prom major version. */
+extern int prom_version(void);
+
+/* Get the prom plugin revision. */
+extern int prom_getrev(void);
+
+/* Get the prom firmware revision. */
+extern int prom_getprev(void);
+
+/* Character operations to/from the console.... */
+
+/* Non-blocking get character from console. */
+extern int prom_nbgetchar(void);
+
+/* Non-blocking put character to console. */
+extern int prom_nbputchar(char character);
+
+/* Blocking get character from console. */
+extern char prom_getchar(void);
+
+/* Blocking put character to console. */
+extern void prom_putchar(char character);
+
+/* Prom's internal printf routine, don't use in kernel/boot code. */
+void prom_printf(char *fmt, ...);
+
+/* Query for input device type */
+
+enum prom_input_device {
+       PROMDEV_IKBD,                   /* input from keyboard */
+       PROMDEV_ITTYA,                  /* input from ttya */
+       PROMDEV_ITTYB,                  /* input from ttyb */
+       PROMDEV_I_UNK,
+};
+
+extern enum prom_input_device prom_query_input_device(void);
+
+/* Query for output device type */
+
+enum prom_output_device {
+       PROMDEV_OSCREEN,                /* to screen */
+       PROMDEV_OTTYA,                  /* to ttya */
+       PROMDEV_OTTYB,                  /* to ttyb */
+       PROMDEV_O_UNK,
+};
+
+extern enum prom_output_device prom_query_output_device(void);
+
+/* Multiprocessor operations... */
+
+/* Start the CPU with the given device tree node, context table, and context
+ * at the passed program counter.
+ */
+extern int prom_startcpu(int cpunode, struct linux_prom_registers *context_table,
+                        int context, char *program_counter);
+
+/* Stop the CPU with the passed device tree node. */
+extern int prom_stopcpu(int cpunode);
+
+/* Idle the CPU with the passed device tree node. */
+extern int prom_idlecpu(int cpunode);
+
+/* Re-Start the CPU with the passed device tree node. */
+extern int prom_restartcpu(int cpunode);
+
+/* PROM device tree traversal functions... */
+
+/* Get the child node of the given node, or zero if no child exists. */
+extern int prom_getchild(int parent_node);
+
+/* Get the next sibling node of the given node, or zero if no further
+ * siblings exist.
+ */
+extern int prom_getsibling(int node);
+
+/* Get the length, at the passed node, of the given property type.
+ * Returns -1 on error (ie. no such property at this node).
+ */
+extern int prom_getproplen(int thisnode, char *property);
+
+/* Fetch the requested property using the given buffer.  Returns
+ * the number of bytes the prom put into your buffer or -1 on error.
+ */
+extern int prom_getproperty(int thisnode, char *property,
+                           char *prop_buffer, int propbuf_size);
+
+/* Acquire an integer property. */
+extern int prom_getint(int node, char *property);
+
+/* Acquire an integer property, with a default value. */
+extern int prom_getintdefault(int node, char *property, int defval);
+
+/* Acquire a boolean property, 0=FALSE 1=TRUE. */
+extern int prom_getbool(int node, char *prop);
+
+/* Acquire a string property, null string on error. */
+extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
+
+/* Does the passed node have the given "name"? YES=1 NO=0 */
+extern int prom_nodematch(int thisnode, char *name);
+
+/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
+ * and y for first regs phys address
+ */
+extern int prom_getname(int node, char *buf, int buflen);
+
+/* Search all siblings starting at the passed node for "name" matching
+ * the given string.  Returns the node on success, zero on failure.
+ */
+extern int prom_searchsiblings(int node_start, char *name);
+
+/* Return the first property type, as a string, for the given node.
+ * Returns a null string on error. Buffer should be at least 32B long.
+ */
+extern char *prom_firstprop(int node, char *buffer);
+
+/* Returns the next property after the passed property for the given
+ * node.  Returns null string on failure. Buffer should be at least 32B long.
+ */
+extern char *prom_nextprop(int node, char *prev_property, char *buffer);
+
+/* Returns 1 if the specified node has given property. */
+extern int prom_node_has_property(int node, char *property);
+
+/* Returns phandle of the path specified */
+extern int prom_finddevice(char *name);
+
+/* Set the indicated property at the given node with the passed value.
+ * Returns the number of bytes of your value that the prom took.
+ */
+extern int prom_setprop(int node, char *prop_name, char *prop_value,
+                       int value_size);
+                       
+extern int prom_pathtoinode(char *path);
+extern int prom_inst2pkg(int);
+
+/* Dorking with Bus ranges... */
+
+/* Adjust reg values with the passed ranges. */
+extern void prom_adjust_regs(struct linux_prom_registers *regp, int nregs,
+                            struct linux_prom_ranges *rangep, int nranges);
+
+/* Adjust child ranges with the passed parent ranges. */
+extern void prom_adjust_ranges(struct linux_prom_ranges *cranges, int ncranges,
+                              struct linux_prom_ranges *pranges, int npranges);
+
+/* Apply promlib probed OBIO ranges to registers. */
+extern void prom_apply_obio_ranges(struct linux_prom_registers *obioregs, int nregs);
+
+/* Apply ranges of any prom node (and optionally parent node as well) to registers. */
+extern void prom_apply_generic_ranges(int node, int parent, 
+                                     struct linux_prom_registers *sbusregs, int nregs);
+                                     
+extern long (*prom_command)(char *, long, ...);
+                                  
+
+#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
+
+/* We support at most 16 input and 1 output argument */
+#define P1275_ARG_NUMBER               0
+#define P1275_ARG_IN_STRING            1
+#define P1275_ARG_OUT_BUF              2
+#define P1275_ARG_OUT_32B              3
+#define P1275_ARG_IN_FUNCTION          4
+
+#define P1275_IN(x) ((x) & 0xf)
+#define P1275_OUT(x) (((x) << 4) & 0xf0)
+#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
+#define P1275_ARG(n,x) ((x) << ((n)*3 + 8)
+
+#endif /* !(__SPARC64_OPLIB_H) */
index ac642b16c4dd1a1d45a84043d80c4ed6dd7c4671..1e2eec6930a4077842373d2f49bbca8bb7bf188e 100644 (file)
@@ -1,14 +1,20 @@
-/* $Id: page.h,v 1.2 1996/12/02 00:01:06 davem Exp $ */
+/* $Id: page.h,v 1.4 1996/12/28 18:39:51 davem Exp $ */
 
 #ifndef _SPARC64_PAGE_H
 #define _SPARC64_PAGE_H
 
 #define PAGE_SHIFT   13
+
+#ifndef __ASSEMBLY__
+
 #define PAGE_SIZE    (1UL << PAGE_SHIFT)
 #define PAGE_MASK    (~(PAGE_SIZE-1))
 
 #ifdef __KERNEL__
 
+#define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
 #define STRICT_MM_TYPECHECKS
 
 #ifdef STRICT_MM_TYPECHECKS
@@ -63,7 +69,9 @@ typedef unsigned long iopgprot_t;
 #define __pgprot(x)    (x)
 #define __iopgprot(x)  (x)
 
-#endif
+#endif /* (STRICT_MM_TYPECHECKS) */
+
+#endif /* !(__ASSEMBLY__) */
 
 #define TASK_UNMAPPED_BASE     0x0000000070000000UL
 
@@ -75,6 +83,8 @@ typedef unsigned long iopgprot_t;
 #define __va(x)                        ((void *)((unsigned long) (x) + PAGE_OFFSET))
 #define MAP_NR(addr)           (__pa(addr) >> PAGE_SHIFT)
 
+#ifndef __ASSEMBLY__
+
 /* The following structure is used to hold the physical
  * memory configuration of the machine.  This is filled in
  * probe_memory() and is later used by mem_init() to set up
@@ -92,6 +102,8 @@ struct sparc_phys_banks {
 
 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 
-#endif /* __KERNEL__ */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__KERNEL__) */
 
-#endif /* _SPARC64_PAGE_H */
+#endif /* !(_SPARC64_PAGE_H) */
index ab050594094dd7c80b1c935ae1267ebbff4553b7..6c9e717a6ac5acf9504576b107cb0a3d62912286 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.1 1996/12/02 00:01:17 davem Exp $
+/* $Id: pgtable.h,v 1.8 1996/12/28 18:39:52 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996 David S. Miller (davem@caip.rutgers.edu)
  * the SpitFire page tables.
  */
 
+#include <asm/spitfire.h>
 #include <asm/asi.h>
 #include <asm/mmu_context.h>
 #include <asm/system.h>
 
+#ifndef __ASSEMBLY__
+
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
@@ -42,6 +45,8 @@
 #define VMALLOC_START          0xFFFFFE0000000000UL
 #define VMALLOC_VMADDR(x)      ((unsigned long)(x))
 
+#endif /* !(__ASSEMBLY__) */
+
 /* SpitFire TTE bits. */
 #define _PAGE_VALID    0x8000000000000000UL    /* Valid TTE                          */
 #define _PAGE_R                0x8000000000000000UL    /* Used to keep ref bit up to date    */
@@ -77,7 +82,6 @@
 
 #define _PFN_MASK      _PAGE_PADDR
 
-#define _PAGE_TABLE    (_PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS)
 #define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED)
 
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_CACHE)
 #define __S110 PAGE_SHARED
 #define __S111 PAGE_SHARED
 
+#ifndef __ASSEMBLY__
+
 extern pte_t __bad_page(void);
 extern pmd_t *__bad_pagetable(void);
 extern unsigned long __zero_page(void);
 
 #define BAD_PAGETABLE  __bad_pagetable()
 #define BAD_PAGE       __bad_page()
-#define ZERO_PAGE      __zero_page()
 
-/* Cache and TLB flush operations. */
-
-extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2"
-                            : /* No outputs */
-                            : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
-}
+#define ZERO_PAGE      PAGE_OFFSET
 
-extern __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
-{
-       __asm__ __volatile__("stxa      %0, [%1] %2"
-                            : /* No outputs */
-                            : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
-}
+/* Cache and TLB flush operations. */
 
 /* This is a bit tricky to do most efficiently.  The I-CACHE on the
  * SpitFire will snoop stores from _other_ processors and changes done
@@ -162,9 +155,9 @@ extern __inline__ void spitfire_flush_icache_page(unsigned long page)
        flush           %0 + 0x30
        flush           %0 + 0x38
        subcc           %1, 0x40, %1
-       bge,pt          %icc, 1b
+       bge,pt          %%icc, 1b
         add            %2, %1, %0
-"      : "=&r" (page), "=&r" (temp),
+"      : "=&r" (page), "=&r" (temp)
        : "r" (page), "0" (page + PAGE_SIZE - 0x40), "1" (PAGE_SIZE - 0x40));
 }
 
@@ -178,6 +171,9 @@ extern __inline__ void flush_cache_all(void)
                spitfire_put_icache_tag(addr, 0x0UL);
                membar("#Sync");
        }
+
+       /* Kill the pipeline. */
+       flushi(PAGE_OFFSET);
 }
 
 extern __inline__ void flush_cache_mm(struct mm_struct *mm)
@@ -192,6 +188,9 @@ extern __inline__ void flush_cache_mm(struct mm_struct *mm)
                        membar("#Sync");
                }
        }
+
+       /* Kill the pipeline. */
+       flushi(PAGE_OFFSET);
 }
 
 extern __inline__ void flush_cache_range(struct mm_struct *mm, unsigned long start,
@@ -205,6 +204,9 @@ extern __inline__ void flush_cache_range(struct mm_struct *mm, unsigned long sta
                        spitfire_put_icache_tag(addr, 0x0UL);
                        membar("#Sync");
                }
+
+               /* Kill the pipeline. */
+               flushi(PAGE_OFFSET);
        }
 }
 
@@ -234,12 +236,12 @@ extern __inline__ void flush_tlb_all(void)
        for(entry = 0; entry < 64; entry++) {
                unsigned long dtag, itag;
 
-               dtag = spitfire_get_dtlb_tag(entry);
-               itag = spitfire_get_itlb_tag(entry);
+               dtag = spitfire_get_dtlb_data(entry);
+               itag = spitfire_get_itlb_data(entry);
                if(!(dtag & _PAGE_L))
-                       spitfire_put_dtlb_tag(entry, 0x0UL);
+                       spitfire_put_dtlb_data(entry, 0x0UL);
                if(!(itag & _PAGE_L))
-                       spitfire_put_itlb_tag(entry, 0x0UL);
+                       spitfire_put_itlb_data(entry, 0x0UL);
        }
 }
 
@@ -271,6 +273,7 @@ extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long
        struct mm_struct *mm = vma->vm_mm;
 
        if(mm->context != NO_CONTEXT) {
+               page &= PAGE_MASK;
                spitfire_set_secondary_context(mm->context);
                if(vma->vm_flags & VM_EXEC)
                        spitfire_flush_itlb_secondary_page(page);
@@ -288,32 +291,32 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 extern inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
-{ pmd_val(*pmdp) = _PAGE_TABLE | ((unsigned long) ptep); }
+{ pmd_val(*pmdp) = ((unsigned long) ptep) - PAGE_OFFSET; }
 
 extern inline void pgd_set(pgd_t *pgdp, pmd_t *pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | ((unsigned long) pmdp); }
+{ pgd_val(*pgdp) = ((unsigned long) pmdp) - PAGE_OFFSET; }
 
 extern inline unsigned long pte_page(pte_t pte)
 { return PAGE_OFFSET + (pte_val(pte) & _PFN_MASK); }
 
 extern inline unsigned long pmd_page(pmd_t pmd)
-{ return (pmd_val(pmd) & PAGE_MASK); }
+{ return (pmd_val(pmd) + PAGE_OFFSET); }
 
 extern inline unsigned long pgd_page(pgd_t pgd)
-{ return (pgd_val(pgd) & PAGE_MASK); }
+{ return (pgd_val(pgd) + PAGE_OFFSET); }
 
 extern inline int pte_none(pte_t pte)          { return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)       { return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_cleat(pte_t *pte)       { pte_val(*pte) = 0; }
+extern inline void pte_clear(pte_t *pte)       { pte_val(*pte) = 0; }
 
 extern inline int pmd_none(pmd_t pmd)          { return !pmd_val(pmd); }
-extern inline int pmd_bad(pmd_t pmd)           { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; }
-extern inline int pmd_present(pmd_t pmd)       { return pmd_val(pmd) & _PAGE_PRESENT; }
+extern inline int pmd_bad(pmd_t pmd)           { return (pmd_val(pmd) & ~PAGE_MASK); }
+extern inline int pmd_present(pmd_t pmd)       { return pmd_val(pmd); }
 extern inline void pmd_clear(pmd_t *pmdp)      { pmd_val(*pmdp) = 0; }
 
 extern inline int pgd_none(pgd_t pgd)          { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)           { return (pgd_val(pgd) & ~PAGE_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd)       { return pgd_val(pgd) & _PAGE_PRESENT; }
+extern inline int pgd_bad(pgd_t pgd)           { return (pgd_val(pgd) & ~PAGE_MASK); }
+extern inline int pgd_present(pgd_t pgd)       { return pgd_val(pgd); }
 extern inline void pgd_clear(pgd_t *pgdp)      { pgd_val(*pgdp) = 0; }
 
 /* The following only work if pte_present() is true.
@@ -331,7 +334,7 @@ extern inline pte_t pte_rdprotect(pte_t pte)
 { return __pte(pte_val(pte) & ~(_PAGE_READ|_PAGE_R)); }
 
 extern inline pte_t pte_mkclean(pte_t pte)
-{ return __pte(pte_val(pte) & ~(_PAGE_MODIFIED | _PAGE_W); }
+{ return __pte(pte_val(pte) & ~(_PAGE_MODIFIED | _PAGE_W)); }
 
 extern inline pte_t pte_mkold(pte_t pte)
 { return __pte(pte_val(pte) & ~(_PAGE_ACCESSED | _PAGE_R)); }
@@ -361,12 +364,30 @@ extern inline pte_t pte_mkyoung(pte_t pte)
 }
 
 extern inline void SET_PAGE_DIR(struct task_struct *tsk, pgd_t *pgdir)
-{ /* XXX */ }
+{
+       register unsigned long paddr asm("%o5");
+
+       paddr = ((unsigned long) pgdir) - PAGE_OFFSET;
+
+       if(tsk->mm == current->mm) {
+               __asm__ __volatile__("
+                       rdpr            %%pstate, %%g1
+                       or              %%g1, %1, %%g2
+                       wrpr            %%g2, %2, %%pstate
+                       mov             %0, %%g7
+                       wrpr            %%g1, 0x0, %%pstate
+               " : : "r" (paddr), "i" (PSTATE_MG), "i" (PSTATE_IE)
+                 : "g1", "g2");
+       }
+}
 
 /* to find an entry in a page-table-directory. */
 extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
 { return mm->pgd + ((address >> PGDIR_SHIFT) & (PTRS_PER_PAGE - 1)); }
 
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
 { return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); }
@@ -489,13 +510,64 @@ extern inline void pgd_free(pgd_t * pgd)
 extern inline pgd_t * pgd_alloc(void)
 { return (pgd_t *) get_free_page(GFP_KERNEL); }
 
-#define pgd_flush(pgd) do { } while (0)
-
-extern pgd_t swapper_pg_dir[1024];     /* XXX */
+extern pgd_t swapper_pg_dir[1024];
 
 extern inline void update_mmu_cache(struct vm_area_struct * vma,
        unsigned long address, pte_t pte)
-{ /* XXX */ }
+{
+       /* Find and fix bad virutal cache aliases. */
+       if((vma->vm_flags & (VM_WRITE|VM_SHARED)) == (VM_WRITE|VM_SHARED)) {
+               struct vm_area_struct *vmaring;
+               struct inode *inode;
+               unsigned long vaddr, offset, start;
+               pgd_t *pgdp;
+               pmd_t *pmdp;
+               pte_t *ptep;
+               int alias_found = 0;
+
+               inode = vma->vm_inode;
+               if(!inode)
+                       return;
+
+               offset = (address & PAGE_MASK) - vma->vm_start;
+               vmaring = inode->i_mmap;
+               do {
+                       vaddr = vmaring->vm_start + offset;
+
+                       /* This conditional is misleading... */
+                       if((vaddr ^ address) & PAGE_SIZE) {
+                               alias_found++;
+                               start = vmaring->vm_start;
+                               while(start < vmaring->vm_end) {
+                                       pgdp = pgd_offset(vmaring->vm_mm, start);
+                                       if(!pgdp) goto next;
+                                       pmdp = pmd_offset(pgdp, start);
+                                       if(!pmdp) goto next;
+                                       ptep = pte_offset(pmdp, start);
+                                       if(!ptep) goto next;
+
+                                       if(pte_val(*ptep) & _PAGE_PRESENT) {
+                                               flush_cache_page(vmaring, start);
+                                               *ptep = __pte(pte_val(*ptep) &
+                                                             ~(_PAGE_CV));
+                                               flush_tlb_page(vmaring, start);
+                                       }
+                               next:
+                                       start += PAGE_SIZE;
+                               }
+                       }
+               } while((vmaring = vmaring->vm_next_share) != inode->i_mmap);
+
+               if(alias_found && (pte_val(pte) & _PAGE_CV)) {
+                       pgdp = pgd_offset(vma->vm_mm, address);
+                       pmdp = pmd_offset(pgdp, address);
+                       ptep = pte_offset(pmdp, address);
+                       flush_cache_page(vma, address);
+                       *ptep = __pte(pte_val(*ptep) & ~(_PAGE_CV));
+                       flush_tlb_page(vma, address);
+               }
+       }
+}
 
 /* Make a non-present pseudo-TTE. */
 extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
@@ -505,4 +577,6 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
 #define SWP_OFFSET(entry)      ((entry) >> 8)
 #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset)))
 
-#endif /* _SPARC64_PGTABLE_H */
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_PGTABLE_H) */
diff --git a/include/asm-sparc64/posix_types.h b/include/asm-sparc64/posix_types.h
new file mode 100644 (file)
index 0000000..d6a8dc9
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef __ARCH_SPARC64_POSIX_TYPES_H
+#define __ARCH_SPARC64_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long long     __kernel_size_t;
+
+typedef int                    __kernel_ssize_t;
+typedef unsigned long long int __kernel_ptrdiff_t;
+typedef long                   __kernel_time_t;
+typedef long                   __kernel_clock_t;
+typedef int                    __kernel_pid_t;
+typedef unsigned short         __kernel_ipc_pid_t;
+typedef unsigned short         __kernel_uid_t;
+typedef unsigned short         __kernel_gid_t;
+typedef unsigned short         __kernel_dev_t;
+typedef unsigned long          __kernel_ino_t;
+typedef unsigned short         __kernel_mode_t;
+typedef unsigned short         __kernel_umode_t;
+typedef short                  __kernel_nlink_t;
+typedef long                   __kernel_daddr_t;
+typedef long                   __kernel_off_t;
+typedef char *                 __kernel_caddr_t;
+
+#ifdef __GNUC__
+typedef long long      __kernel_loff_t;
+#endif
+
+typedef struct {
+       int     val[2];
+} __kernel_fsid_t;
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+{ 
+       unsigned long _tmp = fd / __NFDBITS;
+       unsigned long _rem = fd % __NFDBITS;
+       return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant cases (8 or 32 longs,
+ * for 256 and 1024-bit fd_sets respectively)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+       unsigned long *tmp = p->fds_bits;
+       int i;
+
+       if (__builtin_constant_p(__FDSET_LONGS)) {
+               switch (__FDSET_LONGS) {
+                       case 32:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         tmp[16] = 0; tmp[17] = 0; tmp[18] = 0; tmp[19] = 0;
+                         tmp[20] = 0; tmp[21] = 0; tmp[22] = 0; tmp[23] = 0;
+                         tmp[24] = 0; tmp[25] = 0; tmp[26] = 0; tmp[27] = 0;
+                         tmp[28] = 0; tmp[29] = 0; tmp[30] = 0; tmp[31] = 0;
+                         return;
+                       case 16:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
+                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
+                         return;
+                       case 8:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
+                         return;
+                       case 4:
+                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
+                         return;
+               }
+       }
+       i = __FDSET_LONGS;
+       while (i) {
+               i--;
+               *tmp = 0;
+               tmp++;
+       }
+}
+
+#endif /* !(__ARCH_SPARC64_POSIX_TYPES_H) */
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
new file mode 100644 (file)
index 0000000..b7995dd
--- /dev/null
@@ -0,0 +1,202 @@
+/* $Id: processor.h,v 1.6 1996/12/28 20:05:14 davem Exp $
+ * include/asm-sparc64/processor.h
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __ASM_SPARC64_PROCESSOR_H
+#define __ASM_SPARC64_PROCESSOR_H
+
+#include <asm/a.out.h>
+#include <asm/pstate.h>
+#include <asm/ptrace.h>
+#include <asm/head.h>
+#include <asm/signal.h>
+#include <asm/segment.h>
+
+/* Bus types */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* The sparc has no problems with write protection */
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/* Whee, this is STACK_TOP + PAGE_SIZE and the lowest kernel address too... 
+ * That one page is used to protect kernel from intruders, so that
+ * we can make our access_ok test faster
+ */
+#define TASK_SIZE      (0xFFFFF80000000000UL)
+
+#ifndef __ASSEMBLY__
+
+/* Ok this is hot.  Sparc exception save area. */
+struct exception_struct {
+       unsigned long count;   /* Exception count */
+       unsigned long pc;      /* Callers PC for copy/clear user */
+       unsigned long expc;    /* Where to jump when exception signaled */
+       unsigned long address; /* Saved user base address for transfer */
+};
+
+#define NSWINS         8
+
+/* The Sparc processor specific thread struct. */
+struct thread_struct {
+       /* Context switch saved kernel state. */
+       unsigned long user_globals[8];          /* performance hack */
+       unsigned long ksp, kpc;
+
+       /* Floating point regs */
+       unsigned long   float_regs[64] __attribute__ ((aligned (64)));
+       unsigned long   fsr;
+       unsigned long   fpqdepth;
+       struct fpq {
+               unsigned long *insn_addr;
+               unsigned long insn;
+       } fpqueue[16];
+
+       /* Storage for windows when user stack is bogus. */
+       struct reg_window reg_window[NSWINS] __attribute__ ((aligned (16)));
+       unsigned long rwbuf_stkptrs[NSWINS] __attribute__ ((aligned (8)));
+       unsigned long w_saved;
+
+       /* Arch-specific task state flags, see below. */
+       unsigned long flags;
+
+       /* For signal handling */
+       unsigned long sig_address __attribute__ ((aligned (8)));
+       unsigned long sig_desc;
+
+       struct exception_struct;
+       struct sigstack sstk_info;
+       int current_ds, new_signal;
+       struct exec core_exec;     /* just what it says. */
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#define SPARC_FLAG_KTHREAD      0x1    /* task is a kernel thread */
+#define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
+#define SPARC_FLAG_NEWSIGNALS   0x4    /* task wants new-style signals */
+#define SPARC_FLAG_32BIT        0x8    /* task is older 32-bit binary */
+
+#define INIT_MMAP { &init_mm, 0xfffff80000000000, 0xfffffe00000, \
+                   PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC }
+
+#define INIT_TSS  {                                                    \
+/* user_globals */                                                     \
+   { 0, 0, 0, 0, 0, 0, 0, 0, 0 },                                      \
+/* ksp, kpc */                                                                 \
+   0,   0,                                                             \
+/* FPU regs */   { 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, },  \
+/* FPU status, FPU qdepth, FPU queue */                                \
+   0,          0,          { { 0, 0, }, },                             \
+/* reg_window */                                                       \
+{ { { 0, }, { 0, } }, },                                               \
+/* rwbuf_stkptrs */                                                    \
+{ 0, 0, 0, 0, 0, 0, 0, 0, },                                           \
+/* w_saved */                                                          \
+   0,                                                                  \
+/* flags */                                                            \
+   SPARC_FLAG_KTHREAD,                                                 \
+/* sig_address, sig_desc */                                            \
+   0,           0,                                                     \
+/* ex,     sstk_info, current_ds, */                                   \
+   { 0, }, { 0, 0, }, USER_DS,                                         \
+/* new_signal */                                                       \
+  0,                                                                   \
+/* core_exec */                                                                \
+{ 0, },                                                                        \
+}
+
+#ifndef __ASSEMBLY__
+
+/* Return saved PC of a blocked thread. */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+       return t->kpc;
+}
+
+/* Do necessary setup to start up a newly executed thread. */
+extern __inline__ void start_thread(struct pt_regs *regs, unsigned long pc,
+                                   unsigned long sp)
+{
+       regs->tstate = (regs->tstate & (TSTATE_CWP)) | TSTATE_IE;
+       regs->tpc = ((pc & (~3)) - 4);
+       regs->tnpc = regs->tpc + 4;
+       regs->y = 0;
+       __asm__ __volatile__("
+               stx             %%g0, [%0 + %2 + 0x00]
+               stx             %%g0, [%0 + %2 + 0x08]
+               stx             %%g0, [%0 + %2 + 0x10]
+               stx             %%g0, [%0 + %2 + 0x18]
+               stx             %%g0, [%0 + %2 + 0x20]
+               stx             %%g0, [%0 + %2 + 0x28]
+               stx             %%g0, [%0 + %2 + 0x30]
+               stx             %%g0, [%0 + %2 + 0x38]
+               stx             %%g0, [%0 + %2 + 0x40]
+               stx             %%g0, [%0 + %2 + 0x48]
+               stx             %%g0, [%0 + %2 + 0x50]
+               stx             %%g0, [%0 + %2 + 0x58]
+               stx             %%g0, [%0 + %2 + 0x60]
+               stx             %%g0, [%0 + %2 + 0x68]
+               stx             %1,   [%0 + %2 + 0x70]
+               stx             %%g0, [%0 + %2 + 0x78]
+               " : : "r" (regs), "r" (sp - REGWIN_SZ),
+                     "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])));
+}
+
+extern __inline__ void start_thread32(struct pt_regs *regs, unsigned long pc,
+                                     unsigned long sp)
+{
+       register unsigned int zero asm("g1");
+
+       pc &= 0x00000000ffffffffUL;
+       sp &= 0x00000000ffffffffUL;
+
+       regs->tstate = (regs->tstate & (TSTATE_CWP)) | (TSTATE_IE | TSTATE_AM);
+       regs->tpc = ((pc & (~3)) - 4);
+       regs->tnpc = regs->tpc + 4;
+       regs->y = 0;
+       zero = 0;
+       __asm__ __volatile__("
+               stx             %%g0, [%0 + %2 + 0x00]
+               stx             %%g0, [%0 + %2 + 0x08]
+               stx             %%g0, [%0 + %2 + 0x10]
+               stx             %%g0, [%0 + %2 + 0x18]
+               stx             %%g0, [%0 + %2 + 0x20]
+               stx             %%g0, [%0 + %2 + 0x28]
+               stx             %%g0, [%0 + %2 + 0x30]
+               stx             %%g0, [%0 + %2 + 0x38]
+               stx             %%g0, [%0 + %2 + 0x40]
+               stx             %%g0, [%0 + %2 + 0x48]
+               stx             %%g0, [%0 + %2 + 0x50]
+               stx             %%g0, [%0 + %2 + 0x58]
+               stx             %%g0, [%0 + %2 + 0x60]
+               stx             %%g0, [%0 + %2 + 0x68]
+               stx             %1,   [%0 + %2 + 0x70]
+               stx             %%g0, [%0 + %2 + 0x78]
+               " : : "r" (regs), "r" (sp - REGWIN32_SZ),
+                     "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])),
+                     "r" (zero));
+}
+
+/* Free all resources held by a thread. */
+#define release_thread(tsk)            do { } while(0)
+
+#ifdef __KERNEL__
+/* Allocation and freeing of basic task resources. */
+#define alloc_kernel_stack(tsk)                __get_free_page(GFP_KERNEL)
+#define free_kernel_stack(stack)       free_page(stack)
+#define alloc_task_struct()            kmalloc(sizeof(struct task_struct), GFP_KERNEL)
+#define free_task_struct(tsk)          kfree(tsk)
+#endif
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(__ASM_SPARC64_PROCESSOR_H) */
diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h
new file mode 100644 (file)
index 0000000..4dc38e3
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id: psrcompat.h,v 1.1 1996/12/26 10:02:30 davem Exp $ */
+#ifndef _SPARC64_PSRCOMPAT_H
+#define _SPARC64_PSRCOMPAT_H
+
+#include <asm/pstate.h>
+
+/* Old 32-bit PSR fields for the compatability conversion code. */
+#define PSR_CWP     0x0000001f         /* current window pointer     */
+#define PSR_ET      0x00000020         /* enable traps field         */
+#define PSR_PS      0x00000040         /* previous privilege level   */
+#define PSR_S       0x00000080         /* current privilege level    */
+#define PSR_PIL     0x00000f00         /* processor interrupt level  */
+#define PSR_EF      0x00001000         /* enable floating point      */
+#define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+#define PSR_ICC     0x00f00000         /* integer condition codes    */
+#define PSR_C       0x00100000         /* carry bit                  */
+#define PSR_V       0x00200000         /* overflow bit               */
+#define PSR_Z       0x00400000         /* zero bit                   */
+#define PSR_N       0x00800000         /* negative bit               */
+#define PSR_VERS    0x0f000000         /* cpu-version field          */
+#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+
+extern inline unsigned int tstate_to_psr(unsigned long tstate)
+{
+       unsigned int psr;
+       unsigned long vers;
+
+       /* These fields are in the same place. */
+       psr  = (tstate & (TSTATE_CWP | TSTATE_PEF));
+
+       /* This is what the user would have always seen. */
+       psr |= PSR_S;
+
+       /* Slam in the 32-bit condition codes. */
+       psr |= ((tstate & TSTATE_ICC) >> 12);
+
+       /* This is completely arbitrary. */
+       __asm__ __volatile__("rdpr      %vers, %0" : "=r" (vers));
+       psr |= ((vers << 8) >> 32) & PSR_IMPL;
+       psr |= ((vers << 24) >> 36) & PSR_VERS;
+
+       return psr;
+}
+
+extern inline unsigned long psr_to_tstate_icc(unsigned int psr)
+{
+       unsigned long tstate;
+
+       tstate = (psr & PSR_ICC) << 12;
+
+       return tstate;
+}
+
+#endif /* !(_SPARC64_PSRCOMPAT_H) */
index fd7c7ff180bdeb398e388edad1d24a62b1437882..042af8990b66f83efe9cf37bcc03bc2685cbc82f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pstate.h,v 1.1 1996/12/12 11:57:14 davem Exp $ */
+/* $Id: pstate.h,v 1.2 1996/12/26 09:56:16 davem Exp $ */
 #ifndef _SPARC64_PSTATE_H
 #define _SPARC64_PSTATE_H
 
  *  63    40 39   32 31   24 23    20 19       8 7      5 4     0
  */
 #define TSTATE_CCR     0x000000ff00000000      /* Condition Codes.             */
+#define TSTATE_XCC     0x000000f000000000      /* Condition Codes.             */
 #define TSTATE_XNEG    0x0000008000000000      /* %xcc Negative.               */
 #define TSTATE_XZERO   0x0000004000000000      /* %xcc Zero.                   */
 #define TSTATE_XOVFL   0x0000002000000000      /* %xcc Overflow.               */
 #define TSTATE_XCARRY  0x0000001000000000      /* %xcc Carry.                  */
+#define TSTATE_ICC     0x0000000f00000000      /* Condition Codes.             */
 #define TSTATE_INEG    0x0000000800000000      /* %icc Negative.               */
 #define TSTATE_IZERO   0x0000000400000000      /* %icc Zero.                   */
 #define TSTATE_IOVFL   0x0000000200000000      /* %icc Overflow.               */
index a14e1989e5380d6ddb1e712756f190de13f51948..e9c5345d013b9c33260e13647222231a400d7b77 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ptrace.h,v 1.1 1996/12/12 11:59:35 davem Exp $ */
+/* $Id: ptrace.h,v 1.4 1996/12/28 18:39:54 davem Exp $ */
 #ifndef _SPARC64_PTRACE_H
 #define _SPARC64_PTRACE_H
 
@@ -18,6 +18,14 @@ struct pt_regs {
        unsigned long y;
 };
 
+struct pt_regs32 {
+       unsigned int psr;
+       unsigned int pc;
+       unsigned int npc;
+       unsigned int y;
+       unsigned int u_regs[16]; /* globals and ins */
+};
+
 #define UREG_G0        0
 #define UREG_G1        1
 #define UREG_G2        2
@@ -44,7 +52,7 @@ struct reg_window {
 };
 
 /* A 32-bit register window. */
-struct reg_window_32 {
+struct reg_window32 {
        unsigned int locals[8];
        unsigned int ins[8];
 };
@@ -61,7 +69,7 @@ struct sparc_stackf {
 };     
 
 /* A 32-bit Sparc stack frame */
-struct sparc_stackf_32 {
+struct sparc_stackf32 {
        unsigned int locals[8];
         unsigned int ins[6];
        unsigned int fp;
@@ -71,19 +79,36 @@ struct sparc_stackf_32 {
        unsigned int xxargs[1];
 };     
 
-#define TRACEREG_SZ   sizeof(struct pt_regs)
-#define STACKFRAME_SZ sizeof(struct sparc_stackf)
-#define REGWIN_SZ     sizeof(struct reg_window)
+struct sparc_trapf {
+       unsigned long locals[8];
+       unsigned long ins[8];
+       unsigned long _unused;
+       struct pt_regs *regs;
+};
+
+#define TRACEREG_SZ    sizeof(struct pt_regs)
+#define STACKFRAME_SZ  sizeof(struct sparc_stackf)
+#define REGWIN_SZ      sizeof(struct reg_window)
+
+#define TRACEREG32_SZ  sizeof(struct pt_regs32)
+#define STACKFRAME32_SZ        sizeof(struct sparc_stackf32)
+#define REGWIN32_SZ    sizeof(struct reg_window32)
 
 #ifdef __KERNEL__
-#define user_mode(regs) (!((regs)->tstate & PSR_PS))
+#define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
 #define instruction_pointer(regs) ((regs)->tpc)
 extern void show_regs(struct pt_regs *);
 #endif
 
 #else /* __ASSEMBLY__ */
 /* For assembly code. */
-#define TRACEREG_SZ       0x50
-#define STACKFRAME_SZ     0x60
-#define REGWIN_SZ         0x40
+#define TRACEREG_SZ            XXX
+#define STACKFRAME_SZ          YYY
+#define REGWIN_SZ              ZZZ
+
+#define TRACEREG32_SZ          0x50
+#define STACKFRAME32_SZ                0x60
+#define REGWIN32_SZ            0x40
 #endif
+
+#endif /* !(_SPARC64_PTRACE_H) */
diff --git a/include/asm-sparc64/reg.h b/include/asm-sparc64/reg.h
new file mode 100644 (file)
index 0000000..716b8f8
--- /dev/null
@@ -0,0 +1,79 @@
+/* $Id: reg.h,v 1.1 1996/12/26 14:22:34 davem Exp $
+ * linux/asm-sparc64/reg.h
+ * Layout of the registers as expected by gdb on the Sparc
+ * we should replace the user.h definitions with those in
+ * this file, we don't even use the other 
+ * -miguel
+ *
+ * The names of the structures, constants and aliases in this file
+ * have the same names as the sunos ones, some programs rely on these
+ * names (gdb for example).
+ *
+ */
+
+#ifndef __SPARC64_REG_H
+#define __SPARC64_REG_H
+
+struct regs {
+       int     r_psr;
+#define r_ps r_psr
+        int     r_pc; 
+        int     r_npc;
+        int     r_y;  
+        int     r_g1; 
+        int     r_g2;
+        int     r_g3;
+        int     r_g4;
+        int     r_g5;
+        int     r_g6;
+        int     r_g7;
+        int     r_o0;
+        int     r_o1;
+        int     r_o2;
+        int     r_o3;
+        int     r_o4;
+        int     r_o5;
+        int     r_o6;
+        int     r_o7;
+};
+
+struct fpq {
+        unsigned int *addr;
+        unsigned ing instr;
+};
+
+struct  fq {
+        union {
+                double  whole;
+                struct  fpq fpq;
+        } FQu;
+};
+
+#define FPU_REGS_TYPE unsigned int
+#define FPU_FSR_TYPE unsigned
+
+struct fp_status {
+        union {
+                FPU_REGS_TYPE Fpu_regs[32];
+                double  Fpu_dregs[16];
+        } fpu_fr;
+        FPU_FSR_TYPE Fpu_fsr;
+        unsigned Fpu_flags;
+        unsigned Fpu_extra;
+        unsigned Fpu_qcnt;
+        struct fq Fpu_q[16];
+};
+
+#define fpu_regs  f_fpstatus.fpu_fr.Fpu_regs
+#define fpu_dregs f_fpstatus.fpu_fr.Fpu_dregs
+#define fpu_fsr   f_fpstatus.Fpu_fsr
+#define fpu_flags f_fpstatus.Fpu_flags
+#define fpu_extra f_fpstatus.Fpu_extra
+#define fpu_q     f_fpstatus.Fpu_q
+#define fpu_qcnt  f_fpstatus.Fpu_qcnt
+
+struct fpu {
+        struct fp_status f_fpstatus;
+};
+
+#endif /* __SPARC64_REG_H */
diff --git a/include/asm-sparc64/resource.h b/include/asm-sparc64/resource.h
new file mode 100644 (file)
index 0000000..c6d8683
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id: resource.h,v 1.1 1996/12/26 14:22:34 davem Exp $
+ * resource.h: Resource definitions.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_RESOURCE_H
+#define _SPARC64_RESOURCE_H
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU     0               /* CPU time in ms */
+#define RLIMIT_FSIZE   1               /* Maximum filesize */
+#define RLIMIT_DATA    2               /* max data size */
+#define RLIMIT_STACK   3               /* max stack size */
+#define RLIMIT_CORE    4               /* max core file size */
+#define RLIMIT_RSS     5               /* max resident set size */
+#define RLIMIT_NOFILE  6               /* max number of open files */
+#define RLIMIT_NPROC   7               /* max number of processes */
+#define RLIMIT_MEMLOCK  8               /* max locked-in-memory address space */
+#define RLIMIT_AS       9               /* address space limit */
+
+#define RLIM_NLIMITS   10
+
+#ifdef __KERNEL__
+
+#define INIT_RLIMITS                                                   \
+{                                                                      \
+    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX},                                \
+    {LONG_MAX, LONG_MAX}, {_STK_LIM, _STK_LIM},                                \
+    {       0, LONG_MAX}, {LONG_MAX, LONG_MAX},                                \
+    {NR_OPEN, NR_OPEN}, {MAX_TASKS_PER_USER, MAX_TASKS_PER_USER},      \
+    {LONG_MAX, LONG_MAX}, {LONG_MAX, LONG_MAX}                          \
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* !(_SPARC64_RESOURCE_H) */
diff --git a/include/asm-sparc64/rtc.h b/include/asm-sparc64/rtc.h
new file mode 100644 (file)
index 0000000..cb17334
--- /dev/null
@@ -0,0 +1,27 @@
+/* $Id: rtc.h,v 1.1 1996/12/26 14:22:35 davem Exp $
+ *
+ * rtc.h: Definitions for access to the Mostek real time clock
+ *
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ */
+
+#ifndef _RTC_H
+#define _RTC_H
+
+#include <linux/ioctl.h>
+
+struct rtc_time
+{
+       int     sec;    /* Seconds (0-59) */
+       int     min;    /* Minutes (0-59) */
+       int     hour;   /* Hour (0-23) */
+       int     dow;    /* Day of the week (1-7) */
+       int     dom;    /* Day of the month (1-31) */
+       int     month;  /* Month of year (1-12) */
+       int     year;   /* Year (0-99) */
+};
+
+#define RTCGET _IOR('p', 20, struct rtc_time)
+#define RTCSET _IOW('p', 21, struct rtc_time)
+
+#endif
diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h
new file mode 100644 (file)
index 0000000..70c94de
--- /dev/null
@@ -0,0 +1,98 @@
+/* $Id: sbus.h,v 1.1 1996/12/26 14:22:36 davem Exp $
+ * sbus.h:  Defines for the Sun SBus.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/* XXX This needs to be mostly redone for sun5 SYSIO. */
+
+#ifndef _SPARC64_SBUS_H
+#define _SPARC64_SBUS_H
+
+#include <asm/oplib.h>
+#include <asm/iommu.h>
+
+/* We scan which devices are on the SBus using the PROM node device
+ * tree.  SBus devices are described in two different ways.  You can
+ * either get an absolute address at which to access the device, or
+ * you can get a SBus 'slot' number and an offset within that slot.
+ */
+
+/* The base address at which to calculate device OBIO addresses. */
+#define SUN_SBUS_BVADDR        0xf8000000
+#define SBUS_OFF_MASK          0x01ffffff
+
+/* These routines are used to calculate device address from slot
+ * numbers + offsets, and vice versa.
+ */
+
+extern __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+{
+  return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
+}
+
+extern __inline__ int sbus_dev_slot(unsigned long dev_addr)
+{
+  return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
+}
+
+extern __inline__ unsigned long sbus_dev_offset(unsigned long dev_addr)
+{
+  return (unsigned long) (((dev_addr)-SUN_SBUS_BVADDR)&SBUS_OFF_MASK);
+}
+
+struct linux_sbus;
+
+/* Linux SBUS device tables */
+struct linux_sbus_device {
+  struct linux_sbus_device *next;      /* next device on this SBus or null */
+  struct linux_sbus_device *child;     /* For ledma and espdma on sun4m */
+  struct linux_sbus *my_bus;           /* Back ptr to sbus */
+  int prom_node;                       /* PROM device tree node for this device */
+  char prom_name[64];                  /* PROM device name */
+  char linux_name[64];                 /* Name used internally by Linux */
+
+  struct linux_prom_registers reg_addrs[PROMREG_MAX];
+  int num_registers;
+
+  struct linux_prom_irqs irqs[PROMINTR_MAX];
+  int num_irqs;
+
+  unsigned long sbus_addr;             /* Absolute base address for device. */
+  unsigned long sbus_vaddrs[PROMVADDR_MAX];
+  unsigned long num_vaddrs;
+  unsigned long offset;                /* Offset given by PROM */
+  int slot;
+};
+
+/* This struct describes the SBus(s) found on this machine. */
+struct linux_sbus {
+       struct linux_sbus *next;             /* next SBus, if more than one SBus */
+       struct linux_sbus_device *devices;   /* Link to devices on this SBus */
+       struct iommu_struct *iommu;          /* IOMMU for this sbus if applicable */
+       int prom_node;                       /* PROM device tree node for this SBus */
+       char prom_name[64];                  /* Usually "sbus" or "sbi" */
+       int clock_freq;
+       struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
+       int num_sbus_ranges;
+};
+
+extern struct linux_sbus *SBus_chain;
+
+/* Device probing routines could find these handy */
+#define for_each_sbus(bus) \
+        for((bus) = SBus_chain; (bus); (bus)=(bus)->next)
+
+#define for_each_sbusdev(device, bus) \
+        for((device) = (bus)->devices; (device); (device)=(device)->next)
+        
+#define for_all_sbusdev(device, bus) \
+       for((bus) = SBus_chain, (device) = (bus)->devices; (bus); (device)=((device)->next ? (device)->next : ((bus) = (bus)->next, (bus) ? (bus)->devices : 0)))
+
+/* XXX This is promlib stuff, what is it doing here? XXX */
+
+/* Apply promlib probed SBUS ranges to registers. */
+extern void prom_apply_sbus_ranges(struct linux_sbus *sbus, 
+                                  struct linux_prom_registers *sbusregs, int nregs);
+
+#endif /* !(_SPARC64_SBUS_H) */
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
new file mode 100644 (file)
index 0000000..b6db04c
--- /dev/null
@@ -0,0 +1,18 @@
+/* $Id: scatterlist.h,v 1.1 1996/12/26 14:22:32 davem Exp $ */
+#ifndef _SPARC64_SCATTERLIST_H
+#define _SPARC64_SCATTERLIST_H
+
+#include <asm/page.h>
+
+struct scatterlist {
+    char *  address;    /* Location data is to be transferred to */
+    char * alt_address; /* Location of actual if address is a 
+                        * dma indirect buffer.  NULL otherwise */
+    unsigned int length;
+
+    char * dvma_address; /* A place to hang host-specific addresses at. */
+};
+
+#define ISA_DMA_THRESHOLD ((0x100000000) + PAGE_OFFSET)
+
+#endif /* !(_SPARC64_SCATTERLIST_H) */
diff --git a/include/asm-sparc64/segment.h b/include/asm-sparc64/segment.h
new file mode 100644 (file)
index 0000000..b03e709
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __SPARC64_SEGMENT_H
+#define __SPARC64_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif
diff --git a/include/asm-sparc64/shmparam.h b/include/asm-sparc64/shmparam.h
new file mode 100644 (file)
index 0000000..ded0406
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id: shmparam.h,v 1.1 1996/12/26 14:22:36 davem Exp $ */
+#ifndef _ASMSPARC64_SHMPARAM_H
+#define _ASMSPARC64_SHMPARAM_H
+
+/* XXX Redo most of this... */
+
+/* address range for shared memory attaches if no address passed to shmat() */
+#define SHM_RANGE_START        0x10000000
+#define SHM_RANGE_END  0x20000000
+
+/*
+ * Format of a swap-entry for shared memory pages currently out in
+ * swap space (see also mm/swap.c).
+ *
+ * SWP_TYPE = SHM_SWP_TYPE
+ * SWP_OFFSET is used as follows:
+ *
+ *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
+ *  bits 7..21: index of page within shared memory segment (SHM_IDX)
+ *             (actually fewer bits get used since SHMMAX is so low)
+ */
+
+/*
+ * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
+ * there is a static array of size SHMMNI.
+ */
+#define _SHM_ID_BITS   7
+#define SHM_ID_MASK    ((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT  (_SHM_ID_BITS)
+#define _SHM_IDX_BITS  15
+#define SHM_IDX_MASK   ((1<<_SHM_IDX_BITS)-1)
+
+/*
+ * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
+ * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
+ */
+
+#define SHMMAX (1024 * 1024)           /* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */        /* min shared seg size (bytes) */
+#define SHMMNI (1<<_SHM_ID_BITS)       /* max num of segs system wide */
+#define SHMALL                         /* max shm system wide (pages) */ \
+       (1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
+#define        SHMLBA PAGE_SIZE                /* attach addr a multiple of this */
+#define SHMSEG SHMMNI                  /* max shared segs per process */
+
+#endif /* _ASMSPARC64_SHMPARAM_H */
diff --git a/include/asm-sparc64/sigcontext.h b/include/asm-sparc64/sigcontext.h
new file mode 100644 (file)
index 0000000..418d4fa
--- /dev/null
@@ -0,0 +1,67 @@
+/* $Id: sigcontext.h,v 1.1 1996/12/26 14:22:36 davem Exp $ */
+#ifndef _ASMsparc64_SIGCONTEXT_H
+#define _ASMsparc64_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+#define SUNOS_MAXWIN   31
+
+#ifndef __ASSEMBLY__
+
+/* SunOS system call sigstack() uses this arg. */
+struct sunos_sigstack {
+       unsigned int sig_sp;
+       int onstack_flag;
+};
+
+/* This is what SunOS does, so shall I. */
+struct sigcontext {
+       int sigc_onstack;      /* state to restore */
+       int sigc_mask;         /* sigmask to restore */
+       int sigc_sp;           /* stack pointer */
+       int sigc_pc;           /* program counter */
+       int sigc_npc;          /* next program counter */
+       int sigc_psr;          /* for condition codes etc */
+       int sigc_g1;           /* User uses these two registers */
+       int sigc_o0;           /* within the trampoline code. */
+
+       /* Now comes information regarding the users window set
+        * at the time of the signal.
+        */
+       int sigc_oswins;       /* outstanding windows */
+
+       /* stack ptrs for each regwin buf */
+       /* XXX 32-bit ptrs pinhead... */
+       char *sigc_spbuf[SUNOS_MAXWIN];
+
+       /* Windows to restore after signal */
+       struct reg_window32 sigc_wbuf[SUNOS_MAXWIN];
+};
+
+typedef struct {
+       struct     pt_regs32 si_regs;
+       unsigned   int si_float_regs [64];
+       unsigned   int si_fsr;
+       unsigned   int si_fpqdepth;
+       struct {
+               unsigned int *insn_addr;
+               unsigned int insn;
+       } si_fpqueue [16];
+       int si_mask;
+} __siginfo32_t;
+
+typedef struct {
+       struct     pt_regs si_regs;
+       unsigned   long si_float_regs [64];
+       unsigned   long si_fsr;
+       unsigned   int si_fpqdepth;
+       struct {
+               unsigned int *insn_addr;
+               unsigned int insn;
+       } si_fpqueue [16];
+       int si_mask;
+} __siginfo_t;
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMsparc64_SIGCONTEXT_H) */
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
new file mode 100644 (file)
index 0000000..a48b2d8
--- /dev/null
@@ -0,0 +1,178 @@
+/* $Id: signal.h,v 1.1 1996/12/26 14:22:37 davem Exp $ */
+#ifndef _ASMSPARC64_SIGNAL_H
+#define _ASMSPARC64_SIGNAL_H
+
+#include <asm/sigcontext.h>
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#include <linux/personality.h>
+#endif
+#endif
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define _NSIG             32
+#define NSIG           _NSIG
+
+#define SIGHUP          1
+#define SIGINT          2
+#define SIGQUIT                 3
+#define SIGILL          4
+#define    SUBSIG_STACK       0
+#define    SUBSIG_ILLINST     2
+#define    SUBSIG_PRIVINST    3
+#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
+
+#define SIGTRAP                 5
+#define SIGABRT                 6
+#define SIGIOT          6
+
+#define SIGEMT           7
+#define    SUBSIG_TAG    10
+
+#define SIGFPE          8
+#define    SUBSIG_FPDISABLED     0x400
+#define    SUBSIG_FPERROR        0x404
+#define    SUBSIG_FPINTOVFL      0x001
+#define    SUBSIG_FPSTSIG        0x002
+#define    SUBSIG_IDIVZERO       0x014
+#define    SUBSIG_FPINEXACT      0x0c4
+#define    SUBSIG_FPDIVZERO      0x0c8
+#define    SUBSIG_FPUNFLOW       0x0cc
+#define    SUBSIG_FPOPERROR      0x0d0
+#define    SUBSIG_FPOVFLOW       0x0d4
+
+#define SIGKILL                 9
+#define SIGBUS          10
+#define    SUBSIG_BUSTIMEOUT    1
+#define    SUBSIG_ALIGNMENT     2
+#define    SUBSIG_MISCERROR     5
+
+#define SIGSEGV                11
+#define    SUBSIG_NOMAPPING     3
+#define    SUBSIG_PROTECTION    4
+#define    SUBSIG_SEGERROR      5
+
+#define SIGSYS         12
+
+#define SIGPIPE                13
+#define SIGALRM                14
+#define SIGTERM                15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP                17
+#define SIGTSTP                18
+#define SIGCONT                19
+#define SIGCHLD                20
+#define SIGTTIN                21
+#define SIGTTOU                22
+#define SIGIO          23
+#define SIGPOLL                SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU                24
+#define SIGXFSZ                25
+#define SIGVTALRM      26
+#define SIGPROF                27
+#define SIGWINCH       28
+#define SIGLOST                29
+#define SIGUSR1                30
+#define SIGUSR2                31
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long sigset_t;
+typedef unsigned int sigset32_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#endif
+
+/* A SunOS sigstack */
+struct sigstack {
+       /* XXX 32-bit pointers pinhead XXX */
+       char *the_stack;
+       int   cur_status;
+};
+
+/* Sigvec flags */
+#define SV_SSTACK    1     /* This signal handler should use sig-stack */
+#define SV_INTR      2     /* Sig return should not restart system call */
+#define SV_RESET     4     /* Set handler to SIG_DFL upon taken signal */
+#define SV_IGNCHILD  8     /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
+ */
+#define SA_NOCLDSTOP   SV_IGNCHILD
+#define SA_STACK       SV_SSTACK
+#define SA_RESTART     SV_INTR
+#define SA_ONESHOT     SV_RESET
+#define SA_INTERRUPT   0x10
+#define SA_NOMASK      0x20
+#define SA_SHIRQ       0x40
+
+#define SIG_BLOCK          0x01        /* for blocking signals */
+#define SIG_UNBLOCK        0x02        /* for unblocking signals */
+#define SIG_SETMASK        0x04        /* for setting the signal mask */
+
+#ifdef __KERNEL__
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ *
+ * DJHR
+ * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
+ * interrupt handler's irq structure should be statically allocated
+ * by the request_irq routine.
+ * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
+ * of interrupt usage and that sucks. Also without a flag like this
+ * it may be possible for the free_irq routine to attempt to free
+ * statically allocated data.. which is NOT GOOD.
+ *
+ */
+#define SA_PROBE SA_ONESHOT
+#define SA_SAMPLE_RANDOM SA_RESTART
+#define SA_STATIC_ALLOC                0x80
+#endif
+
+/* Type of a signal handler.  */
+#ifdef __KERNEL__
+typedef void (*__sighandler_t)(int, int, struct sigcontext *, char *);
+#else
+typedef void (*__sighandler_t)(int);
+#endif
+
+#define SIG_DFL        ((__sighandler_t)0)     /* default signal handling */
+#define SIG_IGN        ((__sighandler_t)1)     /* ignore signal */
+#define SIG_ERR        ((__sighandler_t)-1)    /* error return from signal */
+
+struct sigaction {
+       __sighandler_t  sa_handler;
+       sigset_t        sa_mask;
+       unsigned long   sa_flags;
+       void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
+};
+
+struct sigaction32 {
+       /* XXX 32-bit func ptr... */
+       __sighandler_t  sa_handler;
+       sigset32_t      sa_mask;
+       unsigned int    sa_flags;
+
+       /* XXX 32-bit func ptr... */
+       void (*sa_restorer) (void);     /* not used by Linux/SPARC yet */
+};
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_ASMSPARC64_SIGNAL_H) */
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
new file mode 100644 (file)
index 0000000..4792c78
--- /dev/null
@@ -0,0 +1,179 @@
+/* smp.h: Sparc64 specific SMP stuff.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SMP_H
+#define _SPARC64_SMP_H
+
+#include <asm/asi.h>
+
+#ifndef __ASSEMBLY__
+/* PROM provided per-processor information we need
+ * to start them all up.
+ */
+
+struct prom_cpuinfo {
+       int prom_node;
+       int mid;
+};
+#endif /* !(__ASSEMBLY__) */
+
+#ifdef __SMP__
+
+#ifndef __ASSEMBLY__
+
+extern struct prom_cpuinfo linux_cpus[NCPUS];
+
+/* Per processor Sparc parameters we need. */
+
+struct cpuinfo_sparc {
+       unsigned long udelay_val; /* that's it */
+};
+
+extern struct cpuinfo_sparc cpu_data[NR_CPUS];
+
+typedef __volatile__ unsigned char klock_t;
+extern klock_t kernel_flag;
+
+#define KLOCK_HELD       0xff
+#define KLOCK_CLEAR      0x00
+
+/*
+ *     Private routines/data
+ */
+extern int smp_found_cpus;
+extern unsigned char boot_cpu_id;
+extern unsigned int cpu_present_map;
+extern __volatile__ unsigned long smp_invalidate_needed[NR_CPUS];
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned char active_kernel_processor;
+extern void smp_message_irq(void);
+extern unsigned long ipi_count;
+extern __volatile__ unsigned long kernel_counter;
+extern __volatile__ unsigned long syscall_count;
+
+extern void print_lock_state(void);
+
+typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+                      unsigned long, unsigned long);
+
+/*
+ *     General functions that each host system must provide.
+ */
+
+extern void smp_callin(void);
+extern void smp_boot_cpus(void);
+extern void smp_store_cpu_info(int id);
+extern void smp_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3, unsigned long arg4, unsigned long arg5);
+extern void smp_capture(void);
+extern void smp_release(void);
+
+extern __inline__ void xc0(smpfunc_t func) { smp_cross_call(func, 0, 0, 0, 0, 0); }
+extern __inline__ void xc1(smpfunc_t func, unsigned long arg1)
+{ smp_cross_call(func, arg1, 0, 0, 0, 0); }
+extern __inline__ void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
+{ smp_cross_call(func, arg1, arg2, 0, 0, 0); }
+extern __inline__ void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3)
+{ smp_cross_call(func, arg1, arg2, arg3, 0, 0); }
+extern __inline__ void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3, unsigned long arg4)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, 0); }
+extern __inline__ void xc5(smpfunc_t func, unsigned long arg1, unsigned long arg2,
+                          unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{ smp_cross_call(func, arg1, arg2, arg3, arg4, arg5); }
+
+extern __volatile__ int cpu_number_map[NR_CPUS];
+extern __volatile__ int cpu_logical_map[NR_CPUS];
+
+extern __inline__ int smp_processor_id(void)
+{
+       int cpuid;
+
+       /* Get MID from UPA Config register, and use that. */
+       __asm__ __volatile__("
+               ldxa    [%g0] %1, %0
+               srlx    %0, 17, %0
+               and     %0, 0x1f, %0
+       " : "=r" cpuid
+         : "i" (ASI_UPA_CONFIG));
+
+       return cpuid;
+}
+
+
+extern __volatile__ unsigned long smp_proc_in_lock[NR_CPUS]; /* for computing process time */
+extern __volatile__ int smp_process_available;
+
+extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr)
+{
+       unsigned long temp0, temp1;
+
+       __asm__ __volatile__("
+       lduw            [%2], %0
+1:
+       add             %0, 1, %1
+       cas             [%2], %0, %1
+       cmp             %0, %1
+       bne,a,pn        %%icc, 1b
+        lduw           [%2], %0
+2:
+       membar          #StoreStore | #StoreLoad
+"      : "=&r" (temp0), "=&r" (temp1), "=r" (ctr)
+       : "ir" (i), "r" (ctr));
+}
+
+extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr)
+{
+       unsigned long temp0, temp1;
+
+       __asm__ __volatile__("
+       lduw            [%2], %0
+1:
+       sub             %0, 1, %1
+       cas             [%2], %0, %1
+       cmp             %0, %1
+       bne,a,pn        %%icc, 1b
+        lduw           [%2], %0
+2:
+       membar          #StoreStore | #StoreLoad
+"      : "=&r" (temp0), "=&r" (temp1), "=r" (ctr)
+       : "ir" (i), "r" (ctr));
+}
+
+extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
+{
+       return *ctr;
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+/* Sparc specific messages. */
+#define MSG_CAPTURE            0x0004       /* Park a processor. */
+#define MSG_CROSS_CALL         0x0005       /* run func on cpus */
+
+/* Empirical PROM processor mailbox constants.  If the per-cpu mailbox
+ * contains something other than one of these then the ipi is from
+ * Linux's active_kernel_processor.  This facility exists so that
+ * the boot monitor can capture all the other cpus when one catches
+ * a watchdog reset or the user enters the monitor using L1-A keys.
+ */
+#define MBOX_STOPCPU          0xFB
+#define MBOX_IDLECPU          0xFC
+#define MBOX_IDLECPU2         0xFD
+#define MBOX_STOPCPU2         0xFE
+
+
+#define NO_PROC_ID            0xFF
+
+#define PROC_CHANGE_PENALTY     20
+
+#define SMP_FROM_INT           1
+#define SMP_FROM_SYSCALL       2
+
+#endif /* !(__SMP__) */
+
+#endif /* !(_SPARC64_SMP_H) */
diff --git a/include/asm-sparc64/smp_lock.h b/include/asm-sparc64/smp_lock.h
new file mode 100644 (file)
index 0000000..d1e01de
--- /dev/null
@@ -0,0 +1,60 @@
+/* smp_lock.h: Locking and unlocking the kernel on the 64-bit Sparc.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_SMPLOCK_H
+#define __SPARC64_SMPLOCK_H
+
+#include <asm/smp.h>
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
+
+#ifdef __SMP__
+
+extern __inline__ __volatile__ unsigned char ldstub(volatile unsigned char *lock)
+{
+       volatile unsigned char retval;
+
+       __asm__ __volatile__("ldstub [%1], %0" : "=&r" (retval) : "r" (lock));
+       return retval;
+}
+
+/*
+ *     Locking the kernel 
+ */
+
+/* Knock knock... */
+extern __inline__ void lock_kernel(void)
+{
+       int proc = smp_processor_id();
+
+       while(ldstub(&kernel_flag)) {
+               if(proc == active_kernel_processor)
+                       break;
+               do {
+#ifdef __SMP_PROF__            
+                       smp_spins[smp_processor_id()]++;
+#endif                 
+                       barrier();
+               } while(kernel_flag); /* Don't lock the bus more than we have to. */
+       }
+       active_kernel_processor = proc;
+       kernel_counter++;
+}
+
+/* I want out... */
+extern __inline__ void unlock_kernel(void)
+{
+       if(kernel_counter == 0)
+               panic("Bogus kernel counter.\n");
+
+       if(!--kernel_counter) {
+               active_kernel_processor = NO_PROC_ID;
+               kernel_flag = KLOCK_CLEAR;
+       }
+}
+
+#endif /* (__SMP__) */
+
+#endif /* !(__SPARC64_SMPLOCK_H) */
diff --git a/include/asm-sparc64/socket.h b/include/asm-sparc64/socket.h
new file mode 100644 (file)
index 0000000..4b597fe
--- /dev/null
@@ -0,0 +1,38 @@
+/* $Id: socket.h,v 1.1 1996/12/26 14:22:39 davem Exp $ */
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET     0xffff
+
+#define SO_DEBUG       0x0001
+#define SO_PASSCRED    0x0002
+#define SO_REUSEADDR   0x0004
+#define SO_KEEPALIVE   0x0008
+#define SO_DONTROUTE   0x0010
+#define SO_BROADCAST   0x0020
+#define SO_PEERCRED    0x0040
+#define SO_LINGER      0x0080
+#define SO_OOBINLINE   0x0100
+/* To add :#define SO_REUSEPORT 0x0200 */
+#define SO_BSDCOMPAT    0x0400
+#define SO_RCVLOWAT     0x0800
+#define SO_SNDLOWAT     0x1000
+#define SO_RCVTIMEO     0x2000
+#define SO_SNDTIMEO     0x4000
+
+/* wha!??? */
+#define SO_DONTLINGER   (~SO_LINGER)  /* Older SunOS compat. hack */
+
+#define SO_SNDBUF      0x1001
+#define SO_RCVBUF      0x1002
+#define SO_ERROR       0x1007
+#define SO_TYPE                0x1008
+
+/* Linux specific, keep the same. */
+#define SO_NO_CHECK    0x000b
+#define SO_PRIORITY    0x000c
+
+#endif /* _ASM_SOCKET_H */
diff --git a/include/asm-sparc64/sockios.h b/include/asm-sparc64/sockios.h
new file mode 100644 (file)
index 0000000..6735bab
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _ASM_SPARC64_SOCKIOS_H
+#define _ASM_SPARC64_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN      0x8901
+#define SIOCSPGRP      0x8902
+#define FIOGETOWN      0x8903
+#define SIOCGPGRP      0x8904
+#define SIOCATMARK     0x8905
+#define SIOCGSTAMP     0x8906          /* Get stamp */
+
+#endif /* !(_ASM_SPARC64_SOCKIOS_H) */
+
diff --git a/include/asm-sparc64/solerrno.h b/include/asm-sparc64/solerrno.h
new file mode 100644 (file)
index 0000000..a2ea6fc
--- /dev/null
@@ -0,0 +1,132 @@
+/* $Id: solerrno.h,v 1.1 1996/12/26 14:22:40 davem Exp $
+ * solerrno.h: Solaris error return codes for compatibility.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SOLERRNO_H
+#define _SPARC64_SOLERRNO_H
+
+#define SOL_EPERM          1     /* Required superuser access perms  */
+#define SOL_ENOENT         2     /* File or directory does not exist */
+#define SOL_ESRCH          3     /* Process did not exist            */
+#define        SOL_EINTR          4     /* System call was interrupted      */
+#define        SOL_EIO            5     /* An i/o error occurred            */
+#define        SOL_ENXIO          6     /* Device or Address does not exist */
+#define        SOL_E2BIG          7     /* Too many arguments were given    */
+#define        SOL_ENOEXEC        8     /* Header of executable was munged  */
+#define        SOL_EBADF          9     /* Bogus file number                */
+#define        SOL_ECHILD         10    /* No children of process exist     */
+#define        SOL_EAGAIN         11    /* beep beep, "try again later"     */
+#define        SOL_ENOMEM         12    /* No memory available              */
+#define        SOL_EACCES         13    /* Access not allowed               */
+#define        SOL_EFAULT         14    /* Address passed was invalid       */
+#define        SOL_ENOTBLK        15    /* blkdev op on non-block device    */
+#define        SOL_EBUSY          16    /* Mounted device was busy          */
+#define        SOL_EEXIST         17    /* File specified already exists    */
+#define        SOL_EXDEV          18    /* Link request across diff devices */
+#define        SOL_ENODEV         19    /* Device does not exist on system  */
+#define        SOL_ENOTDIR        20    /* Dir operation on non-directory   */
+#define        SOL_EISDIR         21    /* File was of directory type       */
+#define        SOL_EINVAL         22    /* Argument passed was invalid      */
+#define        SOL_ENFILE         23    /* No more room in file table       */
+#define        SOL_EMFILE         24    /* Proc has too many files open     */
+#define        SOL_ENOTTY         25    /* Ioctl was invalid for req device */
+#define        SOL_ETXTBSY        26    /* Text file in busy state          */
+#define        SOL_EFBIG          27    /* Too big of a file for operation  */
+#define        SOL_ENOSPC         28    /* Disk is full                     */
+#define        SOL_ESPIPE         29    /* Seek attempted on non-seeking dev*/
+#define        SOL_EROFS          30    /* Write attempted on read-only fs  */
+#define        SOL_EMLINK         31    /* Too many links in file search    */
+#define        SOL_EPIPE          32    /* Call a plumber                   */
+#define        SOL_EDOM           33    /* Argument was out of fct domain   */
+#define        SOL_ERANGE         34    /* Could not represent math result  */
+#define        SOL_ENOMSG         35    /* Message of req type doesn't exist */
+#define        SOL_EIDRM          36    /* Identifier has been removed      */
+#define        SOL_ECHRNG         37    /* Req channel number out of range  */
+#define        SOL_EL2NSYNC       38    /* Could not sync at run level 2    */
+#define        SOL_EL3HLT         39    /* Halted at run level 3            */
+#define        SOL_EL3RST         40    /* Reset at run level 3             */
+#define        SOL_ELNRNG         41    /* Out of range link number         */
+#define        SOL_EUNATCH        42    /* Driver for protocol not attached */
+#define        SOL_ENOCSI         43    /* CSI structure not around         */
+#define        SOL_EL2HLT         44    /* Halted at run level 2            */
+#define        SOL_EDEADLK        45    /* Deadlock condition detected      */
+#define        SOL_ENOLCK         46    /* Record locks unavailable         */
+#define        SOL_ECANCELED      47    /* Cancellation of oper. happened   */
+#define        SOL_ENOTSUP        48    /* Attempt of unsupported operation */
+#define        SOL_EDQUOT         49    /* Users disk quota exceeded        */
+#define        SOL_EBADE          50    /* Invalid exchange                 */
+#define        SOL_EBADR          51    /* Request descriptor was invalid   */
+#define        SOL_EXFULL         52    /* Full exchange                    */
+#define        SOL_ENOANO         53    /* ano does not exist               */
+#define        SOL_EBADRQC        54    /* Req code was invalid             */
+#define        SOL_EBADSLT        55    /* Bad slot number                  */
+#define        SOL_EDEADLOCK      56    /* Deadlock in fs error             */
+#define        SOL_EBFONT         57    /* Font file format invalid         */
+/* YOW, I LOVE SYSV STREAMS!!!! */
+#define        SOL_ENOSTR         60    /* Stream-op on non-stream dev      */
+#define        SOL_ENODATA        61    /* No data avail at this time       */
+#define        SOL_ETIME          62    /* Expiration of time occurred      */
+#define        SOL_ENOSR          63    /* Streams resources exhausted      */
+#define        SOL_ENONET         64    /* No network connected             */
+#define        SOL_ENOPKG         65    /* Non-installed package            */
+#define        SOL_EREMOTE        66    /* Object was on remote machine     */
+#define        SOL_ENOLINK        67    /* Cut link                         */
+#define        SOL_EADV           68    /* Error in advertise               */
+#define        SOL_ESRMNT         69    /* Some magic srmount problem       */
+#define        SOL_ECOMM          70    /* During send, comm error occurred */
+#define        SOL_EPROTO         71    /* Protocol botch                   */
+#define        SOL_EMULTIHOP      74    /* Multihop attempted               */
+#define        SOL_EBADMSG        77    /* Message was unreadable           */
+#define        SOL_ENAMETOOLONG   78    /* Too long of a path name          */
+#define        SOL_EOVERFLOW      79    /* Data type too small for datum    */
+#define        SOL_ENOTUNIQ       80    /* Logical name was not unique      */
+#define        SOL_EBADFD         81    /* Op cannot be performed on fd     */
+#define        SOL_EREMCHG        82    /* Remote address is now different  */
+#define        SOL_ELIBACC        83    /* Shared lib could not be accessed */
+#define        SOL_ELIBBAD        84    /* ShLib is corrupted in some way   */
+#define        SOL_ELIBSCN        85    /* A.out ShLib problems             */
+#define        SOL_ELIBMAX        86    /* Exceeded ShLib linkage limit     */
+#define        SOL_ELIBEXEC       87    /* Execution of ShLib attempted     */
+#define        SOL_EILSEQ         88    /* Bad byte sequence found          */
+#define        SOL_ENOSYS         89    /* Invalid filesystem operation     */
+#define        SOL_ELOOP          90    /* Detected loop in symbolic links  */
+#define        SOL_ERESTART       91    /* System call is restartable       */
+#define        SOL_ESTRPIPE       92    /* Do not sleep in head of stream   */
+#define        SOL_ENOTEMPTY      93    /* Rmdir of non-empty directory     */
+#define        SOL_EUSERS         94    /* Over abundance of users for ufs  */
+#define        SOL_ENOTSOCK       95    /* Sock-op on non-sock              */
+#define        SOL_EDESTADDRREQ   96    /* No dest addr given, but needed   */
+#define        SOL_EMSGSIZE       97    /* Msg too big                      */
+#define        SOL_EPROTOTYPE     98    /* Bad socket protocol              */
+#define        SOL_ENOPROTOOPT    99    /* Unavailable protocol             */
+#define        SOL_EPROTONOSUPPORT 120  /* Unsupported protocol             */
+#define        SOL_ESOCKTNOSUPPORT 121  /* Unsupported socket type          */
+#define        SOL_EOPNOTSUPP     122   /* Unsupported sock-op              */
+#define        SOL_EPFNOSUPPORT   123   /* Unsupported protocol family      */
+#define        SOL_EAFNOSUPPORT   124   /* Unsup addr family for protocol   */
+#define        SOL_EADDRINUSE     125   /* Req addr is already in use       */
+#define        SOL_EADDRNOTAVAIL  126   /* Req addr not available right now */
+#define        SOL_ENETDOWN       127   /* Your subnet is on fire           */
+#define        SOL_ENETUNREACH    128   /* Someone playing with gateway and */
+                                 /* did not tell you he was going to */
+#define        SOL_ENETRESET      129   /* Buy less-buggy ethernet cards    */
+#define        SOL_ECONNABORTED   130   /* Aborted connection due to sw     */
+#define        SOL_ECONNRESET     131   /* Your peers reset your connection */
+#define        SOL_ENOBUFS        132   /* No buffer space available        */
+#define        SOL_EISCONN        133   /* Connect on already connected     */
+                                 /* socket attempted                 */
+#define        SOL_ENOTCONN       134   /* Comm on non-connected socket     */
+#define        SOL_ESHUTDOWN      143   /* Op attempted after sock-shutdown */
+#define        SOL_ETOOMANYREFS   144   /* Reference limit exceeded         */
+#define        SOL_ETIMEDOUT      145   /* Timed out connection             */
+#define        SOL_ECONNREFUSED   146   /* Connection refused by remote host*/
+#define        SOL_EHOSTDOWN      147   /* Remote host is up in flames      */
+#define        SOL_EHOSTUNREACH   148   /* Make a left at Easton Ave.....   */
+#define        SOL_EWOULDBLOCK    EAGAIN /* Just an alias */
+#define        SOL_EALREADY       149   /* Operation is already occurring   */
+#define        SOL_EINPROGRESS    150   /* Operation is happening now       */
+#define        SOL_ESTALE         151   /* Fungus growth on NFS file handle */
+
+#endif /* !(_SPARC64_SOLERRNO_H) */
diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h
new file mode 100644 (file)
index 0000000..1c776f9
--- /dev/null
@@ -0,0 +1,197 @@
+/* $Id: spitfire.h,v 1.2 1996/12/28 18:39:55 davem Exp $
+ * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_SPITFIRE_H
+#define _SPARC64_SPITFIRE_H
+
+#include <asm/asi.h>
+
+/* The following register addresses are accessible via ASI_DMMU
+ * and ASI_IMMU, that is there is a distinct and unique copy of
+ * each these registers for each TLB.
+ */
+#define TSB_TAG_TARGET         0x0000000000000000
+#define TLB_SFSR               0x0000000000000018
+#define TSB_REG                        0x0000000000000028
+#define TLB_TAG_ACCESS         0x0000000000000030
+
+/* These registers only exist as one entity, and are accessed
+ * via ASI_DMMU only.
+ */
+#define PRIMARY_CONTEXT                0x0000000000000008
+#define SECONDARY_CONTEXT      0x0000000000000010
+#define DMMU_SFAR              0x0000000000000020
+#define VIRT_WATCHPOINT                0x0000000000000038
+#define PHYS_WATCHPOINT                0x0000000000000040
+
+#ifndef __ASSEMBLY__
+
+extern __inline__ unsigned long spitfire_get_primary_context(void)
+{
+       unsigned long ctx;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (ctx)
+                            : "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_set_primary_context(unsigned long ctx)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : : "r" (ctx), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_get_secondary_context(void)
+{
+       unsigned long ctx;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (ctx)
+                            : "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+extern __inline__ unsigned long spitfire_set_secondary_context(unsigned long ctx)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : : "r" (ctx), "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU));
+}
+
+/* The data cache is write through, so this just invalidates the
+ * specified line.
+ */
+extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : /* No outputs */
+                            : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
+}
+
+/* The instruction cache lines are flushed with this, but note that
+ * this does not flush the pipeline.  It is possible for a line to
+ * get flushed but stale instructions to still be in the pipeline,
+ * a flush instruction (to any address) is sufficient to handle
+ * this issue after the line is invalidated.
+ */
+extern __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : /* No outputs */
+                            : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
+}
+
+extern __inline__ unsigned long spitfire_get_dtlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
+       return data;
+}
+
+extern __inline__ unsigned long spitfire_put_dtlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : : "r" (data), "r" (entry << 3),
+                                "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+extern __inline__ unsigned long spitfire_get_itlb_data(int entry)
+{
+       unsigned long data;
+
+       __asm__ __volatile__("ldxa      [%1] %2, %0"
+                            : "=r" (data)
+                            : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
+       return data;
+}
+
+extern __inline__ unsigned long spitfire_put_itlb_data(int entry, unsigned long data)
+{
+       __asm__ __volatile__("stxa      %0, [%1] %2"
+                            : : "r" (data), "r" (entry << 3),
+                                "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+/* Spitfire hardware assisted TLB flushes. */
+
+/* Context level flushes. */
+extern __inline__ void spitfire_flush_dtlb_primary_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x40), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_primary_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x40), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_secondary_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x41), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_secondary_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x41), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_nucleus_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x42), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_nucleus_context(void)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (0x42), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Page level flushes. */
+extern __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_primary_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page)
+{
+       __asm__ __volatile__("stxa      %%g0, [%0] %1"
+                            : : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
+}
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* !(_SPARC64_SPITFIRE_H) */
diff --git a/include/asm-sparc64/stat.h b/include/asm-sparc64/stat.h
new file mode 100644 (file)
index 0000000..dd9a4a7
--- /dev/null
@@ -0,0 +1,62 @@
+/* $Id: stat.h,v 1.1 1996/12/26 14:22:31 davem Exp $ */
+#ifndef _SPARC64_STAT_H
+#define _SPARC64_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+       unsigned short st_dev;
+       unsigned short st_ino;
+       unsigned short st_mode;
+       unsigned short st_nlink;
+       unsigned short st_uid;
+       unsigned short st_gid;
+       unsigned short st_rdev;
+       unsigned long  st_size;
+       unsigned long  st_atime;
+       unsigned long  st_mtime;
+       unsigned long  st_ctime;
+};
+
+/* XXX Fix this for full backwards 32-bit compat. */
+struct stat32 {
+       dev_t   st_dev;
+       ino_t   st_ino;
+       mode_t  st_mode;
+       short   st_nlink;
+       uid_t   st_uid;
+       gid_t   st_gid;
+       dev_t   st_rdev;
+       off_t   st_size;
+       time_t  st_atime;
+       unsigned int  __unused1;
+       time_t  st_mtime;
+       unsigned int  __unused2;
+       time_t  st_ctime;
+       unsigned int  __unused3;
+       off_t   st_blksize;
+       off_t   st_blocks;
+       unsigned int  __unused4[2];
+};
+
+struct stat {
+       dev_t   st_dev;
+       ino_t   st_ino;
+       mode_t  st_mode;
+       short   st_nlink;
+       uid_t   st_uid;
+       gid_t   st_gid;
+       dev_t   st_rdev;
+       off_t   st_size;
+       time_t  st_atime;
+       unsigned long  __unused1;
+       time_t  st_mtime;
+       unsigned long  __unused2;
+       time_t  st_ctime;
+       unsigned long  __unused3;
+       off_t   st_blksize;
+       off_t   st_blocks;
+       unsigned long  __unused4[2];
+};
+
+#endif
diff --git a/include/asm-sparc64/statfs.h b/include/asm-sparc64/statfs.h
new file mode 100644 (file)
index 0000000..1e976b7
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id: statfs.h,v 1.1 1996/12/26 14:22:40 davem Exp $ */
+#ifndef _SPARC64_STATFS_H
+#define _SPARC64_STATFS_H
+
+#ifndef __KERNEL_STRICT_NAMES
+
+#include <linux/types.h>
+
+typedef __kernel_fsid_t        fsid_t;
+
+#endif
+
+/* XXX Fix this for full backwards 32-bit compat. */
+struct statfs32 {
+       int f_type;
+       int f_bsize;
+       int f_blocks;
+       int f_bfree;
+       int f_bavail;
+       int f_files;
+       int f_ffree;
+       __kernel_fsid_t f_fsid;
+       int f_namelen;  /* SunOS ignores this field. */
+       int f_spare[6];
+};
+
+struct statfs {
+       long f_type;
+       long f_bsize;
+       long f_blocks;
+       long f_bfree;
+       long f_bavail;
+       long f_files;
+       long f_ffree;
+       __kernel_fsid_t f_fsid;
+       long f_namelen;
+       long f_spare[6];
+};
+
+#endif
diff --git a/include/asm-sparc64/string.h b/include/asm-sparc64/string.h
new file mode 100644 (file)
index 0000000..df26bfd
--- /dev/null
@@ -0,0 +1,178 @@
+/* $Id: string.h,v 1.1 1996/12/26 14:22:40 davem Exp $
+ * string.h: External definitions for optimized assembly string
+ *           routines for the Linux Kernel.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef __SPARC64_STRING_H__
+#define __SPARC64_STRING_H__
+
+/* Really, userland/ksyms should not see any of this stuff. */
+
+#if defined(__KERNEL__) && !defined(EXPORT_SYMTAB)
+
+/* First the mem*() things. */
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCPY
+extern void *__memcpy(void *,const void *,__kernel_size_t);
+
+extern inline void *__constant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+       extern void __copy_1page(void *, const void *);
+
+       if(n <= 32) {
+               __builtin_memcpy(to, from, n);
+       } else {
+               switch(n) {
+               case 8192:
+                       __copy_1page(to, from);
+                       break;
+               default:
+                       __memcpy(to, from, n);
+                       break;
+               }
+       }
+       return to;
+}
+
+extern inline void *__nonconstant_memcpy(void *to, const void *from, __kernel_size_t n)
+{
+       __memcpy(to, from, n);
+       return to;
+}
+
+#undef memcpy
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __nonconstant_memcpy((t),(f),(n)))
+
+#define __HAVE_ARCH_MEMSET
+extern void *__memset(void *,int,__kernel_size_t);
+
+extern inline void *__constant_c_and_count_memset(void *s, char c, size_t count)
+{
+       extern void *bzero_1page(void *);
+       extern void *__bzero(void *, size_t);
+
+       if(!c) {
+               if(count == 8192)
+                       bzero_1page(s);
+               else
+                       __bzero(s, count);
+       } else {
+               __memset(s, c, count);
+       }
+       return s;
+}
+
+extern inline void *__constant_c_memset(void *s, char c, size_t count)
+{
+       extern void *__bzero(void *, size_t);
+
+       if(!c)
+               __bzero(s, count);
+       else
+               __memset(s, c, count);
+       return s;
+}
+
+#undef memset
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? (__builtin_constant_p(count) ? \
+                            __constant_c_and_count_memset((s), (c), (count)) : \
+                            __constant_c_memset((s), (c), (count))) \
+                         : __memset((s), (c), (count)))
+
+#define __HAVE_ARCH_MEMSCAN
+
+#undef memscan
+#define memscan(__arg0, __char, __arg2)                                                \
+({                                                                             \
+       extern void *__memscan_zero(void *, size_t);                            \
+       extern void *__memscan_generic(void *, int, size_t);                    \
+       void *__retval, *__addr = (__arg0);                                     \
+       size_t __size = (__arg2);                                               \
+                                                                               \
+       if(__builtin_constant_p(__char) && !(__char))                           \
+               __retval = __memscan_zero(__addr, __size);                      \
+       else                                                                    \
+               __retval = __memscan_generic(__addr, (__char), __size);         \
+                                                                               \
+       __retval;                                                               \
+})
+
+#define __HAVE_ARCH_MEMCMP
+
+/* Now the str*() stuff... */
+#define __HAVE_ARCH_STRLEN
+
+#define __HAVE_ARCH_STRNCMP
+
+extern int __strncmp(const char *, const char *, __kernel_size_t);
+
+extern inline int __constant_strncmp(const char *src, const char *dest, __kernel_size_t count)
+{
+       register int retval;
+       switch(count) {
+       case 0: return 0;
+       case 1: return (src[0] - dest[0]);
+       case 2: retval = (src[0] - dest[0]);
+               if(!retval && src[0])
+                 retval = (src[1] - dest[1]);
+               return retval;
+       case 3: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1])
+                   retval = (src[2] - dest[2]);
+               }
+               return retval;
+       case 4: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if (!retval && src[2])
+                     retval = (src[3] - dest[3]);
+                 }
+               }
+               return retval;
+       case 5: retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if (!retval && src[2]) {
+                     retval = (src[3] - dest[3]);
+                     if (!retval && src[3])
+                       retval = (src[4] - dest[4]);
+                   }
+                 }
+               }
+               return retval;
+       default:
+               retval = (src[0] - dest[0]);
+               if(!retval && src[0]) {
+                 retval = (src[1] - dest[1]);
+                 if(!retval && src[1]) {
+                   retval = (src[2] - dest[2]);
+                   if(!retval && src[2])
+                     retval = __strncmp(src+3,dest+3,count-3);
+                 }
+               }
+               return retval;
+       }
+}
+
+#undef strncmp
+#define strncmp(__arg0, __arg1, __arg2)        \
+(__builtin_constant_p(__arg2) ?        \
+ __constant_strncmp(__arg0, __arg1, __arg2) : \
+ __strncmp(__arg0, __arg1, __arg2))
+
+#endif /* (__KERNEL__) && !(EXPORT_SYMTAB) */
+
+#endif /* !(__SPARC64_STRING_H__) */
diff --git a/include/asm-sparc64/svr4.h b/include/asm-sparc64/svr4.h
new file mode 100644 (file)
index 0000000..13f59bb
--- /dev/null
@@ -0,0 +1,130 @@
+/* Solaris/SPARC constants and definitions -- 
+ * (C) 1996 Miguel de Icaza
+ *
+ * This file is not meant to be included by user level applications
+ * but the solaris syscall emulator
+ */
+
+#ifndef _SPARC64_SVR4_H
+#define _SPARC64_SVR4_H
+
+/* Signals as used by svr4 */
+typedef struct {                /* signal set type */
+       uint sigbits[4];
+} svr4_sigset_t;
+
+/* Values for siginfo.code */
+#define SVR4_SINOINFO 32767
+/* Siginfo, sucker expects bunch of information on those parameters */
+typedef union {
+       char total_size [128];
+       struct {
+               int signo;
+               int code;
+               int error;
+               union {
+               } data; 
+       } siginfo;
+} svr4_siginfo_t;
+
+/* Context definition */
+
+/* Location of the user stored registers into a greg_t */
+enum {
+       SVR4_PSR, SVR4_PC, SVR4_NPC, SVR4_Y,
+       SVR4_G1,  SVR4_G2, SVR4_G3,  SVR4_G4,
+       SVR4_G5,  SVR4_G6, SVR4_G7,  SVR4_O0,
+       SVR4_O1,  SVR4_O2, SVR4_O3,  SVR4_O4,
+       SVR4_O5,  SVR4_O6, SVR4_O7
+};
+
+/* sizeof (regs) / sizeof (greg_t), defined in the ABI */
+#define SVR4_NREGS  19
+#define SVR4_MAXWIN 31
+
+typedef struct {
+       uint rwin_lo[8];
+       uint rwin_in[8];
+} svr4_rwindow_t;
+
+typedef struct {
+       int            count;
+
+       /* XXX 32-bit pointers on 64-bit kernel... fixme XXX */
+       int            *winptr [SVR4_MAXWIN]; /* pointer to the windows */
+
+       svr4_rwindow_t win[SVR4_MAXWIN];      /* the windows */
+} svr4_gwindows_t;
+
+typedef int svr4_gregset_t[SVR4_NREGS];
+
+typedef struct {
+       double   fpu_regs[32];
+       void     *fp_q;
+       unsigned fp_fsr;
+       u_char   fp_nqel;
+       u_char   fp_nqsize;
+       u_char   inuse;         /* if fpu is in use */
+} svr4_fregset_t;
+
+typedef struct {
+       uint    id;             /* if this holds "xrs" string => ptr is valid */
+
+       /* XXX what is caddr_t on sparc64?? XXX */
+       caddr_t ptr;
+} svr4_xrs_t;
+
+/* Machine dependant context */
+typedef struct {
+       svr4_gregset_t   greg;  /* registers 0..19 (see top) */
+
+       /* XXX 32-bit pointers again... fixme XXX */
+       svr4_gwindows_t  *gwin; /* may point to register windows */
+
+       svr4_fregset_t   freg;  /* floating point registers */
+       svr4_xrs_t       xrs;   /* mhm? */
+       int              pad[19];
+} svr4_mcontext_t;
+
+/* flags for stack_t.flags */
+enum svr4_stack_flags {
+       SS_ONSTACK,
+       SVR4_SS_DISABLE,
+};
+
+/* signal stack exection place, unsupported */
+typedef struct svr4_stack_t {
+        char *sp;
+        int  size;
+        int  flags;
+} svr4_stack_t;
+
+/* Context used by getcontext and setcontext */
+typedef struct svr4_ucontext_t {
+       u_int                flags; /* context flags, indicate what is loaded */
+
+       /* XXX 32-bit pointer... fixme XXX */
+       struct svr4_ucontext *link;
+
+       svr4_sigset_t        sigmask;
+       svr4_stack_t         stack;
+       svr4_mcontext_t      mcontext;
+       int                  pad[23];
+} svr4_ucontext_t;                          
+
+/* windows hold the windows as they were at signal time,
+ * ucontext->mcontext holds a pointer to them.
+ * addresses for uc and si are passed as parameters to svr4 signal
+ * handler
+ */
+
+/* This is the signal frame that is passed to the signal handler */
+typedef struct {
+       svr4_gwindows_t gw;     /* windows */
+       svr4_ucontext_t uc;     /* machine context */
+       svr4_siginfo_t  si;     /* siginfo */
+} svr4_signal_frame_t;
+
+#define SVR4_SF_ALIGNED (((sizeof (svr4_signal_frame_t) + 7) & (~7)))
+
+#endif /* include control */
index d2140b57c75c33f5b5acd683dc56bbc802b7fcd9..d3c8a31a37c3f3e1cb194c28b254c7f90cdeabd5 100644 (file)
@@ -1,7 +1,10 @@
-/* $Id: system.h,v 1.2 1996/12/02 00:01:07 davem Exp $ */
+/* $Id: system.h,v 1.4 1996/12/28 18:39:56 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+
 #define setipl(__new_ipl) \
        __asm__ __volatile__("wrpr      %0, %%pil"  : : "r" (__new_ipl) : "memory")
 
 
 #define membar(type)   __asm__ __volatile__ ("membar " type : : : "memory");
 
+#define flushi(addr)   __asm__ __volatile__ ("flush %0" : : "r" (addr))
+
+#define flushw_all()   __asm__ __volatile__("flushw")
+
+#ifndef __ASSEMBLY__
+
+extern __inline__ void flushw_user(void)
+{
+       __asm__ __volatile__("
+               rdpr            %%otherwin, %%g1
+1:
+               rdpr            %%otherwin, %%g2
+               brnz,pn         %%g2, 1b
+                save           %%sp, %0, %%sp
+1:
+               subcc           %%g1, 1, %%g1
+               bne,pn          %%xcc, 1b
+                restore        %%g0, %%g0, %%g0
+       " : : "i" (-REGWIN_SZ)
+         : "g1", "g2");
+}
+
 /* Unlike the hybrid v7/v8 kernel, we can assume swap exists under V9. */
 extern __inline__ unsigned long xchg_u32(__volatile__ unsigned int *m, unsigned int val)
 {
@@ -87,4 +112,6 @@ static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
        return x;
 }
 
+#endif /* !(__ASSEMBLY__) */
+
 #endif /* !(__SPARC64_SYSTEM_H) */
diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h
new file mode 100644 (file)
index 0000000..5212dcd
--- /dev/null
@@ -0,0 +1,210 @@
+#ifndef _SPARC64_TERMBITS_H
+#define _SPARC64_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char   cc_t;
+typedef unsigned int    speed_t;
+
+/* XXX is this right for sparc64?  it was an unsigned long... XXX */
+typedef unsigned int    tcflag_t;
+
+#define NCC 8
+struct termio {
+       unsigned short c_iflag;         /* input mode flags */
+       unsigned short c_oflag;         /* output mode flags */
+       unsigned short c_cflag;         /* control mode flags */
+       unsigned short c_lflag;         /* local mode flags */
+       unsigned char c_line;           /* line discipline */
+       unsigned char c_cc[NCC];        /* control characters */
+};
+
+#define NCCS 17
+struct termios {
+       tcflag_t c_iflag;               /* input mode flags */
+       tcflag_t c_oflag;               /* output mode flags */
+       tcflag_t c_cflag;               /* control mode flags */
+       tcflag_t c_lflag;               /* local mode flags */
+       cc_t c_line;                    /* line discipline */
+       cc_t c_cc[NCCS];                /* control characters */
+#ifdef __KERNEL__
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+       cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
+#endif
+};
+
+/* c_cc characters */
+#define VINTR    0
+#define VQUIT    1
+#define VERASE   2
+#define VKILL    3
+#define VEOF     4
+#define VEOL     5
+#define VEOL2    6
+#define VSWTC    7
+#define VSTART   8
+#define VSTOP    9
+
+
+
+#define VSUSP    10
+#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifdef __KERNEL__
+#define VMIN     16
+#define VTIME    17
+#else
+#define VMIN     VEOF
+#define VTIME    VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK 0x00000001
+#define BRKINT 0x00000002
+#define IGNPAR 0x00000004
+#define PARMRK 0x00000008
+#define INPCK  0x00000010
+#define ISTRIP 0x00000020
+#define INLCR  0x00000040
+#define IGNCR  0x00000080
+#define ICRNL  0x00000100
+#define IUCLC  0x00000200
+#define IXON   0x00000400
+#define IXANY  0x00000800
+#define IXOFF  0x00001000
+#define IMAXBEL        0x00002000
+
+/* c_oflag bits */
+#define OPOST  0x00000001
+#define OLCUC  0x00000002
+#define ONLCR  0x00000004
+#define OCRNL  0x00000008
+#define ONOCR  0x00000010
+#define ONLRET 0x00000020
+#define OFILL  0x00000040
+#define OFDEL  0x00000080
+#define NLDLY  0x00000100
+#define   NL0  0x00000000
+#define   NL1  0x00000100
+#define CRDLY  0x00000600
+#define   CR0  0x00000000
+#define   CR1  0x00000200
+#define   CR2  0x00000400
+#define   CR3  0x00000600
+#define TABDLY 0x00001800
+#define   TAB0 0x00000000
+#define   TAB1 0x00000800
+#define   TAB2 0x00001000
+#define   TAB3 0x00001800
+#define   XTABS        0x00001800
+#define BSDLY  0x00002000
+#define   BS0  0x00000000
+#define   BS1  0x00002000
+#define VTDLY  0x00004000
+#define   VT0  0x00000000
+#define   VT1  0x00004000
+#define FFDLY  0x00008000
+#define   FF0  0x00000000
+#define   FF1  0x00008000
+#define PAGEOUT 0x00010000  /* SUNOS specific */
+#define WRAP    0x00020000  /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD  0x0000000f
+#define  B0    0x00000000   /* hang up */
+#define  B50   0x00000001
+#define  B75   0x00000002
+#define  B110  0x00000003
+#define  B134  0x00000004
+#define  B150  0x00000005
+#define  B200  0x00000006
+#define  B300  0x00000007
+#define  B600  0x00000008
+#define  B1200 0x00000009
+#define  B1800 0x0000000a
+#define  B2400 0x0000000b
+#define  B4800 0x0000000c
+#define  B9600 0x0000000d
+#define  B19200        0x0000000e
+#define  B38400        0x0000000f
+#define EXTA    B19200
+#define EXTB    B38400
+#define  CSIZE  0x00000030
+#define   CS5  0x00000000
+#define   CS6  0x00000010
+#define   CS7  0x00000020
+#define   CS8  0x00000030
+#define CSTOPB 0x00000040
+#define CREAD  0x00000080
+#define PARENB 0x00000100
+#define PARODD 0x00000200
+#define HUPCL  0x00000400
+#define CLOCAL 0x00000800
+/* We'll never see these speeds with the Zilogs' but for completeness... */
+#define CBAUDEX 0x00010000
+#define  B57600  0x00010001
+#define  B115200 0x00010002
+#define  B230400 0x00010003
+#define  B460800 0x00010004
+#define CIBAUD   0x000f0000  /* input baud rate (not used) */
+#define CRTSCTS          0x80000000  /* flow control */
+
+/* c_lflag bits */
+#define ISIG   0x00000001
+#define ICANON 0x00000002
+#define XCASE  0x00000004
+#define ECHO   0x00000008
+#define ECHOE  0x00000010
+#define ECHOK  0x00000020
+#define ECHONL 0x00000040
+#define NOFLSH 0x00000080
+#define TOSTOP 0x00000100
+#define ECHOCTL        0x00000200
+#define ECHOPRT        0x00000400
+#define ECHOKE 0x00000800
+#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
+#define FLUSHO 0x00002000
+#define PENDIN 0x00004000
+#define IEXTEN 0x00008000
+
+/* modem lines */
+#define TIOCM_LE       0x001
+#define TIOCM_DTR      0x002
+#define TIOCM_RTS      0x004
+#define TIOCM_ST       0x008
+#define TIOCM_SR       0x010
+#define TIOCM_CTS      0x020
+#define TIOCM_CAR      0x040
+#define TIOCM_RNG      0x080
+#define TIOCM_DSR      0x100
+#define TIOCM_CD       TIOCM_CAR
+#define TIOCM_RI       TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01   /* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define        TCOOFF          0
+#define        TCOON           1
+#define        TCIOFF          2
+#define        TCION           3
+
+/* tcflush() and TCFLSH use these */
+#define        TCIFLUSH        0
+#define        TCOFLUSH        1
+#define        TCIOFLUSH       2
+
+/* tcsetattr uses these */
+#define        TCSANOW         0
+#define        TCSADRAIN       1
+#define        TCSAFLUSH       2
+
+#endif /* !(_SPARC64_TERMBITS_H) */
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
new file mode 100644 (file)
index 0000000..2696e43
--- /dev/null
@@ -0,0 +1,158 @@
+/* $Id: termios.h,v 1.2 1996/12/30 03:31:12 davem Exp $ */
+#ifndef _SPARC64_TERMIOS_H
+#define _SPARC64_TERMIOS_H
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
+struct sgttyb {
+       char    sg_ispeed;
+       char    sg_ospeed;
+       char    sg_erase;
+       char    sg_kill;
+       short   sg_flags;
+};
+
+struct tchars {
+       char    t_intrc;
+       char    t_quitc;
+       char    t_startc;
+       char    t_stopc;
+       char    t_eofc;
+       char    t_brkc;
+};
+
+struct ltchars {
+       char    t_suspc;
+       char    t_dsuspc;
+       char    t_rprntc;
+       char    t_flushc;
+       char    t_werasc;
+       char    t_lnextc;
+};
+#endif /* __KERNEL__ */
+
+struct sunos_ttysize {
+       int st_lines;   /* Lines on the terminal */
+       int st_columns; /* Columns on the terminal */
+};
+
+/* Used for packet mode */
+#define TIOCPKT_DATA            0
+#define TIOCPKT_FLUSHREAD       1
+#define TIOCPKT_FLUSHWRITE      2
+#define TIOCPKT_STOP            4
+#define TIOCPKT_START           8
+#define TIOCPKT_NOSTOP         16
+#define TIOCPKT_DOSTOP         32
+
+struct winsize {
+       unsigned short ws_row;
+       unsigned short ws_col;
+       unsigned short ws_xpixel;
+       unsigned short ws_ypixel;
+};
+
+/* line disciplines */
+#define N_TTY          0
+#define N_SLIP         1
+#define N_MOUSE                2
+#define N_PPP          3
+#define N_STRIP                4
+#define N_AX25         5
+
+#ifdef __KERNEL__
+
+/*
+ * c_cc characters in the termio structure.  Oh, how I love being
+ * backwardly compatible.  Notice that character 4 and 5 are
+ * interpreted differently depending on whether ICANON is set in
+ * c_lflag.  If it's set, they are used as _VEOF and _VEOL, otherwise
+ * as _VMIN and V_TIME.  This is for compatibility with OSF/1 (which
+ * is compatible with sysV)...
+ */
+#define _VMIN  4
+#define _VTIME 5
+
+/*     intr=^C         quit=^\         erase=del       kill=^U
+       eof=^D          eol=\0          eol2=\0         sxtc=\0
+       start=^Q        stop=^S         susp=^Z         dsusp=^Y
+       reprint=^R      discard=^U      werase=^W       lnext=^V
+       vmin=\1         vtime=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\000\000\000\021\023\032\031\022\025\027\026\001\000"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define user_termio_to_kernel_termios(termios, termio) \
+do { \
+       unsigned short tmp; \
+       get_user(tmp, &(termio)->c_iflag); \
+       (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
+       get_user(tmp, &(termio)->c_oflag); \
+       (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
+       get_user(tmp, &(termio)->c_cflag); \
+       (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
+       get_user(tmp, &(termio)->c_lflag); \
+       (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
+       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+} while(0)
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ *
+ * Note the "fun" _VMIN overloading.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+do { \
+       put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       put_user((termios)->c_line,  &(termio)->c_line); \
+       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+       if (!((termios)->c_lflag & ICANON)) { \
+               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+       } \
+} while(0)
+
+#define user_termios_to_kernel_termios(k, u) \
+do { \
+       get_user((k)->c_iflag, &(u)->c_iflag); \
+       get_user((k)->c_oflag, &(u)->c_oflag); \
+       get_user((k)->c_cflag, &(u)->c_cflag); \
+       get_user((k)->c_lflag, &(u)->c_lflag); \
+       get_user((k)->c_line,  &(u)->c_line); \
+       copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       if((k)->c_lflag & ICANON) { \
+               get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } else { \
+               get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } \
+} while(0)
+
+#define kernel_termios_to_user_termios(u, k) \
+do { \
+       put_user((k)->c_iflag, &(u)->c_iflag); \
+       put_user((k)->c_oflag, &(u)->c_oflag); \
+       put_user((k)->c_cflag, &(u)->c_cflag); \
+       put_user((k)->c_lflag, &(u)->c_lflag); \
+       put_user((k)->c_line, &(u)->c_line); \
+       copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       if(!((k)->c_lflag & ICANON)) { \
+               put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+       } else { \
+               put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+       } \
+} while(0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _SPARC64_TERMIOS_H */
diff --git a/include/asm-sparc64/uaccess.h b/include/asm-sparc64/uaccess.h
new file mode 100644 (file)
index 0000000..08fed53
--- /dev/null
@@ -0,0 +1,380 @@
+/* $Id: uaccess.h,v 1.2 1996/12/26 15:36:53 davem Exp $ */
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+
+#ifdef __KERNEL__
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <asm/a.out.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* Sparc is not segmented, however we need to be able to fool verify_area()
+ * when doing system calls from kernel mode legitimately.
+ *
+ * "For historical reasons, these macros are grossly misnamed." -Linus
+ */
+#define KERNEL_DS   0
+#define USER_DS     -1
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#define get_fs() (current->tss.current_ds)
+#define get_ds() (KERNEL_DS)
+#define set_fs(val) ((current->tss.current_ds) = (val))
+
+/* We have there a nice not-mapped page at page_offset - PAGE_SIZE, so that this test
+ * can be fairly lightweight.
+ * No one can read/write anything from userland in the kernel space by setting
+ * large size and address near to page_offset - a fault will break his intentions.
+ */
+#define __user_ok(addr,size) ((addr) < PAGE_OFFSET)
+#define __kernel_ok (get_fs() == KERNEL_DS)
+#define __access_ok(addr,size) (__user_ok((addr) & get_fs(),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+       return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ *
+ * There is a special way how to put a range of potentially faulting
+ * insns (like twenty ldd/std's with now intervening other instructions)
+ * You specify address of first in insn and 0 in fixup and in the next 
+ * exception_table_entry you specify last potentially faulting insn + 1
+ * and in fixup the routine which should handle the fault.
+ * That fixup code will get
+ * (faulting_insn_address - first_insn_in_the_range_address)/4
+ * in %g2 (ie. index of the faulting instruction in the range).
+ */
+
+struct exception_table_entry
+{
+        unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long, unsigned long *);
+
+extern void __ret_efault(void);
+
+/* Uh, these should become the main single-value transfer routines..
+ * They automatically use the right size if we just have the right
+ * pointer type..
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the uglyness from the user.
+ */
+#define put_user(x,ptr) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__put_user_check((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr))); })
+
+#define put_user_ret(x,ptr,retval) ({ \
+unsigned long __pu_addr = (unsigned long)(ptr); \
+__put_user_check_ret((__typeof__(*(ptr)))(x),__pu_addr,sizeof(*(ptr)),retval); })
+
+#define get_user(x,ptr) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__get_user_check((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr))); })
+
+#define get_user_ret(x,ptr,retval) ({ \
+unsigned long __gu_addr = (unsigned long)(ptr); \
+__get_user_check_ret((x),__gu_addr,sizeof(*(ptr)),__typeof__(*(ptr)),retval); })
+
+/*
+ * The "__xxx" versions do not do address space checking, useful when
+ * doing multiple accesses to the same area (the user has to do the
+ * checks by hand with "access_ok()")
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __put_user_ret(x,ptr,retval) __put_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),retval)
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)))
+#define __get_user_ret(x,ptr,retval) __get_user_nocheck_ret((x),(ptr),sizeof(*(ptr)),__typeof__(*(ptr)),retval)
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) ((struct __large_struct *)(x))
+
+#define __put_user_check(x,addr,size) ({ \
+register int __pu_ret; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,w,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} } else { __pu_ret = -EFAULT; } __pu_ret; })
+
+#define __put_user_check_ret(x,addr,size,retval) ({ \
+register int __foo __asm__ ("l1"); \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
+case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
+case 4: __put_user_asm_ret(x,w,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,x,addr,retval,__foo); break; \
+default: if (__put_user_bad()) return retval; break; \
+} } else return retval; })
+
+#define __put_user_nocheck(x,addr,size) ({ \
+register int __pu_ret; \
+switch (size) { \
+case 1: __put_user_asm(x,b,addr,__pu_ret); break; \
+case 2: __put_user_asm(x,h,addr,__pu_ret); break; \
+case 4: __put_user_asm(x,w,addr,__pu_ret); break; \
+case 8: __put_user_asm(x,x,addr,__pu_ret); break; \
+default: __pu_ret = __put_user_bad(); break; \
+} __pu_ret; })
+
+#define __put_user_nocheck_ret(x,addr,size,retval) ({ \
+register int __foo __asm__ ("l1"); \
+switch (size) { \
+case 1: __put_user_asm_ret(x,b,addr,retval,__foo); break; \
+case 2: __put_user_asm_ret(x,h,addr,retval,__foo); break; \
+case 4: __put_user_asm_ret(x,w,addr,retval,__foo); break; \
+case 8: __put_user_asm_ret(x,x,addr,retval,__foo); break; \
+default: if (__put_user_bad()) return retval; break; \
+} })
+
+#define __put_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Put user asm, inline. */\n"                                 \
+"1:\t" "st"#size " %1, [%2]\n\t"                                       \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "b      2b\n\t"                                                 \
+       " mov   %3, %0\n\n\t"                                           \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\t"                                             \
+       ".text\n\n\t"                                                   \
+       : "=&r" (ret) : "r" (x), "r" (__m(addr)),                       \
+        "i" (-EFAULT))
+
+#define __put_user_asm_ret(x,size,addr,ret,foo)                                \
+if (__builtin_constant_p(ret) && ret == -EFAULT)                       \
+__asm__ __volatile__(                                                  \
+       "/* Put user asm ret, inline. */\n"                             \
+"1:\t" "st"#size " %1, [%2]\n\n\t"                                     \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, __ret_efault\n\n\t"                                 \
+       ".text\n\n\t"                                                   \
+       : "=r" (foo) : "r" (x), "r" (__m(addr)));                       \
+else                                                                   \
+__asm__ __volatile(                                                    \
+       "/* Put user asm ret, inline. */\n"                             \
+"1:\t" "st"#size " %1, [%2]\n\n\t"                                     \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "ret\n\t"                                                       \
+       " restore %%g0, %3, %%o0\n\n\t"                                 \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".text\n\n\t"                                                   \
+       : "=r" (foo) : "r" (x), "r" (__m(addr)), "i" (ret))
+
+extern int __put_user_bad(void);
+
+#define __get_user_check(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} } else { __gu_val = 0; __gu_ret = -EFAULT; } x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_check_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+if (__access_ok(addr,size)) { \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; } else return retval; })
+
+#define __get_user_nocheck(x,addr,size,type) ({ \
+register int __gu_ret; \
+register unsigned long __gu_val; \
+switch (size) { \
+case 1: __get_user_asm(__gu_val,ub,addr,__gu_ret); break; \
+case 2: __get_user_asm(__gu_val,uh,addr,__gu_ret); break; \
+case 4: __get_user_asm(__gu_val,uw,addr,__gu_ret); break; \
+case 8: __get_user_asm(__gu_val,x,addr,__gu_ret); break; \
+default: __gu_val = 0; __gu_ret = __get_user_bad(); break; \
+} x = (type) __gu_val; __gu_ret; })
+
+#define __get_user_nocheck_ret(x,addr,size,type,retval) ({ \
+register unsigned long __gu_val __asm__ ("l1"); \
+switch (size) { \
+case 1: __get_user_asm_ret(__gu_val,ub,addr,retval); break; \
+case 2: __get_user_asm_ret(__gu_val,uh,addr,retval); break; \
+case 4: __get_user_asm_ret(__gu_val,uw,addr,retval); break; \
+case 8: __get_user_asm_ret(__gu_val,x,addr,retval); break; \
+default: if (__get_user_bad()) return retval; \
+} x = (type) __gu_val; })
+
+#define __get_user_asm(x,size,addr,ret)                                        \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm, inline. */\n"                                 \
+"1:\t" "ld"#size " [%2], %1\n\t"                                       \
+       "clr    %0\n"                                                   \
+"2:\n\n\t"                                                             \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "clr    %1\n\t"                                                 \
+       "b      2b\n\t"                                                 \
+       " mov   %3, %0\n\n\t"                                           \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".text\n\t"                                                     \
+       : "=&r" (ret), "=&r" (x) : "r" (__m(addr)),                     \
+        "i" (-EFAULT))
+
+#define __get_user_asm_ret(x,size,addr,retval)                         \
+if (__builtin_constant_p(retval) && retval == -EFAULT)                 \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size " [%1], %0\n\n\t"                                     \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b,__ret_efault\n\n\t"                                  \
+       ".text\n\t"                                                     \
+       : "=&r" (x) : "r" (__m(addr)));                                 \
+else                                                                   \
+__asm__ __volatile__(                                                  \
+       "/* Get user asm ret, inline. */\n"                             \
+"1:\t" "ld"#size " [%1], %0\n\n\t"                                     \
+       ".section .fixup,#alloc,#execinstr\n\t"                         \
+       ".align 4\n"                                                    \
+"3:\n\t"                                                               \
+       "ret\n\t"                                                       \
+       " restore %%g0, %2, %%o0\n\n\t"                                 \
+       ".section __ex_table,#alloc\n\t"                                \
+       ".align 4\n\t"                                                  \
+       ".word  1b, 3b\n\n\t"                                           \
+       ".text\n\t"                                                     \
+       : "=&r" (x) : "r" (__m(addr)), "i" (retval))
+
+extern int __get_user_bad(void);
+
+extern int __copy_user(unsigned long to, unsigned long from, int size);
+
+#define copy_to_user(to,from,n) ({ \
+unsigned long __copy_to = (unsigned long) (to); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_to, __copy_size)) { \
+__copy_res = __copy_user(__copy_to, (unsigned long) (from), __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_to_user_ret(to,from,n,retval) ({ \
+if (copy_to_user(to,from,n)) \
+       return retval; \
+})
+
+#define __copy_to_user(to,from,n)              \
+       __copy_user((unsigned long)(to),        \
+                   (unsigned long)(from), n)
+
+#define __copy_to_user_ret(to,from,n,retval) ({ \
+if (__copy_to_user(to,from,n)) \
+       return retval; \
+})
+
+#define copy_from_user(to,from,n) ({ \
+unsigned long __copy_from = (unsigned long) (from); \
+unsigned long __copy_size = (unsigned long) (n); \
+unsigned long __copy_res; \
+if(__copy_size && __access_ok(__copy_from, __copy_size)) { \
+__copy_res = __copy_user((unsigned long) (to), __copy_from, __copy_size); \
+} else __copy_res = __copy_size; \
+__copy_res; })
+
+#define copy_from_user_ret(to,from,n,retval) ({ \
+if (copy_from_user(to,from,n)) \
+       return retval; \
+})
+
+#define __copy_from_user(to,from,n)            \
+       __copy_user((unsigned long)(to),        \
+                   (unsigned long)(from), n)
+
+#define __copy_from_user_ret(to,from,n,retval) ({ \
+if (__copy_from_user(to,from,n)) \
+       return retval; \
+})
+
+extern int __clear_user(unsigned long addr, int size);
+
+#define clear_user(addr,n) ({ \
+unsigned long __clear_addr = (unsigned long) (addr); \
+int __clear_size = (int) (n); \
+int __clear_res; \
+if(__clear_size && __access_ok(__clear_addr, __clear_size)) { \
+__clear_res = __clear_user(__clear_addr, __clear_size); \
+} else __clear_res = __clear_size; \
+__clear_res; })
+
+#define clear_user_ret(addr,size,retval) ({ \
+if (clear_user(addr,size)) \
+       return retval; \
+})
+
+extern int __strncpy_from_user(unsigned long dest, unsigned long src, int count);
+
+#define strncpy_from_user(dest,src,count) ({ \
+unsigned long __sfu_src = (unsigned long) (src); \
+int __sfu_count = (int) (count); \
+long __sfu_res = -EFAULT; \
+if(__access_ok(__sfu_src, __sfu_count)) { \
+__sfu_res = __strncpy_from_user((unsigned long) (dest), __sfu_src, __sfu_count); \
+} __sfu_res; })
+
+extern int __strlen_user(const char *);
+
+extern __inline__ int strlen_user(const char *str)
+{
+       if(!access_ok(VERIFY_READ, str, 0))
+               return 0;
+       else
+               return __strlen_user(str);
+}
+
+#endif  /* __ASSEMBLY__ */
+
+#endif /* _ASM_UACCESS_H */
diff --git a/include/asm-sparc64/unaligned.h b/include/asm-sparc64/unaligned.h
new file mode 100644 (file)
index 0000000..4f1adb8
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _ASM_SPARC64_UNALIGNED_H_
+#define _ASM_SPARC64_UNALIGNED_H_
+
+/* Sparc can't handle unaligned accesses. */
+
+#include <asm/string.h>
+
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)                                \
+  ({ __typeof__(*(ptr)) __tmp = (val);                 \
+     memmove((ptr), &__tmp, sizeof(*(ptr)));           \
+     (void)0; })
+
+#endif /* _ASM_SPARC64_UNALIGNED_H */
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
new file mode 100644 (file)
index 0000000..f51ae6c
--- /dev/null
@@ -0,0 +1,493 @@
+/* $Id: unistd.h,v 1.1 1996/12/26 14:22:43 davem Exp $ */
+#ifndef _SPARC64_UNISTD_H
+#define _SPARC64_UNISTD_H
+
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+
+#define __NR_setup                0 /* Used only by init, to get system going.     */
+#define __NR_exit                 1 /* Common                                      */
+#define __NR_fork                 2 /* Common                                      */
+#define __NR_read                 3 /* Common                                      */
+#define __NR_write                4 /* Common                                      */
+#define __NR_open                 5 /* Common                                      */
+#define __NR_close                6 /* Common                                      */
+#define __NR_wait4                7 /* Common                                      */
+#define __NR_creat                8 /* Common                                      */
+#define __NR_link                 9 /* Common                                      */
+#define __NR_unlink              10 /* Common                                      */
+#define __NR_execv               11 /* SunOS Specific                              */
+#define __NR_chdir               12 /* Common                                      */
+/* #define __NR_ni_syscall       13    ENOSYS under SunOS                          */
+#define __NR_mknod               14 /* Common                                      */
+#define __NR_chmod               15 /* Common                                      */
+#define __NR_chown               16 /* Common                                      */
+#define __NR_brk                 17 /* Common                                      */
+/* #define __NR_ni_syscall       18    ENOSYS under SunOS                          */
+#define __NR_lseek               19 /* Common                                      */
+#define __NR_getpid              20 /* Common                                      */
+/* #define __NR_ni_syscall       21    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       22    ENOSYS under SunOS                          */
+#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
+#define __NR_getuid              24 /* Common                                      */
+/* #define __NR_ni_syscall       25    ENOSYS under SunOS                          */
+#define __NR_ptrace              26 /* Common                                      */
+#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
+/* #define __NR_ni_syscall       28    ENOSYS under SunOS                          */
+#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
+#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+#define __NR_stty                31 /* Implemented via ioctl() under SunOS         */
+#define __NR_gtty                32 /* Implemented via ioctl() under SunOS         */
+#define __NR_access              33 /* Common                                      */
+#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
+#define __NR_ftime               35 /* Implemented via gettimeofday() in SunOS     */
+#define __NR_sync                36 /* Common                                      */
+#define __NR_kill                37 /* Common                                      */
+#define __NR_stat                38 /* Common                                      */
+/* #define __NR_ni_syscall       39    ENOSYS under SunOS                          */
+#define __NR_lstat               40 /* Common                                      */
+#define __NR_dup                 41 /* Common                                      */
+#define __NR_pipe                42 /* Common                                      */
+#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
+#define __NR_profil              44 /* Common                                      */
+/* #define __NR_ni_syscall       45    ENOSYS under SunOS                          */
+#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
+#define __NR_getgid              47 /* Common                                      */
+#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
+#define __NR_geteuid             49 /* SunOS calls getuid()                        */
+#define __NR_getegid             50 /* SunOS calls getgid()                        */
+#define __NR_acct                51 /* Common                                      */
+/* #define __NR_ni_syscall       52    ENOSYS under SunOS                          */
+#define __NR_mctl                53 /* SunOS specific                              */
+#define __NR_ioctl               54 /* Common                                      */
+#define __NR_reboot              55 /* Common                                      */
+/* #define __NR_ni_syscall       56    ENOSYS under SunOS                          */
+#define __NR_symlink             57 /* Common                                      */
+#define __NR_readlink            58 /* Common                                      */
+#define __NR_execve              59 /* Common                                      */
+#define __NR_umask               60 /* Common                                      */
+#define __NR_chroot              61 /* Common                                      */
+#define __NR_fstat               62 /* Common                                      */
+/* #define __NR_ni_syscall       63    ENOSYS under SunOS                          */
+#define __NR_getpagesize         64 /* Common                                      */
+#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
+/* #define __NR_ni_syscall       66    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       67    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall       68    ENOSYS under SunOS                          */
+#define __NR_sbrk                69 /* SunOS Specific                              */
+#define __NR_sstk                70 /* SunOS Specific                              */
+#define __NR_mmap                71 /* Common                                      */
+#define __NR_vadvise             72 /* SunOS Specific                              */
+#define __NR_munmap              73 /* Common                                      */
+#define __NR_mprotect            74 /* Common                                      */
+#define __NR_madvise             75 /* SunOS Specific                              */
+#define __NR_vhangup             76 /* Common                                      */
+/* #define __NR_ni_syscall       77    ENOSYS under SunOS                          */
+#define __NR_mincore             78 /* SunOS Specific                              */
+#define __NR_getgroups           79 /* Common                                      */
+#define __NR_setgroups           80 /* Common                                      */
+#define __NR_getpgrp             81 /* Common                                      */
+#define __NR_setpgrp             82 /* setpgid, same difference...                 */
+#define __NR_setitimer           83 /* Common                                      */
+/* #define __NR_ni_syscall       84    ENOSYS under SunOS                          */
+#define __NR_swapon              85 /* Common                                      */
+#define __NR_getitimer           86 /* Common                                      */
+#define __NR_gethostname         87 /* SunOS Specific                              */
+#define __NR_sethostname         88 /* Common                                      */
+#define __NR_getdtablesize       89 /* SunOS Specific                              */
+#define __NR_dup2                90 /* Common                                      */
+#define __NR_getdopt             91 /* SunOS Specific                              */
+#define __NR_fcntl               92 /* Common                                      */
+#define __NR_select              93 /* Common                                      */
+#define __NR_setdopt             94 /* SunOS Specific                              */
+#define __NR_fsync               95 /* Common                                      */
+#define __NR_setpriority         96 /* Common                                      */
+#define __NR_socket              97 /* SunOS Specific                              */
+#define __NR_connect             98 /* SunOS Specific                              */
+#define __NR_accept              99 /* SunOS Specific                              */
+#define __NR_getpriority        100 /* Common                                      */
+#define __NR_send               101 /* SunOS Specific                              */
+#define __NR_recv               102 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      103    ENOSYS under SunOS                          */
+#define __NR_bind               104 /* SunOS Specific                              */
+#define __NR_setsockopt         105 /* SunOS Specific                              */
+#define __NR_listen             106 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      107    ENOSYS under SunOS                          */
+#define __NR_sigvec             108 /* SunOS Specific                              */
+#define __NR_sigblock           109 /* SunOS Specific                              */
+#define __NR_sigsetmask         110 /* SunOS Specific                              */
+#define __NR_sigpause           111 /* SunOS Specific                              */
+#define __NR_sigstack           112 /* SunOS Specific                              */
+#define __NR_recvmsg            113 /* SunOS Specific                              */
+#define __NR_sendmsg            114 /* SunOS Specific                              */
+#define __NR_vtrace             115 /* SunOS Specific                              */
+#define __NR_gettimeofday       116 /* Common                                      */
+#define __NR_getrusage          117 /* Common                                      */
+#define __NR_getsockopt         118 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      119    ENOSYS under SunOS                          */
+#define __NR_readv              120 /* Common                                      */
+#define __NR_writev             121 /* Common                                      */
+#define __NR_settimeofday       122 /* Common                                      */
+#define __NR_fchown             123 /* Common                                      */
+#define __NR_fchmod             124 /* Common                                      */
+#define __NR_recvfrom           125 /* SunOS Specific                              */
+#define __NR_setreuid           126 /* Common                                      */
+#define __NR_setregid           127 /* Common                                      */
+#define __NR_rename             128 /* Common                                      */
+#define __NR_truncate           129 /* Common                                      */
+#define __NR_ftruncate          130 /* Common                                      */
+#define __NR_flock              131 /* Common                                      */
+/* #define __NR_ni_syscall      132    ENOSYS under SunOS                          */
+#define __NR_sendto             133 /* SunOS Specific                              */
+#define __NR_shutdown           134 /* SunOS Specific                              */
+#define __NR_socketpair         135 /* SunOS Specific                              */
+#define __NR_mkdir              136 /* Common                                      */
+#define __NR_rmdir              137 /* Common                                      */
+#define __NR_utimes             138 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      139    ENOSYS under SunOS                          */
+#define __NR_adjtime            140 /* SunOS Specific                              */
+#define __NR_getpeername        141 /* SunOS Specific                              */
+#define __NR_gethostid          142 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      143    ENOSYS under SunOS                          */
+#define __NR_getrlimit          144 /* Common                                      */
+#define __NR_setrlimit          145 /* Common                                      */
+#define __NR_killpg             146 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      147    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall      148    ENOSYS under SunOS                          */
+/* #define __NR_ni_syscall      149    ENOSYS under SunOS                          */
+#define __NR_getsockname        150 /* SunOS Specific                              */
+#define __NR_getmsg             151 /* SunOS Specific                              */
+#define __NR_putmsg             152 /* SunOS Specific                              */
+#define __NR_poll               153 /* SunOS Specific                              */
+/* #define __NR_ni_syscall      154    ENOSYS under SunOS                          */
+#define __NR_nfssvc             155 /* SunOS Specific                              */
+#define __NR_getdirentries      156 /* SunOS Specific                              */
+#define __NR_statfs             157 /* Common                                      */
+#define __NR_fstatfs            158 /* Common                                      */
+#define __NR_umount             159 /* Common                                      */
+#define __NR_async_daemon       160 /* SunOS Specific                              */
+#define __NR_getfh              161 /* SunOS Specific                              */
+#define __NR_getdomainname      162 /* SunOS Specific                              */
+#define __NR_setdomainname      163 /* Common                                      */
+/* #define __NR_ni_syscall      164    ENOSYS under SunOS                          */
+#define __NR_quotactl           165 /* Common                                      */
+#define __NR_exportfs           166 /* SunOS Specific                              */
+#define __NR_mount              167 /* Common                                      */
+#define __NR_ustat              168 /* Common                                      */
+#define __NR_semsys             169 /* SunOS Specific                              */
+#define __NR_msgsys             170 /* SunOS Specific                              */
+#define __NR_shmsys             171 /* SunOS Specific                              */
+#define __NR_auditsys           172 /* SunOS Specific                              */
+#define __NR_rfssys             173 /* SunOS Specific                              */
+#define __NR_getdents           174 /* Common                                      */
+#define __NR_setsid             175 /* Common                                      */
+#define __NR_fchdir             176 /* Common                                      */
+#define __NR_fchroot            177 /* SunOS Specific                              */
+#define __NR_vpixsys            178 /* SunOS Specific                              */
+#define __NR_aioread            179 /* SunOS Specific                              */
+#define __NR_aiowrite           180 /* SunOS Specific                              */
+#define __NR_aiowait            181 /* SunOS Specific                              */
+#define __NR_aiocancel          182 /* SunOS Specific                              */
+#define __NR_sigpending         183 /* Common                                      */
+/* #define __NR_ni_syscall      184    ENOSYS under SunOS                          */
+#define __NR_setpgid            185 /* Common                                      */
+#define __NR_pathconf           186 /* SunOS Specific                              */
+#define __NR_fpathconf          187 /* SunOS Specific                              */
+#define __NR_sysconf            188 /* SunOS Specific                              */
+#define __NR_uname              189 /* Linux Specific                              */
+#define __NR_init_module        190 /* Linux Specific                              */
+#define __NR_personality        191 /* Linux Specific                              */
+#define __NR_prof               192 /* Linux Specific                              */
+#define __NR_break              193 /* Linux Specific                              */
+#define __NR_lock               194 /* Linux Specific                              */
+#define __NR_mpx                195 /* Linux Specific                              */
+#define __NR_ulimit             196 /* Linux Specific                              */
+#define __NR_getppid            197 /* Linux Specific                              */
+#define __NR_sigaction          198 /* Linux Specific                              */
+#define __NR_sgetmask           199 /* Linux Specific                              */
+#define __NR_ssetmask           200 /* Linux Specific                              */
+#define __NR_sigsuspend         201 /* Linux Specific                              */
+#define __NR_oldlstat           202 /* Linux Specific                              */
+#define __NR_uselib             203 /* Linux Specific                              */
+#define __NR_readdir            204 /* Linux Specific                              */
+#define __NR_ioperm             205 /* Linux Specific - i386 specific, unused      */
+#define __NR_socketcall         206 /* Linux Specific                              */
+#define __NR_syslog             207 /* Linux Specific                              */
+#define __NR_olduname           208 /* Linux Specific                              */
+#define __NR_iopl               209 /* Linux Specific - i386 specific, unused      */
+#define __NR_idle               210 /* Linux Specific                              */
+#define __NR_vm86               211 /* Linux Specific - i386 specific, unused      */
+#define __NR_waitpid            212 /* Linux Specific                              */
+#define __NR_swapoff            213 /* Linux Specific                              */
+#define __NR_sysinfo            214 /* Linux Specific                              */
+#define __NR_ipc                215 /* Linux Specific                              */
+#define __NR_sigreturn          216 /* Linux Specific                              */
+#define __NR_clone              217 /* Linux Specific                              */
+#define __NR_modify_ldt         218 /* Linux Specific - i386 specific, unused      */
+#define __NR_adjtimex           219 /* Linux Specific                              */
+#define __NR_sigprocmask        220 /* Linux Specific                              */
+#define __NR_create_module      221 /* Linux Specific                              */
+#define __NR_delete_module      222 /* Linux Specific                              */
+#define __NR_get_kernel_syms    223 /* Linux Specific                              */
+#define __NR_getpgid            224 /* Linux Specific                              */
+#define __NR_bdflush            225 /* Linux Specific                              */
+#define __NR_sysfs              226 /* Linux Specific                              */
+#define __NR_afs_syscall        227 /* Linux Specific                              */
+#define __NR_setfsuid           228 /* Linux Specific                              */
+#define __NR_setfsgid           229 /* Linux Specific                              */
+#define __NR__newselect         230 /* Linux Specific                              */
+#define __NR_time               231 /* Linux Specific                              */
+#define __NR_oldstat            232 /* Linux Specific                              */
+#define __NR_stime              233 /* Linux Specific                              */
+#define __NR_oldfstat           234 /* Linux Specific                              */
+#define __NR_phys               235 /* Linux Specific                              */
+#define __NR__llseek            236 /* Linux Specific                              */
+#define __NR_mlock              237
+#define __NR_munlock            238
+#define __NR_mlockall           239
+#define __NR_munlockall         240
+#define __NR_sched_setparam     241
+#define __NR_sched_getparam     242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield        245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval  248
+#define __NR_nanosleep          249
+#define __NR_mremap             250
+#define __NR__sysctl            251
+#define __NR_getsid             252
+#define __NR_fdatasync          253
+#define __NR_nfsctl             254
+#define __NR_aplib              255
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res)\
+                     : "0" (__NR_##name) \
+                     : "g1", "o0"); \
+if (__res >= 0) \
+    return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+                     "or %%g0, %1, %%o0\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res), "=r" ((long)(arg1)) \
+                     : "0" (__NR_##name),"1" ((long)(arg1)) \
+                     : "g1", "o0"); \
+if (__res >= 0) \
+       return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+                     "or %%g0, %1, %%o0\n\t" \
+                     "or %%g0, %2, %%o1\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)) \
+                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)) \
+                     : "g1", "o0", "o1"); \
+if (__res >= 0) \
+       return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+                     "or %%g0, %1, %%o0\n\t" \
+                     "or %%g0, %2, %%o1\n\t" \
+                     "or %%g0, %3, %%o2\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+                       "=r" ((long)(arg3)) \
+                     : "0" (__NR_##name), "1" ((long)(arg1)), "2" ((long)(arg2)), \
+                       "3" ((long)(arg3)) \
+                     : "g1", "o0", "o1", "o2"); \
+if (__res>=0) \
+       return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ __volatile__ ("or %%g0, %0, %%g1\n\t" \
+                     "or %%g0, %1, %%o0\n\t" \
+                     "or %%g0, %2, %%o1\n\t" \
+                     "or %%g0, %3, %%o2\n\t" \
+                     "or %%g0, %4, %%o3\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0,%%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res), "=r" ((long)(arg1)), "=r" ((long)(arg2)), \
+                       "=r" ((long)(arg3)), "=r" ((long)(arg4)) \
+                     : "0" (__NR_##name),"1" ((long)(arg1)),"2" ((long)(arg2)), \
+                       "3" ((long)(arg3)),"4" ((long)(arg4)) \
+                     : "g1", "o0", "o1", "o2", "o3"); \
+if (__res>=0) \
+       return (type) __res; \
+errno = -__res; \
+return -1; \
+} 
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+         type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+      long __res; \
+\
+__asm__ __volatile__ ("or %%g0, %1, %%o0\n\t" \
+                     "or %%g0, %2, %%o1\n\t" \
+                     "or %%g0, %3, %%o2\n\t" \
+                     "or %%g0, %4, %%o3\n\t" \
+                     "or %%g0, %5, %%o4\n\t" \
+                     "or %%g0, %6, %%g1\n\t" \
+                     "t 0x10\n\t" \
+                     "bcc 1f\n\t" \
+                     "or %%g0, %%o0, %0\n\t" \
+                     "sub %%g0, %%o0, %0\n\t" \
+                     "1:\n\t" \
+                     : "=r" (__res) \
+                     : "r" ((long)(arg1)),"r" ((long)(arg2)), \
+                       "r" ((long)(arg3)),"r" ((long)(arg4)),"r" ((long)(arg5)), \
+                       "i" (__NR_##name)  \
+                     : "g1", "o0", "o1", "o2", "o3", "o4"); \
+if (__res>=0) \
+       return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static __inline__ _syscall0(int,idle)
+static __inline__ _syscall0(int,fork)
+static __inline__ _syscall2(int,clone,unsigned long,flags,char *,ksp)
+static __inline__ _syscall0(int,pause)
+static __inline__ _syscall0(int,setup)
+static __inline__ _syscall0(int,sync)
+static __inline__ _syscall0(pid_t,setsid)
+static __inline__ _syscall3(int,write,int,fd,__const__ char *,buf,off_t,count)
+static __inline__ _syscall1(int,dup,int,fd)
+static __inline__ _syscall3(int,execve,__const__ char *,file,char **,argv,char **,envp)
+static __inline__ _syscall3(int,open,__const__ char *,file,int,flag,int,mode)
+static __inline__ _syscall1(int,close,int,fd)
+static __inline__ _syscall1(int,_exit,int,exitcode)
+static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+static __inline__ pid_t wait(int * wait_stat)
+{
+       return waitpid(-1,wait_stat,0);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+static __inline__ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+       long retval;
+
+       __asm__ __volatile("mov %4, %%g2\n\t"    /* Set aside fn ptr... */
+                          "mov %5, %%g3\n\t"    /* and arg. */
+                          "mov %1, %%g1\n\t"
+                          "mov %2, %%o0\n\t"    /* Clone flags. */
+                          "mov 0, %%o1\n\t"     /* usp arg == 0 */
+                          "t 0x10\n\t"          /* Linux/Sparc clone(). */
+                          "cmp %%o1, 0\n\t"
+                          "be 1f\n\t"           /* The parent, just return. */
+                          " nop\n\t"            /* Delay slot. */
+                          "jmpl %%g2, %%o7\n\t" /* Call the function. */
+                          " mov %%g3, %%o0\n\t" /* Get back the arg in delay. */
+                          "mov %3, %%g1\n\t"
+                          "t 0x10\n\t"          /* Linux/Sparc exit(). */
+                          /* Notreached by child. */
+                          "1: mov %%o0, %0\n\t" :
+                          "=r" (retval) :
+                          "i" (__NR_clone), "r" (flags | CLONE_VM),
+                          "i" (__NR_exit),  "r" (fn), "r" (arg) :
+                          "g1", "g2", "g3", "o0", "o1", "memory");
+       return retval;
+}
+
+#endif /* __KERNEL_SYSCALLS__ */
+
+/* sysconf options, for SunOS compatibility */
+#define   _SC_ARG_MAX             1
+#define   _SC_CHILD_MAX           2
+#define   _SC_CLK_TCK             3
+#define   _SC_NGROUPS_MAX         4
+#define   _SC_OPEN_MAX            5
+#define   _SC_JOB_CONTROL         6
+#define   _SC_SAVED_IDS           7
+#define   _SC_VERSION             8
+
+#endif /* _SPARC64_UNISTD_H */
diff --git a/include/asm-sparc64/upa.h b/include/asm-sparc64/upa.h
new file mode 100644 (file)
index 0000000..83572fb
--- /dev/null
@@ -0,0 +1,24 @@
+/* $Id */
+#ifndef _SPARC64_UPA_H
+#define _SPARC64_UPA_H
+
+/* UPA level registers and defines. */
+
+/* UPA Config Register */
+#define UPA_CONFIG_RESV                0xffffffffc0000000 /* Reserved.                    */
+#define UPA_CONFIG_PCON                0x000000003fc00000 /* Depth of various sys queues. */
+#define UPA_CONFIG_MID         0x00000000003e0000 /* Module ID.                   */
+#define UPA_CONFIG_PCAP                0x000000000001ffff /* Port Capabilities.           */
+
+/* UPA Port ID Register */
+#define UPA_PORTID_FNP         0xff00000000000000 /* Hardcoded to 0xfc on ultra.  */
+#define UPA_PORTID_RESV                0x00fffff800000000 /* Reserved.                    */
+#define UPA_PORTID_ECCVALID     0x0000000400000000 /* Zero if mod can generate ECC */
+#define UPA_PORTID_ONEREAD      0x0000000200000000 /* Set if mod generates P_RASB  */
+#define UPA_PORTID_PINTRDQ      0x0000000180000000 /* # outstanding P_INT_REQ's    */
+#define UPA_PORTID_PREQDQ       0x000000007e000000 /* slave-wr's to mod supported  */
+#define UPA_PORTID_PREQRD       0x0000000001e00000 /* # incoming P_REQ's supported */
+#define UPA_PORTID_UPACAP       0x00000000001f0000 /* UPA capabilities of mod      */
+#define UPA_PORTID_ID           0x000000000000ffff /* Module Indentification bits  */
+
+#endif /* !(_SPARC64_UPA_H) */
diff --git a/include/asm-sparc64/user.h b/include/asm-sparc64/user.h
new file mode 100644 (file)
index 0000000..fce4e85
--- /dev/null
@@ -0,0 +1,60 @@
+/* $Id: user.h,v 1.1 1996/12/26 14:22:44 davem Exp $
+ * asm-sparc64/user.h: Core file definitions for the Sparc.
+ *
+ * Keep in sync with reg.h.  Actually, we could get rid of this
+ * one, since we won't a.out core dump that much anyways - miguel.
+ * Copyright (C) 1995 (davem@caip.rutgers.edu)
+ */
+#ifndef _SPARC64_USER_H
+#define _SPARC64_USER_H
+
+#include <asm/a.out.h>
+struct sunos_regs {
+       unsigned int psr, pc, npc, y;
+       unsigned int regs[15];
+};
+
+struct sunos_fpqueue {
+       unsigned int *addr;
+       unsigned int inst;
+};
+
+struct sunos_fp {
+       union {
+               unsigned int regs[32];
+               double reg_dbls[16];
+       } fregs;
+       unsigned int fsr;
+       unsigned int flags;
+       unsigned int extra;
+       unsigned int fpq_count;
+       struct sunos_fpqueue fpq[16];
+};
+
+struct sunos_fpu {
+       struct sunos_fp fpstatus;
+};
+
+/* The SunOS core file header layout. */
+struct user {
+       unsigned int magic;
+       unsigned int len;
+       struct sunos_regs regs;
+       struct exec uexec;
+       int           signal;
+       size_t        u_tsize; /* all of these in bytes! */
+       size_t        u_dsize;
+       size_t        u_ssize;
+       char          u_comm[17];
+       struct sunos_fpu fpu;
+       unsigned int  sigcode;   /* Special sigcontext subcode, if any */
+};
+
+#define NBPG                   PAGE_SIZE /* XXX 4096 maybe? */
+#define UPAGES                 1
+#define HOST_TEXT_START_ADDR   (u.start_code)
+#define HOST_DATA_START_ADDR   (u.start_data)
+#define HOST_STACK_END_ADDR    (u.start_stack + u.u_ssize * NBPG)
+#define SUNOS_CORE_MAGIC       0x080456
+
+#endif /* !(_SPARC64_USER_H) */
diff --git a/include/asm-sparc64/vuid_event.h b/include/asm-sparc64/vuid_event.h
new file mode 100644 (file)
index 0000000..0c5977f
--- /dev/null
@@ -0,0 +1,42 @@
+/* SunOS Virtual User Input Device (VUID) compatibility */
+
+typedef struct firm_event {
+       unsigned short id;        /* tag for this event */
+       unsigned char  pair_type; /* unused by X11 */
+        unsigned char  pair;     /* unused by X11 */
+        int            value;    /* VKEY_UP, VKEY_DOWN or delta */
+
+       /* XXX Timeval could hose old 32-bit programs, investigate and fixme XXX */
+        struct timeval time;
+} Firm_event;
+
+enum {
+    FE_PAIR_NONE,
+    FE_PAIR_SET,
+    FE_PAIR_DELTA,
+    FE_PAIR_ABSOLUTE
+};
+
+/* VUID stream formats */
+#define VUID_NATIVE     0      /* Native byte stream format */
+#define VUID_FIRM_EVENT 1      /* send firm_event structures */
+
+/* ioctls */
+    /* Set input device byte stream format (any of VUID_{NATIVE,FIRM_EVENT}) */
+#define VUIDSFORMAT   _IOW('v', 1, int)
+    /* Retrieve input device byte stream format */
+#define VUIDGFORMAT   _IOR('v', 2, int)
+
+/* Possible tag values */
+/*    mouse buttons: */
+#define MS_LEFT         0x7f20
+#define MS_MIDDLE       0x7f21
+#define MS_RIGHT        0x7f22
+/*    motion: */
+#define LOC_X_DELTA     0x7f80
+#define LOC_Y_DELTA     0x7f81
+#define LOC_X_ABSOLUTE  0x7f82  /* X compat, unsupported */
+#define LOC_Y_ABSOLUTE  0x7f83  /* X compat, unsupported */
+
+#define VKEY_UP   0
+#define VKEY_DOWN 1
diff --git a/include/asm-sparc64/winmacro.h b/include/asm-sparc64/winmacro.h
new file mode 100644 (file)
index 0000000..bdfca06
--- /dev/null
@@ -0,0 +1,66 @@
+/* $Id: winmacro.h,v 1.1 1996/12/26 13:25:20 davem Exp $
+ * winmacro.h: Window loading-unloading macros for Sparc/V9.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _SPARC64_WINMACRO_H
+#define _SPARC64_WINMACRO_H
+
+#define STORE_V9_WINDOW_GENERIC_ASI(store_insn, base, offset, the_asi) \
+       store_insn      %l0, [base + offset + RW_V9_L0] the_asi;        \
+       store_insn      %l1, [base + offset + RW_V9_L1] the_asi;        \
+       store_insn      %l2, [base + offset + RW_V9_L2] the_asi;        \
+       store_insn      %l3, [base + offset + RW_V9_L3] the_asi;        \
+       store_insn      %l4, [base + offset + RW_V9_L4] the_asi;        \
+       store_insn      %l5, [base + offset + RW_V9_L5] the_asi;        \
+       store_insn      %l6, [base + offset + RW_V9_L6] the_asi;        \
+       store_insn      %l7, [base + offset + RW_V9_L7] the_asi;        \
+       store_insn      %i0, [base + offset + RW_V9_I0] the_asi;        \
+       store_insn      %i1, [base + offset + RW_V9_I1] the_asi;        \
+       store_insn      %i2, [base + offset + RW_V9_I2] the_asi;        \
+       store_insn      %i3, [base + offset + RW_V9_I3] the_asi;        \
+       store_insn      %i4, [base + offset + RW_V9_I4] the_asi;        \
+       store_insn      %i5, [base + offset + RW_V9_I5] the_asi;        \
+       store_insn      %i6, [base + offset + RW_V9_I6] the_asi;        \
+       store_insn      %i7, [base + offset + RW_V9_I7] the_asi;
+
+#define STORE_V9_WINDOW_KERNEL(base)           \
+       stx     %l0, [base + RW_V9_L0];         \
+       stx     %l1, [base + RW_V9_L1];         \
+       stx     %l2, [base + RW_V9_L2];         \
+       stx     %l3, [base + RW_V9_L3];         \
+       stx     %l4, [base + RW_V9_L4];         \
+       stx     %l5, [base + RW_V9_L5];         \
+       stx     %l6, [base + RW_V9_L6];         \
+       stx     %l7, [base + RW_V9_L7];         \
+       stx     %i0, [base + RW_V9_I0];         \
+       stx     %i1, [base + RW_V9_I1];         \
+       stx     %i2, [base + RW_V9_I2];         \
+       stx     %i3, [base + RW_V9_I3];         \
+       stx     %i4, [base + RW_V9_I4];         \
+       stx     %i5, [base + RW_V9_I5];         \
+       stx     %i6, [base + RW_V9_I6];         \
+       stx     %i7, [base + RW_V9_I7];
+
+#define LOAD_V9_WINDOW_KERNEL(base)            \
+       ldx     [base + RW_V9_L0], %l0;         \
+       ldx     [base + RW_V9_L1], %l1;         \
+       ldx     [base + RW_V9_L2], %l2;         \
+       ldx     [base + RW_V9_L3], %l3;         \
+       ldx     [base + RW_V9_L4], %l4;         \
+       ldx     [base + RW_V9_L5], %l5;         \
+       ldx     [base + RW_V9_L6], %l6;         \
+       ldx     [base + RW_V9_L7], %l7;         \
+       ldx     [base + RW_V9_I0], %i0;         \
+       ldx     [base + RW_V9_I1], %i1;         \
+       ldx     [base + RW_V9_I2], %i2;         \
+       ldx     [base + RW_V9_I3], %i3;         \
+       ldx     [base + RW_V9_I4], %i4;         \
+       ldx     [base + RW_V9_I5], %i5;         \
+       ldx     [base + RW_V9_I6], %i6;         \
+       ldx     [base + RW_V9_I7], %i7;
+
+#define STORE_V9_WINDOW_ASI_REG(base)          \
+
+#endif /* !(_SPARC64_WINMACRO_H) */
index a9bbea22d87fd22dcba053d27142d53f3f5bdcd2..d7f46b1d8bb72b38ff84aa7cb726e86effd3bf92 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/fd.h>
 #include <linux/config.h>
 
+#include <asm/byteorder.h>
+
 #define MSDOS_ROOT_INO  1 /* == MINIX_ROOT_INO */
 #define SECTOR_SIZE     512 /* sector size (bytes) */
 #define SECTOR_BITS    9 /* log2(SECTOR_SIZE) */
  * BE = big-endian, c: W = word (16 bits), L = longword (32 bits)
  */
 
-#define CF_LE_W(v) (v)
-#define CF_LE_L(v) (v)
-#define CT_LE_W(v) (v)
-#define CT_LE_L(v) (v)
-
+#define CF_LE_W(v) le16_to_cpu(v)
+#define CF_LE_L(v) le32_to_cpu(v)
+#define CT_LE_W(v) cpu_to_le16(v)
+#define CT_LE_L(v) cpu_to_le32(v)
 
 struct msdos_boot_sector {
        __s8    ignored[3];     /* Boot strap short or near jump */
index 3d5286ec125eb7d0f7575e387184bc38c92ffcf7..fac308709b84c2b3678e13d46a5c27168089ec0a 100644 (file)
@@ -2,6 +2,7 @@
  *  ncp.h
  *
  *  Copyright (C) 1995 by Volker Lendecke
+ *  Modified for sparc by J.F. Chadima
  *
  */
 
@@ -92,16 +93,16 @@ struct ncp_filesearch_info {
 #define NCP_MAX_FILENAME 14
 
 /* these define the attribute byte as seen by NCP */
-#define aRONLY     (1L<<0)
-#define aHIDDEN    (1L<<1)
-#define aSYSTEM    (1L<<2)
-#define aEXECUTE   (1L<<3)
-#define aDIR       (1L<<4)
-#define aARCH      (1L<<5)
+#define aRONLY     (ntohl(0x01000000))
+#define aHIDDEN    (ntohl(0x02000000))
+#define aSYSTEM    (ntohl(0x04000000))
+#define aEXECUTE   (ntohl(0x08000000))
+#define aDIR       (ntohl(0x10000000))
+#define aARCH      (ntohl(0x20000000))
 
-#define AR_READ      (0x01)
-#define AR_WRITE     (0x02)
-#define AR_EXCLUSIVE (0x20)
+#define AR_READ      (ntohs(0x0100))
+#define AR_WRITE     (ntohs(0x0200))
+#define AR_EXCLUSIVE (ntohs(0x2000))
 
 #define NCP_FILE_ID_LEN 6
 struct ncp_file_info {
@@ -124,20 +125,20 @@ struct ncp_file_info {
 #define NW_NS_OS2     4
 
 /*  Defines for ReturnInformationMask */
-#define RIM_NAME             (0x0001L)
-#define RIM_SPACE_ALLOCATED   (0x0002L)
-#define RIM_ATTRIBUTES       (0x0004L)
-#define RIM_DATA_SIZE        (0x0008L)
-#define RIM_TOTAL_SIZE       (0x0010L)
-#define RIM_EXT_ATTR_INFO     (0x0020L)
-#define RIM_ARCHIVE          (0x0040L)
-#define RIM_MODIFY           (0x0080L)
-#define RIM_CREATION         (0x0100L)
-#define RIM_OWNING_NAMESPACE  (0x0200L)
-#define RIM_DIRECTORY        (0x0400L)
-#define RIM_RIGHTS           (0x0800L)
-#define RIM_ALL              (0x0FFFL)
-#define RIM_COMPRESSED_INFO   (0x80000000L)
+#define RIM_NAME             (ntohl(0x01000000L))
+#define RIM_SPACE_ALLOCATED   (ntohl(0x02000000L))
+#define RIM_ATTRIBUTES       (ntohl(0x04000000L))
+#define RIM_DATA_SIZE        (ntohl(0x08000000L))
+#define RIM_TOTAL_SIZE       (ntohl(0x10000000L))
+#define RIM_EXT_ATTR_INFO     (ntohl(0x20000000L))
+#define RIM_ARCHIVE          (ntohl(0x40000000L))
+#define RIM_MODIFY           (ntohl(0x80000000L))
+#define RIM_CREATION         (ntohl(0x00010000L))
+#define RIM_OWNING_NAMESPACE  (ntohl(0x00020000L))
+#define RIM_DIRECTORY        (ntohl(0x00040000L))
+#define RIM_RIGHTS           (ntohl(0x00080000L))
+#define RIM_ALL              (ntohl(0xFF0F0000L))
+#define RIM_COMPRESSED_INFO   (ntohl(0x00000080L))
 
 /* open/create modes */
 #define OC_MODE_OPEN     0x01
@@ -194,19 +195,19 @@ struct nw_info_struct
 };
 
 /* modify mask - use with MODIFY_DOS_INFO structure */
-#define DM_ATTRIBUTES            (0x0002L)
-#define DM_CREATE_DATE           (0x0004L)
-#define DM_CREATE_TIME           (0x0008L)
-#define DM_CREATOR_ID            (0x0010L)
-#define DM_ARCHIVE_DATE          (0x0020L)
-#define DM_ARCHIVE_TIME          (0x0040L)
-#define DM_ARCHIVER_ID           (0x0080L)
-#define DM_MODIFY_DATE           (0x0100L)
-#define DM_MODIFY_TIME           (0x0200L)
-#define DM_MODIFIER_ID           (0x0400L)
-#define DM_LAST_ACCESS_DATE      (0x0800L)
-#define DM_INHERITED_RIGHTS_MASK  (0x1000L)
-#define DM_MAXIMUM_SPACE         (0x2000L)
+#define DM_ATTRIBUTES            (ntohl(0x02000000L))
+#define DM_CREATE_DATE           (ntohl(0x04000000L))
+#define DM_CREATE_TIME           (ntohl(0x08000000L))
+#define DM_CREATOR_ID            (ntohl(0x10000000L))
+#define DM_ARCHIVE_DATE          (ntohl(0x20000000L))
+#define DM_ARCHIVE_TIME          (ntohl(0x40000000L))
+#define DM_ARCHIVER_ID           (ntohl(0x80000000L))
+#define DM_MODIFY_DATE           (ntohl(0x00010000L))
+#define DM_MODIFY_TIME           (ntohl(0x00020000L))
+#define DM_MODIFIER_ID           (ntohl(0x00040000L))
+#define DM_LAST_ACCESS_DATE      (ntohl(0x00080000L))
+#define DM_INHERITED_RIGHTS_MASK  (ntohl(0x00100000L))
+#define DM_MAXIMUM_SPACE         (ntohl(0x00200000L))
 
 struct nw_modify_dos_info
 {
index 2d0ea9c2dbfbc90b6b6df69d3876080722e9b8ba..28d32372cad783d84346f664ad6d43e45debe639 100644 (file)
@@ -317,12 +317,9 @@ extern struct   mm_struct init_mm;
 extern struct task_struct init_task;
 extern struct task_struct *task[NR_TASKS];
 extern struct task_struct *last_task_used_math;
-extern struct task_struct *current_set[NR_CPUS];
-/*
- *     On a single processor system this comes out as current_set[0] when cpp
- *     has finished with it, which gcc will optimise away.
- */
-#define current (current_set[smp_processor_id()])      /* Current on this processor */
+
+#include <asm/current.h>
+
 extern unsigned long volatile jiffies;
 extern unsigned long itimer_ticks;
 extern unsigned long itimer_next;
index cdfdca72ef5c515da4286bb7114f67bf9828d748..beaafffd3cfb57cd8d88ec78f7c23391c2e3f4ba 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __LINUX_UIO_H
 #define __LINUX_UIO_H
 
+#include <linux/types.h>
+
 /*
  *     Berkeley style UIO structures   -       Alan Cox 1994.
  *
index 6353a7743461e4159d6f49553de1c7f651c903d1..13a09a8765c767b18142b0c3ddd25214407cc49c 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 
 extern void sem_exit (void);
 extern void acct_process (long exitcode);
@@ -475,6 +476,7 @@ static inline void __exit_mm(struct task_struct * tsk)
        if (mm != &init_mm) {
                flush_cache_mm(mm);
                flush_tlb_mm(mm);
+               destroy_context(mm);
                tsk->mm = &init_mm;
                tsk->swappable = 0;
                SET_PAGE_DIR(tsk, swapper_pg_dir);
index 8deb8045536be517952656344412f3874a8aec18..5a013983f6579d6703e49b5c727d93b31f16ac86 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
+#include <asm/mmu_context.h>
 #include <asm/uaccess.h>
 
 int nr_tasks=1;
@@ -118,6 +119,7 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
                if (!mm)
                        return -1;
                *mm = *current->mm;
+               init_new_context(mm);
                mm->count = 1;
                mm->def_flags = 0;
                tsk->mm = mm;
@@ -132,8 +134,8 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
                }
                return 0;
        }
-       SET_PAGE_DIR(tsk, current->mm->pgd);
        current->mm->count++;
+       SET_PAGE_DIR(tsk, current->mm->pgd);
        return 0;
 }
 
index 286ed4f4cd53ce53f02f6ce9da572c7cc2149fb2..387a11bc951f330708be7ca437aacb5d8e3a7ca9 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -310,7 +310,7 @@ unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
        if (len > TASK_SIZE)
                return 0;
        if (!addr)
-               addr = TASK_SIZE / 3;
+               addr = TASK_UNMAPPED_BASE;
        addr = PAGE_ALIGN(addr);
 
        for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {