]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.36pre1 2.1.36pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:07 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:07 +0000 (15:13 -0500)
280 files changed:
Documentation/Changes
Documentation/Configure.help
Documentation/parport.txt
Makefile
arch/alpha/kernel/osf_sys.c
arch/alpha/kernel/process.c
arch/alpha/kernel/signal.c
arch/i386/Makefile
arch/i386/boot/Makefile
arch/i386/kernel/bios32.c
arch/i386/kernel/i386_ksyms.c
arch/i386/kernel/irq.c
arch/i386/kernel/irq.h
arch/i386/kernel/ptrace.c
arch/i386/kernel/signal.c
arch/i386/kernel/smp.c
arch/i386/kernel/time.c
arch/i386/mm/init.c
arch/m68k/Makefile
arch/m68k/amiga/Makefile
arch/m68k/amiga/amifb.c
arch/m68k/amiga/amiga_ksyms.c
arch/m68k/amiga/amiints.c
arch/m68k/amiga/cia.c
arch/m68k/amiga/config.c
arch/m68k/amiga/cyberfb.c
arch/m68k/amiga/zorro.c
arch/m68k/atari/atafb.c
arch/m68k/atari/ataints.c
arch/m68k/atari/atakeyb.c
arch/m68k/atari/atari_ksyms.c
arch/m68k/atari/config.c
arch/m68k/atari/joystick.c
arch/m68k/boot/Makefile
arch/m68k/boot/amiga/bootstrap.c
arch/m68k/boot/amiga/bootstrap.h
arch/m68k/boot/amiga/linuxboot.c
arch/m68k/boot/amiga/linuxboot.h
arch/m68k/boot/atari/bootp.c
arch/m68k/boot/atari/bootp.h
arch/m68k/boot/atari/bootstrap.c
arch/m68k/config.in
arch/m68k/console/fbcon.c
arch/m68k/console/txtcon.c
arch/m68k/defconfig
arch/m68k/fpsp040/skeleton.S
arch/m68k/ifpsp060/os.S
arch/m68k/kernel/Makefile
arch/m68k/kernel/console.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/head.S
arch/m68k/kernel/ints.c
arch/m68k/kernel/m68k_ksyms.c
arch/m68k/kernel/process.c
arch/m68k/kernel/ptrace.c
arch/m68k/kernel/setup.c
arch/m68k/kernel/signal.c
arch/m68k/kernel/sys_m68k.c
arch/m68k/kernel/traps.c
arch/m68k/lib/checksum.c
arch/m68k/lib/semaphore.S
arch/m68k/mm/extable.c
arch/m68k/mm/fault.c
arch/m68k/mm/init.c
arch/m68k/mm/memory.c
arch/sparc/defconfig
arch/sparc/kernel/entry.S
arch/sparc/kernel/head.S
arch/sparc/kernel/irq.c
arch/sparc/kernel/ptrace.c
arch/sparc/kernel/signal.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4c_irq.c
arch/sparc/kernel/sun4m_irq.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/kernel/sys_sunos.c
arch/sparc/kernel/tick14.c
arch/sparc/kernel/time.c
arch/sparc/lib/locks.S
arch/sparc64/Makefile
arch/sparc64/defconfig
arch/sparc64/kernel/etrap.S
arch/sparc64/kernel/idprom.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/signal32.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sparcelf32.c
arch/sparc64/kernel/sys_sparc32.c
arch/sparc64/kernel/systbls.S
arch/sparc64/mm/init.c
drivers/Makefile
drivers/block/acsi.c
drivers/block/amiflop.c
drivers/block/ataflop.c
drivers/block/floppy.c
drivers/block/genhd.c
drivers/block/ll_rw_blk.c
drivers/block/rd.c
drivers/block/z2ram.c
drivers/char/Makefile
drivers/char/amigamouse.c
drivers/char/atarimouse.c
drivers/char/lp.c
drivers/char/lp_m68k.c
drivers/char/mem.c
drivers/char/vt.c
drivers/isdn/sc/init.c
drivers/net/Config.in
drivers/net/Space.c
drivers/net/a2065.c
drivers/net/ariadne.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/eexpress.c
drivers/net/hydra.c
drivers/net/myri_code.h
drivers/net/myri_sbus.c
drivers/net/plip.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/wavelan.c
drivers/net/wavelan.p.h
drivers/pnp/BUGS-parport
drivers/pnp/Makefile
drivers/pnp/TODO-parport
drivers/pnp/parport_init.c
drivers/pnp/parport_procfs.c
drivers/pnp/parport_share.c
drivers/sbus/char/Config.in
drivers/sbus/char/Makefile
drivers/sbus/char/bpp.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/sunserial.c
drivers/sbus/char/tcx.c
drivers/sbus/char/weitek.c
drivers/sbus/sbus.c
drivers/scsi/a2091.c
drivers/scsi/a3000.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/atari_scsi.c
drivers/scsi/esp.c
drivers/scsi/gvp11.c
drivers/scsi/ncr53c8xx.c
drivers/scsi/ncr53c8xx.h
drivers/scsi/ppa.c
drivers/scsi/qlogicpti.c
drivers/scsi/qlogicpti_asm.c
drivers/scsi/wd33c93.c
drivers/scsi/wd33c93.h
fs/affs/inode.c
fs/autofs/init.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_em86.c
fs/binfmt_java.c
fs/binfmt_script.c
fs/exec.c
fs/ext2/super.c
fs/hpfs/hpfs_fs.c
fs/isofs/dir.c
fs/isofs/inode.c
fs/isofs/namei.c
fs/lockd/host.c
fs/lockd/svc.c
fs/minix/inode.c
fs/msdos/msdosfs_syms.c
fs/ncpfs/inode.c
fs/nfs/dir.c
fs/nfs/mount_clnt.c
fs/nfs/nfs2xdr.c
fs/nfsd/vfs.c
fs/proc/root.c
fs/romfs/inode.c
fs/smbfs/inode.c
fs/sysv/inode.c
fs/ufs/ufs_super.c
fs/umsdos/inode.c
fs/vfat/namei.c
include/asm-alpha/atomic.h
include/asm-alpha/semaphore.h
include/asm-alpha/smp_lock.h
include/asm-alpha/spinlock.h
include/asm-i386/atomic.h
include/asm-i386/init.h
include/asm-i386/semaphore.h
include/asm-i386/smp.h
include/asm-i386/smp_lock.h
include/asm-i386/spinlock.h
include/asm-m68k/amigaints.h
include/asm-m68k/atarihw.h
include/asm-m68k/atariints.h
include/asm-m68k/atomic.h
include/asm-m68k/bootinfo.h
include/asm-m68k/byteorder.h
include/asm-m68k/cache.h
include/asm-m68k/checksum.h
include/asm-m68k/ide.h
include/asm-m68k/ioctl.h
include/asm-m68k/irq.h
include/asm-m68k/machdep.h
include/asm-m68k/page.h
include/asm-m68k/pgtable.h
include/asm-m68k/processor.h
include/asm-m68k/scatterlist.h
include/asm-m68k/semaphore.h
include/asm-m68k/serial.h
include/asm-m68k/setup.h
include/asm-m68k/sigcontext.h
include/asm-m68k/system.h
include/asm-m68k/termbits.h
include/asm-m68k/termios.h
include/asm-m68k/uaccess.h
include/asm-m68k/unistd.h
include/asm-m68k/user.h
include/asm-ppc/atomic.h
include/asm-ppc/semaphore.h
include/asm-sparc/atomic.h
include/asm-sparc/errno.h
include/asm-sparc/fbio.h
include/asm-sparc/init.h
include/asm-sparc/irq.h
include/asm-sparc/pgtable.h
include/asm-sparc/semaphore.h
include/asm-sparc/smp.h
include/asm-sparc/smp_lock.h
include/asm-sparc/spinlock.h
include/asm-sparc/system.h
include/asm-sparc64/atomic.h
include/asm-sparc64/errno.h
include/asm-sparc64/fbio.h
include/asm-sparc64/fcntl.h
include/asm-sparc64/init.h
include/asm-sparc64/ipc.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/posix_types.h
include/asm-sparc64/processor.h
include/asm-sparc64/semaphore.h
include/asm-sparc64/smp.h
include/asm-sparc64/smp_lock.h
include/asm-sparc64/stat.h
include/asm-sparc64/statfs.h
include/linux/init.h
include/linux/parport.h
include/linux/sched.h
include/linux/wireless.h
include/net/sock.h
init/main.c
kernel/exit.c
kernel/fork.c
kernel/ksyms.c
kernel/sched.c
kernel/signal.c
kernel/sys.c
mm/swap.c
net/core/dev.c
net/core/dst.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/arp.c
net/ipv4/fib.c
net/ipv4/ip_fragment.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv6/addrconf.c
net/ipv6/ipv6_sockglue.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/unix/af_unix.c

index 70c7854449e092ad5231d653751ff4941fbf5fd7..3b1fed283bd034ced76abe19842dc013f74bf9c7 100644 (file)
@@ -29,7 +29,7 @@ English-language HTML version.
    Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
 needs.
 
-Last updated: April 15, 1997.
+Last updated: April 17, 1997.
 Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
 
 Current Minimal Requirements
@@ -184,7 +184,7 @@ requires that you be logged in as root.
 
 Binutils: ld -v
 Gnu C: gcc -v or gcc --version
-Kbd: loadkeys -h
+Kbd: dumpkeys -h
 Ld.so: ldd -v
 Libc: ls -l /lib/libc.so.*
 Libc++: ls -l /usr/lib/libg++.so.*
@@ -249,7 +249,7 @@ Modules utilities
 
 The 2.1.34 release:
 ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.34.tar.gz
-ftp://ftp.kernel.org/pub/linux/kernel/modutils-2.1.34.tar.gz
+ftp://ftp.kernel.org/pub/linux/kernel/v2.1/modutils-2.1.34.tar.gz
 
 Procps utilities
 ================
index a024a3c81f810b0d7d6d33cdc772cc80a41928cd..f77cb06759a3aebae6ca7f590a665207f7cd209c 100644 (file)
@@ -3063,22 +3063,20 @@ CONFIG_PT
   Documentation/networking/net-modules.txt. The module will be called
   pt.o.
 
-WaveLAN support
+AT&T WaveLAN & DEC RoamAbout DS support
 CONFIG_WAVELAN
-  These are cards for wireless ethernet-like networking. Supported are
-  AT&T GIS and NCR WaveLAN cards. If you want to use a card of this
-  type under Linux, say Y and read the Ethernet-HOWTO, available via
-  ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. Some
-  more specific information is contained in
-  drivers/net/README.wavelan. This driver is also available as a
-  module ( = code which can be inserted in and removed from the
-  running kernel whenever you want). The module will be called
-  wavelan.o. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. If you plan to use more
-  than one network card under linux, read the
-  Multiple-Ethernet-mini-HOWTO, available from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
+    The Lucent Wavelan (formerly NCR and AT&T ; or DEC RoamAbout DS)
+  is a Radio LAN (wireless ethernet-like) at 900 MHz and 2.4 GHz.
+    This driver support the ISA version of the Wavelan. A driver for
+  the pcmcia hardware is available in David Hinds's pcmcia package.
+    This driver is fairly stable and may be compiled as a module
+  (wavelan.o). It implements many nice feature and the Wireless
+  Extensions (you must get the Wireless tools from the net).
+    For documentation, refer to :
+      o the wavelan man page, wireless tools man pages
+      o wavelan.p.h and the source code
+      o Ethernet-HOWTO, Multiple-Ethernet-mini-HOWTO, Module-HOWTO
+      o More documentation to come when I will have the time :-)
 
 HP PCLAN+ (27247B and 27252A) support
 CONFIG_HPLAN_PLUS
index 6b3ba37ece019c1535f6a66bb57e9c6f3b58c596..17a659e55538fd669ac59d2826587890f6a38483 100644 (file)
@@ -47,9 +47,13 @@ regardless of base address.
 Also:
 
  * If you selected the device autoprobe at compile time, you can say
-`lp=auto' on the kernel command line, and lp will create devices only
-for those ports that seem to have printers attached.
+   `lp=auto' on the kernel command line, and lp will create devices
+   only for those ports that seem to have printers attached.
 
  * If you give PLIP the `timid' parameter, either with `plip=timid' on
-the command line, or with `insmod plip timid=1' when using modules, it
-will avoid any ports that seem to be in use by other devices.
+   the command line, or with `insmod plip timid=1' when using modules,
+   it will avoid any ports that seem to be in use by other devices.
+
+ * If your BIOS allows you to engage "ECP mode", you may find that
+   your port's IRQ can be autoprobed, without having to specify any 
+   parameters.
index d88d06be329af070b832121a42231ee8c491e290..73eba89ec1497f76ab2c020c9d77a21ae9768e70 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 35
+SUBLEVEL = 36
 
 ARCH := $(shell uname -m | sed s/i.86/i386/)
 
@@ -118,7 +118,8 @@ CORE_FILES  =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
 FILESYSTEMS    =fs/filesystems.a
 NETWORKS       =net/network.a
 DRIVERS                =drivers/block/block.a \
-                drivers/char/char.a
+                drivers/char/char.a \
+                drivers/pnp/pnp.a
 LIBS           =$(TOPDIR)/lib/lib.a
 SUBDIRS                =kernel drivers mm fs net ipc lib
 
@@ -144,10 +145,6 @@ ifdef CONFIG_PCI
 DRIVERS := $(DRIVERS) drivers/pci/pci.a
 endif
 
-ifdef CONFIG_PNP
-DRIVERS := $(DRIVERS) drivers/pnp/pnp.a
-endif
-
 ifdef CONFIG_SBUS
 DRIVERS := $(DRIVERS) drivers/sbus/sbus.a
 endif
index a5a9dc1c3c5b19d0d4b6f9c47c13a0bf83321081..e2f9bf4c972d7cf78722114ab86f72aa476b9333 100644 (file)
@@ -171,7 +171,7 @@ asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4,
        int prio;
 
        /*
-        * We don't need to aquire the kernel lock here, because
+        * We don't need to acquire the kernel lock here, because
         * all of these operations are local. sys_getpriority
         * will get the lock as required..
         */
@@ -193,7 +193,7 @@ asmlinkage unsigned long sys_madvise(void)
 }
 
 /*
- * No need to aquire the kernel lock, we're local..
+ * No need to acquire the kernel lock, we're local..
  */
 asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
                                     struct pt_regs regs)
@@ -218,7 +218,7 @@ asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int
 
        /* 
         * This isn't strictly "local" any more and we should actually
-        * aquire the kernel lock. The "p_opptr" pointer might change
+        * acquire the kernel lock. The "p_opptr" pointer might change
         * if the parent goes away (or due to ptrace). But any race
         * isn't actually going to matter, as if the parent happens
         * to change we can happily return either of the pids.
index f30afa5c96fdf1811ebe7e629f80261a74a5d448..2eb2d51b74772c164ade96b6fd45ffac84ace01c 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 /*
- * No need to aquire the kernel lock, we're entirely local..
+ * No need to acquire the kernel lock, we're entirely local..
  */
 asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
        unsigned long a3, unsigned long a4, unsigned long a5,
index b3fa9df839793c7cfa5f41550d9a6d27847aecfa..38b32b203cca4046629ec36962609981c52c4b05 100644 (file)
@@ -41,7 +41,7 @@ extern int ptrace_cancel_bpt (struct task_struct *child);
  * We change the range to -1 .. 1 in order to let gcc easily
  * use the conditional move instructions.
  *
- * Note that we don't need to aquire the kernel lock for SMP
+ * Note that we don't need to acquire the kernel lock for SMP
  * operation, as all of this is local to this thread.
  */
 asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask,
index 8bd6d89530a084bdd20ccedd6ac8c9918a45377b..c67b8671a6233b9f0b3599ef21fe3c2b95a20601 100644 (file)
@@ -21,7 +21,7 @@ LD=$(CROSS_COMPILE)ld -m elf_i386
 CPP=$(CC) -E
 OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 LDFLAGS=-e stext
-LINKFLAGS =-T arch/i386/vmlinux.lds $(LDFLAGS)
+LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
 
 CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce
 
index 83e4a19dec69da923c05143816e1f0dd60768379..c876022cdbfda5fb7abd5ccfbf990790738f0bfb 100644 (file)
@@ -40,8 +40,8 @@ zlilo: $(CONFIGURE) $(BOOTIMAGE)
        cp $(TOPDIR)/System.map $(INSTALL_PATH)/
        if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
-install: $(CONFIGURE) zImage
-       sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+install: $(CONFIGURE) $(BOOTIMAGE)
+       sh -x ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
 tools/build: tools/build.c
        $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include
index 58c08b189b8375bb68fd7bce7a36c6a469f491e2..e128000c38a58f359e4aa7667ee33e39df103027 100644 (file)
@@ -738,7 +738,7 @@ __initfunc(static struct pci_access *check_direct_pci(void))
     outb (0x00, 0xCFB);
     outb (0x00, 0xCF8);
     outb (0x00, 0xCFA);
-    if (inb (0xCF8) == 0x00 && inb (0xCFC) == 0x00) {
+    if (inb (0xCF8) == 0x00 && inb (0xCFB) == 0x00) {
        restore_flags(flags);
        printk("pcibios_init: Using configuration type 2\n");
        return &pci_direct_conf2;
index cbdfc763b82c822c558d6219546bcaf4779a81a9..8c16f02041f24d54495070add11028a0116e011b 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/mca.h>
 #include <linux/sched.h>
 #include <linux/in6.h>
+#include <linux/interrupt.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -31,7 +32,7 @@ EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL_NOVERS(__down_failed);
 EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
 EXPORT_SYMBOL_NOVERS(__up_wakeup);
-
+EXPORT_SYMBOL(__intel_bh_counter);
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy);
 
@@ -42,6 +43,13 @@ EXPORT_SYMBOL(kernel_flag);
 EXPORT_SYMBOL(active_kernel_processor);
 EXPORT_SYMBOL(smp_invalidate_needed);
 EXPORT_SYMBOL_NOVERS(__lock_kernel);
+
+/* Global SMP irq stuff */
+EXPORT_SYMBOL(global_irq_holder);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
 #endif
 
 #ifdef CONFIG_MCA
index 90f2ff8eab97eddcd92ba5479e204a07bd25f8a0..95a7b525fad7384fc8c4c266bcfbd031fa9c7321 100644 (file)
@@ -128,6 +128,11 @@ void enable_irq(unsigned int irq_nr)
  * other interrupts would have to avoid using the jiffies variable for delay
  * and interval timing operations to avoid hanging the system.
  */
+
+#if NR_IRQS != 16
+#error make irq stub building NR_IRQS dependent and remove me.
+#endif
+
 BUILD_TIMER_IRQ(FIRST,0,0x01)
 BUILD_IRQ(FIRST,1,0x02)
 BUILD_IRQ(FIRST,2,0x04)
@@ -231,7 +236,7 @@ int get_irq_list(char *buf)
        int i, len = 0;
        struct irqaction * action;
 
-       for (i = 0 ; i < 16 ; i++) {
+       for (i = 0 ; i < NR_IRQS ; i++) {
                action = irq_action[i];
                if (!action) 
                        continue;
@@ -734,15 +739,9 @@ __initfunc(void init_IRQ(void))
        outb_p(LATCH & 0xff , 0x40);    /* LSB */
        outb(LATCH >> 8 , 0x40);        /* MSB */
 
-       for (i = 0; i < 16 ; i++)
+       for (i = 0; i < NR_IRQS ; i++)
                set_intr_gate(0x20+i,bad_interrupt[i]);
 
-       /*
-        * This bit is a hack because we don't send timer messages to all
-        * processors yet. It has to be here .. it doesn't work if you put
-        * it down the bottom - assembler explodes 8)
-        */
-
 #ifdef __SMP__ 
        /*
         * NOTE! The local APIC isn't very good at handling
@@ -752,9 +751,20 @@ __initfunc(void init_IRQ(void))
         * want to spread these out a bit so that they don't
         * all fall in the same interrupt level
         */
+
+       /*
+        * The reschedule interrupt slowly changes it's functionality,
+        * while so far it was a kind of broadcasted timer interrupt,
+        * in the future it should become a CPU-to-CPU rescheduling IPI,
+        * driven by schedule() ?
+        *
+        * [ It has to be here .. it doesn't work if you put
+        *   it down the bottom - assembler explodes 8) ]
+        */
        /* IRQ '16' (trap 0x30) - IPI for rescheduling */
        set_intr_gate(0x20+i, reschedule_interrupt);
 
+
        /* IRQ '17' (trap 0x31) - IPI for invalidation */
        set_intr_gate(0x21+i, invalidate_interrupt);
 
index 365344a5924e639bfe69346ce3ce35422a9477ef..3a349f20a04c51aed5ba896fcbe895576f68dcdd 100644 (file)
@@ -266,4 +266,26 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
        UNBLK_##chip(mask) \
        "jmp ret_from_intr\n");
 
+/*
+ * x86 profiling function, SMP safe. We might want to do this in
+ * assembly totally?
+ */
+static inline void x86_do_profile (unsigned long eip)
+{
+       if (prof_buffer && current->pid) {
+               extern int _stext;
+               eip -= (unsigned long) &_stext;
+               eip >>= prof_shift;
+               if (eip < prof_len)
+                       atomic_inc((atomic_t *)&prof_buffer[eip]);
+               else
+               /*
+                * Dont ignore out-of-bounds EIP values silently,
+                * put them into the last histogram slot, so if
+                * present, they will show up as a sharp peak.
+                */
+                       atomic_inc((atomic_t *)&prof_buffer[prof_len-1]);
+       }
+}
+
 #endif
index fdb4088ffa41945d101e123d4e214b8a9c41c252..920d1bc1c400248cd6f723c74431e54f01083c38 100644 (file)
@@ -584,10 +584,9 @@ out:
 
 asmlinkage void syscall_trace(void)
 {
-       lock_kernel();
        if ((current->flags & (PF_PTRACED|PF_TRACESYS))
                        != (PF_PTRACED|PF_TRACESYS))
-               goto out;
+               return;
        current->exit_code = SIGTRAP;
        current->state = TASK_STOPPED;
        notify_parent(current);
@@ -597,9 +596,10 @@ asmlinkage void syscall_trace(void)
         * for normal use.  strace only continues with a signal if the
         * stopping signal is not SIGTRAP.  -brl
         */
-       if (current->exit_code)
+       if (current->exit_code) {
+               spin_lock_irq(&current->sigmask_lock);
                current->signal |= (1 << (current->exit_code - 1));
+               spin_unlock_irq(&current->sigmask_lock);
+       }
        current->exit_code = 0;
-out:
-       unlock_kernel();
 }
index 68fa03e1c32647861c2f136a36c1c43e02ce8189..970c8c5d7e947e46f783ad216b876cee06e891bf 100644 (file)
@@ -23,7 +23,9 @@
 
 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
-asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
+asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+                        int options, unsigned long *ru);
+
 asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
 
 /*
@@ -31,24 +33,21 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
  */
 asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
 {
+       struct pt_regs * regs = (struct pt_regs *) &restart;
        unsigned long mask;
-       struct pt_regs * regs;
-       int res = -EINTR;
 
-       lock_kernel();
-       regs = (struct pt_regs *) &restart;
+       spin_lock_irq(&current->sigmask_lock);
        mask = current->blocked;
        current->blocked = set & _BLOCKABLE;
+       spin_unlock_irq(&current->sigmask_lock);
+
        regs->eax = -EINTR;
        while (1) {
                current->state = TASK_INTERRUPTIBLE;
                schedule();
-               if (do_signal(mask,regs))
-                       goto out;
+               if (do_signal(mask, regs))
+                       return -EINTR;
        }
-out:
-       unlock_kernel();
-       return res;
 }
 
 static inline void restore_i387_hard(struct _fpstate *buf)
@@ -108,9 +107,7 @@ if (   (tmp & 0xfffc)     /* not a NULL selectors */ \
 __asm__("mov %w0,%%" #seg: :"r" (tmp)); }
        struct sigcontext * context;
        struct pt_regs * regs;
-       int res;
 
-       lock_kernel();
        regs = (struct pt_regs *) &__unused;
        context = (struct sigcontext *) regs->esp;
        if (verify_area(VERIFY_READ, context, sizeof(*context)))
@@ -136,11 +133,12 @@ __asm__("mov %w0,%%" #seg: :"r" (tmp)); }
                        goto badframe;
                restore_i387(buf);
        }
-       res = context->eax;
-       unlock_kernel();
-       return res;
+       return context->eax;
+
 badframe:
+       lock_kernel();
        do_exit(SIGSEGV);
+       unlock_kernel();
 }
 
 static inline struct _fpstate * save_i387_hard(struct _fpstate * buf)
@@ -194,7 +192,7 @@ static void setup_frame(struct sigaction * sa,
                frame = (unsigned long *) sa->sa_restorer;
        frame -= 64;
        if (!access_ok(VERIFY_WRITE,frame,64*4))
-               do_exit(SIGSEGV);
+               goto segv_and_exit;
 
 /* set up the "normal" stack seen by the signal handler (iBCS2) */
 #define __CODE ((unsigned long)(frame+24))
@@ -206,7 +204,7 @@ static void setup_frame(struct sigaction * sa,
        We use __put_user() here because the access_ok() call was already
        done earlier. */  
        if (__put_user(__CODE,frame))
-               do_exit(SIGSEGV);
+               goto segv_and_exit;
        if (current->exec_domain && current->exec_domain->signal_invmap)
                __put_user(current->exec_domain->signal_invmap[signr], frame+1);
        else
@@ -259,6 +257,12 @@ __asm__("mov %%" #seg",%w0":"=r" (tmp):"0" (tmp)); __put_user(tmp,mem);
                regs->xcs = USER_CS;
        }
        regs->eflags &= ~TF_MASK;
+       return;
+
+segv_and_exit:
+       lock_kernel();
+       do_exit(SIGSEGV);
+       unlock_kernel();
 }
 
 /*
@@ -292,8 +296,11 @@ static void handle_signal(unsigned long signr, struct sigaction *sa,
 
        if (sa->sa_flags & SA_ONESHOT)
                sa->sa_handler = NULL;
-       if (!(sa->sa_flags & SA_NOMASK))
+       if (!(sa->sa_flags & SA_NOMASK)) {
+               spin_lock_irq(&current->sigmask_lock);
                current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+               spin_unlock_irq(&current->sigmask_lock);
+       }
 }
 
 /*
@@ -310,9 +317,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
        unsigned long mask;
        unsigned long signr;
        struct sigaction * sa;
-       int res;
 
-       lock_kernel();
        mask = ~current->blocked;
        while ((signr = current->signal & mask)) {
                /*
@@ -322,6 +327,9 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                 */
                struct task_struct *t=current;
                __asm__("bsf %3,%1\n\t"
+#ifdef __SMP__
+                       "lock ; "
+#endif
                        "btrl %1,%0"
                        :"=m" (t->signal),"=r" (signr)
                        :"0" (t->signal), "1" (signr));
@@ -338,7 +346,9 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                        if (signr == SIGSTOP)
                                continue;
                        if (_S(signr) & current->blocked) {
+                               spin_lock_irq(&current->sigmask_lock);
                                current->signal |= _S(signr);
+                               spin_unlock_irq(&current->sigmask_lock);
                                continue;
                        }
                        sa = current->sig->action + signr - 1;
@@ -347,7 +357,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                        if (signr != SIGCHLD)
                                continue;
                        /* check for SIGCHLD: it's special */
-                       while (sys_waitpid(-1,NULL,WNOHANG) > 0)
+                       while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0)
                                /* nothing */;
                        continue;
                }
@@ -380,14 +390,19 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                                }
                                /* fall through */
                        default:
+                               spin_lock_irq(&current->sigmask_lock);
                                current->signal |= _S(signr & 0x7f);
+                               spin_unlock_irq(&current->sigmask_lock);
+
                                current->flags |= PF_SIGNALED;
+
+                               lock_kernel(); /* 8-( */
                                do_exit(signr);
+                               unlock_kernel();
                        }
                }
                handle_signal(signr, sa, oldmask, regs);
-               res = 1;
-               goto out;
+               return 1;
        }
 
        /* Did we come from a system call? */
@@ -400,8 +415,5 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
                        regs->eip -= 2;
                }
        }
-       res = 0;
-out:
-       unlock_kernel();
-       return res;
+       return 0;
 }
index c2f60ef0ecab6658b463408c84d7eb52e65e7ad0..a1590f500c98d8908c2a68b3874d803c714a7037 100644 (file)
@@ -49,6 +49,9 @@
 #include "irq.h"
 
 extern unsigned long start_kernel, _etext;
+extern void update_one_process( struct task_struct *p,
+                                unsigned long ticks, unsigned long user,
+                                unsigned long system);
 void setup_APIC_clock (void);
 
 /*
@@ -1306,37 +1309,6 @@ void smp_flush_tlb(void)
 /*     printk("SMID\n");*/
 }
 
-/*
- * Platform specific profiling function.
- * it builds a 'prof_shift' resolution EIP distribution histogram
- *
- * it's SMP safe.
- */
-
-static inline void x86_do_profile (unsigned long eip)
-{
-       if (prof_buffer && current->pid) {
-               extern int _stext;
-               eip -= (unsigned long) &_stext;
-               eip >>= prof_shift;
-               if (eip < prof_len)
-                       atomic_inc(&prof_buffer[eip]);
-               else
-               /*
-                * Dont ignore out-of-bounds EIP values silently,
-                * put them into the last histogram slot, so if
-                * present, they will show up as a sharp peak.
-                */
-                       atomic_inc(&prof_buffer[prof_len-1]);
-       }
-}
-
-unsigned int prof_multiplier[NR_CPUS];
-unsigned int prof_counter[NR_CPUS];
-
-extern void update_one_process(        struct task_struct *p,
-                               unsigned long ticks, unsigned long user,
-                               unsigned long system);
 /*
  * Local timer interrupt handler. It does both profiling and
  * process statistics/rescheduling.
@@ -1346,14 +1318,19 @@ extern void update_one_process( struct task_struct *p,
  * multiplier is 1 and it can be changed by writing a 4 bytes multiplier
  * value into /proc/profile.
  */
+
+unsigned int prof_multiplier[NR_CPUS];
+unsigned int prof_counter[NR_CPUS];
+
 static inline void smp_local_timer_interrupt(struct pt_regs * regs)
 {
        int cpu = smp_processor_id();
+
        /*
-        * Both the profiling function and the statistics
-        * counters are SMP safe. We leave the APIC irq
-        * unacked while updating the profiling info, thus
-        * we cannot be interrupted by the same APIC interrupt.
+        * The profiling function is SMP safe. (nothing can mess
+        * around with "current", and the profiling counters are
+        * updated with atomic operations). This is especially
+        * useful with a profiling multiplier != 1
         */
        if (!user_mode(regs))
                x86_do_profile (regs->eip);
@@ -1363,13 +1340,10 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
                struct task_struct * p = current;
 
                /*
-                * We mess around with thread statistics, but
-                * since we are the CPU running it, we dont
-                * have to lock it. We assume that switch_to()
-                * protects 'current' against local irqs via __cli.
-                *
-                * kernel statistics counters are updated via atomic
-                * operations.
+                * After doing the above, we need to make like
+                * a normal interrupt - otherwise timer interrupts
+                * ignore the global interrupt lock, which is the
+                * WrongThing (tm) to do.
                 */
 
                if (user_mode(regs))
@@ -1377,7 +1351,9 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
                else
                        system=1;
 
+               irq_enter(cpu, 0);
                if (p->pid) {
+
                        update_one_process(p, 1, user, system);
 
                        p->counter -= 1;
@@ -1386,25 +1362,21 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
                                need_resched = 1;
                        }
                        if (p->priority < DEF_PRIORITY)
-                               atomic_add (user, &kstat.cpu_nice);
+                               kstat.cpu_nice += user;
                        else
-                               atomic_add (user, &kstat.cpu_user);
+                               kstat.cpu_user += user;
 
-                       atomic_add (system, &kstat.cpu_system);
+                       kstat.cpu_system += system;
                
                } else {
 #ifdef __SMP_PROF__
                        if (test_bit(cpu,&smp_idle_map))
                                smp_idle_count[cpu]++;
 #endif
-                       /*
-                        * This is a hack until we have need_resched[]
-                        */
-                       if (read_smp_counter(&smp_process_available))
-                               need_resched=1;
                }
-
                prof_counter[cpu]=prof_multiplier[cpu];
+
+               irq_exit(cpu, 0);
        }
 
 #ifdef __SMP_PROF__
@@ -1432,8 +1404,6 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
  */
 void smp_apic_timer_interrupt(struct pt_regs * regs)
 {
-       int cpu = smp_processor_id();
-
        /*
         * NOTE! We'd better ACK the irq immediately,
         * because timer handling can be slow, and we
@@ -1442,15 +1412,7 @@ void smp_apic_timer_interrupt(struct pt_regs * regs)
         */
        ack_APIC_irq ();
 
-       /*
-        * After doing the above, we need to make like
-        * a normal interrupt - otherwise timer interrupts
-        * ignore the global interrupt lock, which is the
-        * WrongThing (tm) to do.
-        */
-       irq_enter(cpu, 0);
        smp_local_timer_interrupt(regs);
-       irq_exit(cpu, 0);
 }
 
 /*     
index 974e5c85b865c402767fd07dca45202008336584..6a7d6b461ef6d4164b5cbf78b77b4b10ed28cbe5 100644 (file)
 #include <linux/timex.h>
 #include <linux/config.h>
 
+/*
+ * for x86_do_profile()
+ */
+#include "irq.h"
+
 extern int setup_x86_irq(int, struct irqaction *);
 extern volatile unsigned long lost_ticks;
 
@@ -365,29 +370,6 @@ static int set_rtc_mmss(unsigned long nowtime)
 /* last time the cmos clock got updated */
 static long last_rtc_update = 0;
 
-
-/*
- * Move this to a header file - right now it shows
- * up both here and in smp.c
- */
-static inline void x86_do_profile (unsigned long eip)
-{
-       if (prof_buffer && current->pid) {
-               extern int _stext;
-               eip -= (unsigned long) &_stext;
-               eip >>= prof_shift;
-               if (eip < prof_len)
-                       atomic_inc(&prof_buffer[eip]);
-               else
-               /*
-                * Dont ignore out-of-bounds EIP values silently,
-                * put them into the last histogram slot, so if
-                * present, they will show up as a sharp peak.
-                */
-                       atomic_inc(&prof_buffer[prof_len-1]);
-       }
-}
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
index f9a925f44e30bc6162b96bc670c3c069793485ce..8ff11393a1fcefa96d0ccf88d0237914a24a176d 100644 (file)
@@ -322,6 +322,7 @@ void free_initmem(void)
                atomic_set(&mem_map[MAP_NR(addr)].count, 1);
                free_page(addr);
        }
+       printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
 void si_meminfo(struct sysinfo *val)
index 97d70e4b46b2ba88e49f00e765e1dc46c46294b3..939a80387cb29a2dd3c9ef91545fa6405cde97ef 100644 (file)
@@ -36,7 +36,7 @@ endif
 
 LINKFLAGS = -Ttext 0x1000
 
-CFLAGS := $(CFLAGS) -pipe
+CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce
 
 ifdef CONFIG_OPTIMIZE_040
 CFLAGS := $(CFLAGS) -m68040
@@ -46,40 +46,46 @@ ifdef CONFIG_OPTIMIZE_060
 CFLAGS := $(CFLAGS) -m68020-40
 endif
 
+ifdef CONFIG_KGDB
+# If configured for kgdb support, include debugging infos and keep the
+# frame pointer
+CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
+endif
+
 HEAD := arch/m68k/kernel/head.o
 
 SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/lib
-ARCHIVES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(ARCHIVES)
+CORE_FILES := arch/m68k/kernel/kernel.o arch/m68k/mm/mm.o $(CORE_FILES)
 LIBS += arch/m68k/lib/lib.a
 
 ifdef CONFIG_AMIGA
-ARCHIVES := $(ARCHIVES) arch/m68k/amiga/amiga.o
+CORE_FILES := $(CORE_FILES) arch/m68k/amiga/amiga.o
 SUBDIRS := $(SUBDIRS) arch/m68k/amiga
 endif
 
 ifdef CONFIG_ATARI
-ARCHIVES := $(ARCHIVES) arch/m68k/atari/atari.o
+CORE_FILES := $(CORE_FILES) arch/m68k/atari/atari.o
 SUBDIRS := $(SUBDIRS) arch/m68k/atari
 endif
 
 ifdef CONFIG_MAC
-ARCHIVES := $(ARCHIVES) arch/m68k/mac/mac.o
+CORE_FILES := $(CORE_FILES) arch/m68k/mac/mac.o
 SUBDIRS := $(SUBDIRS) arch/m68k/mac
 endif
 
 ifdef CONFIG_VT
 # add in console.a after {amiga,atari}.o that need it
-ARCHIVES := $(ARCHIVES) arch/m68k/console/console.a
+CORE_FILES := $(CORE_FILES) arch/m68k/console/console.a
 SUBDIRS := $(SUBDIRS) arch/m68k/console
 endif
 
 ifdef CONFIG_M68040
-ARCHIVES := $(ARCHIVES) arch/m68k/fpsp040/fpsp.o
+CORE_FILES := $(CORE_FILES) arch/m68k/fpsp040/fpsp.o
 SUBDIRS := $(SUBDIRS) arch/m68k/fpsp040
 endif
 
 ifdef CONFIG_M68060
-ARCHIVES := $(ARCHIVES) arch/m68k/ifpsp060/ifpsp.o
+CORE_FILES := $(CORE_FILES) arch/m68k/ifpsp060/ifpsp.o
 SUBDIRS := $(SUBDIRS) arch/m68k/ifpsp060
 endif
 
@@ -92,10 +98,24 @@ lilo:       vmlinux
        cp System.map $(INSTALL_PATH)/System.map
        if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
 
-bootstrap:
+zImage compressed: vmlinux.gz
+
+vmlinux.gz: vmlinux
+
+ifdef CONFIG_KGDB
+       cp vmlinux vmlinux.tmp
+       $(STRIP) vmlinux.tmp
+       gzip -9c vmlinux.tmp >vmlinux.gz
+       rm vmlinux.tmp
+else
+       gzip -9c vmlinux >vmlinux.gz
+endif
+
+bootstrap: dummy
        @$(MAKEBOOT) bootstrap
 
 archclean:
+       rm -f vmlinux.gz
        @$(MAKEBOOT) clean
 
 archdep:
index 7afc48fc2142aaa1b8c1fde377972f83bc7e6311..9716668ea0804096196085042a1901cd3d005d43 100644 (file)
@@ -16,4 +16,8 @@ ifdef CONFIG_FB_CYBER
 O_OBJS := $(O_OBJS) cyberfb.o
 endif
 
+ifdef CONFIG_FB_RETINAZ3
+O_OBJS := $(O_OBJS) retz3fb.o
+endif
+
 include $(TOPDIR)/Rules.make
index 3a6500047847747d69259eb8e855319e0a5601e3..c97609611eff521c87f4cc3f816107447fc89c33 100644 (file)
@@ -1242,6 +1242,7 @@ struct fb_info *amiga_fb_init(long *mem_start);
 static int amifbcon_switch(int con);
 static int amifbcon_updatevar(int con);
 static void amifbcon_blank(int blank);
+static int amifbcon_setcmap(struct fb_cmap *cmap, int con);
 
        /*
         * Internal routines
@@ -1315,7 +1316,15 @@ extern void Cyber_video_setup(char *options, int *ints);
 extern struct fb_info *Cyber_fb_init(long *mem_start);
 
 static int amifb_Cyber = 0;
-#endif /* CONFIG_FB_CYBER */
+#endif
+
+#ifdef CONFIG_FB_RETINAZ3                      /* RetinaZ3 */
+extern int retz3_probe(void);
+extern void retz3_video_setup(char *options, int *ints);
+extern struct fb_info *retz3_fb_init(long *mem_start);
+
+static int amifb_retz3 = 0;
+#endif
 
 #ifdef CONFIG_GSP_RESOLVER                     /* DMI Resolver */
 extern int resolver_probe(void);
@@ -1323,7 +1332,7 @@ extern void resolver_video_setup(char *options, int *ints);
 extern struct fb_info *resolver_fb_init(long *mem_start);
 
 static int amifb_resolver = 0;
-#endif /* CONFIG_GSP_RESOLVER */
+#endif
 
 static struct fb_ops amiga_fb_ops = {
        amiga_fb_get_fix, amiga_fb_get_var, amiga_fb_set_var, amiga_fb_get_cmap,
@@ -1347,7 +1356,15 @@ void amiga_video_setup(char *options, int *ints)
                        Cyber_video_setup(options, ints);
                        return;
                }
-#endif /* CONFIG_FB_CYBER */
+#endif
+#ifdef CONFIG_FB_RETINAZ3
+       if (options && *options)
+               if (!strncmp(options, "retz3", 5) && retz3_probe()) {
+                       amifb_retz3 = 1;
+                       retz3_video_setup(options, ints);
+                       return;
+               }
+#endif
 #ifdef CONFIG_GSP_RESOLVER
        if (options && *options)
                if (!strncmp(options, "resolver", 5) && resolver_probe()) {
@@ -1797,7 +1814,14 @@ struct fb_info *amiga_fb_init(long *mem_start)
 #ifdef CONFIG_FB_CYBER
        if (amifb_Cyber)
                return Cyber_fb_init(mem_start);
-#endif /* CONFIG_FB_CYBER */
+#endif
+#ifdef CONFIG_FB_RETINAZ3
+       if (amifb_retz3){
+               custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
+                               DMAF_BLITTER | DMAF_SPRITE;
+               return retz3_fb_init(mem_start);
+       }
+#endif
 #ifdef CONFIG_GSP_RESOLVER
        if (amifb_resolver){
                custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
@@ -1943,11 +1967,11 @@ default_chipset:
 
        check_default_mode();
 
-       if (request_irq(IRQ3, amifb_interrupt, IRQ_FLG_LOCK,
+       if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK,
                        "fb vertb handler", NULL))
                panic("Couldn't add vblank interrupt\n");
-       ami_intena_vals[IRQ_IDX(IRQ_AMIGA_VERTB)] = IF_COPER;
-       ami_intena_vals[IRQ_IDX(IRQ_AMIGA_COPPER)] = 0;
+       ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER;
+       ami_intena_vals[IRQ_AMIGA_COPPER] = 0;
        custom.intena = IF_VERTB;
        custom.intena = IF_SETCLR | IF_COPER;
 
@@ -1957,6 +1981,7 @@ default_chipset:
        fb_info.switch_con = &amifbcon_switch;
        fb_info.updatevar = &amifbcon_updatevar;
        fb_info.blank = &amifbcon_blank;
+       fb_info.setcmap = &amifbcon_setcmap;
 
        amiga_fb_set_var(&amiga_fb_predefined[0], 0);
 
@@ -1995,6 +2020,15 @@ static void amifbcon_blank(int blank)
        do_blank = blank ? blank : -1;
 }
 
+       /*
+        * Set the colormap
+        */
+
+static int amifbcon_setcmap(struct fb_cmap *cmap, int con)
+{
+       return(amiga_fb_set_cmap(cmap, 1, con));
+}
+
 /* ---------------------------- Generic routines ---------------------------- */
 
 static struct fb_cmap *get_default_colormap(int bpp)
@@ -2213,10 +2247,11 @@ static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 {
        u_short ints = custom.intreqr & custom.intenar;
        static struct irq_server server = {0, 0};
+       unsigned long flags;
 
        if (ints & IF_BLIT) {
                custom.intreq = IF_BLIT;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp);
+               amiga_do_irq(IRQ_AMIGA_BLIT, fp);
        }
 
        if (ints & IF_COPER) {
@@ -2240,8 +2275,11 @@ static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
                                ami_set_sprite();
                }
 
-               if (get_vbpos() < down2(currentpar.diwstrt_v - 4))
+               save_flags(flags);
+               cli();
+               if (get_vbpos() < down2(currentpar.diwstrt_v - 6))
                        custom.copjmp2 = 0;
+               restore_flags(flags);
 
                if (do_blank) {
                        ami_do_blank();
@@ -2252,7 +2290,7 @@ static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
                        ami_reinit_copper();
                        do_vmode_full = 0;
                }
-               amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server);
+               amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
        }
 
        if (ints & IF_VERTB) {
index 0c12976ebc20ae22b23546933107ef56d7b821d2..fe55f5f6930b82c2efe6939c5034a970a797192b 100644 (file)
@@ -1,6 +1,7 @@
-#include <linux/types.h>
+#include <linux/config.h>
 #include <linux/module.h>
-#include <asm/zorro.h>
+#include <linux/types.h>
+#include <linux/zorro.h>
 #include <asm/amigahw.h>
 
 extern volatile u_short amiga_audio_min_period;
index d9b061da5cacbce6954b9829093648d8401fc7b0..b527a8c6c467236e5c63234b87b52352197406c6 100644 (file)
@@ -172,12 +172,16 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
                return -ENXIO;
        }
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB))
-               return cia_request_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB),
+       if (irq >= IRQ_AMIGA_AUTO)
+               return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler,
+                                      flags, devname, dev_id);
+
+       if (irq >= IRQ_AMIGA_CIAB)
+               return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB,
                                       handler, flags, devname, dev_id);
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA))
-               return cia_request_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA),
+       if (irq >= IRQ_AMIGA_CIAA)
+               return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA,
                                       handler, flags, devname, dev_id);
 
        if (ami_servers[irq]) {
@@ -196,7 +200,7 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
                                       __FUNCTION__, irq, ami_irq_list[irq]->devname);
                                return -EBUSY;
                        }
-                       if (flags & IRQ_FLG_REPLACE) {
+                       if (!(flags & IRQ_FLG_REPLACE)) {
                                printk("%s: %s can't replace IRQ %d from %s\n",
                                       __FUNCTION__, devname, irq, ami_irq_list[irq]->devname);
                                return -EBUSY;
@@ -209,7 +213,7 @@ int amiga_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r
        }
 
        /* enable the interrupt */
-       if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq])
+       if (irq < IRQ_AMIGA_PORTS && !ami_ablecount[irq])
                custom.intena = IF_SETCLR | ami_intena_vals[irq];
 
        return 0;
@@ -222,20 +226,23 @@ void amiga_free_irq(unsigned int irq, void *dev_id)
                return;
        }
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
-               cia_free_irq(&ciab_base, irq - IRQ_IDX(IRQ_AMIGA_CIAB), dev_id);
+       if (irq >= IRQ_AMIGA_AUTO)
+               sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
+
+       if (irq >= IRQ_AMIGA_CIAB) {
+               cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id);
                return;
        }
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
-               cia_free_irq(&ciaa_base, irq - IRQ_IDX(IRQ_AMIGA_CIAA), dev_id);
+       if (irq >= IRQ_AMIGA_CIAA) {
+               cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id);
                return;
        }
 
        if (ami_servers[irq]) {
                amiga_delete_irq(&ami_irq_list[irq], dev_id);
                /* if server list empty, disable the interrupt */
-               if (!ami_irq_list[irq] && irq < IRQ_IDX(IRQ_AMIGA_PORTS))
+               if (!ami_irq_list[irq] && irq < IRQ_AMIGA_PORTS)
                        custom.intena = ami_intena_vals[irq];
        } else {
                if (ami_irq_list[irq]->dev_id != dev_id)
@@ -267,15 +274,22 @@ void amiga_enable_irq(unsigned int irq)
        if (--ami_ablecount[irq])
                return;
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
+       /* No action for auto-vector interrupts */
+       if (irq >= IRQ_AMIGA_AUTO){
+               printk("%s: Trying to enable auto-vector IRQ %i\n",
+                      __FUNCTION__, irq - IRQ_AMIGA_AUTO);
+               return;
+       }
+
+       if (irq >= IRQ_AMIGA_CIAB) {
                cia_able_irq(&ciab_base, CIA_ICR_SETCLR |
-                            (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB))));
+                            (1 << (irq - IRQ_AMIGA_CIAB)));
                return;
        }
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
+       if (irq >= IRQ_AMIGA_CIAA) {
                cia_able_irq(&ciaa_base, CIA_ICR_SETCLR |
-                            (1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA))));
+                            (1 << (irq - IRQ_AMIGA_CIAA)));
                return;
        }
 
@@ -293,13 +307,20 @@ void amiga_disable_irq(unsigned int irq)
        if (ami_ablecount[irq]++)
                return;
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
-               cia_able_irq(&ciab_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAB)));
+       /* No action for auto-vector interrupts */
+       if (irq >= IRQ_AMIGA_AUTO) {
+               printk("%s: Trying to disable auto-vector IRQ %i\n",
+                      __FUNCTION__, irq - IRQ_AMIGA_AUTO);
+               return;
+       }
+
+       if (irq >= IRQ_AMIGA_CIAB) {
+               cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
                return;
        }
 
-       if (irq >= IRQ_IDX(IRQ_AMIGA_CIAA)) {
-               cia_able_irq(&ciaa_base, 1 << (irq - IRQ_IDX(IRQ_AMIGA_CIAA)));
+       if (irq >= IRQ_AMIGA_CIAA) {
+               cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
                return;
        }
 
@@ -310,13 +331,12 @@ void amiga_disable_irq(unsigned int irq)
 inline void amiga_do_irq(int irq, struct pt_regs *fp)
 {
        kstat.interrupts[SYS_IRQS + irq]++;
-       ami_irq_list[irq]->handler(irq | IRQ_MACHSPEC, ami_irq_list[irq]->dev_id, fp);
+       ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
 }
 
 void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
 {
        irq_node_t *node, *slow_nodes;
-       int mach_irq = irq | IRQ_MACHSPEC;
        unsigned short flags;
 
        kstat.interrupts[SYS_IRQS + irq]++;
@@ -326,7 +346,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
        for (node = ami_irq_list[irq];
             node && (!(node->flags & IRQ_FLG_SLOW));
             node = node->next)
-               node->handler(mach_irq, node->dev_id, fp);
+               node->handler(irq, node->dev_id, fp);
        custom.intreq = ami_intena_vals[irq];
        if (!node) {
                server->count--;
@@ -338,7 +358,7 @@ void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
        slow_nodes = node;
        for (;;) {
                for (; node; node = node->next)
-                       node->handler(mach_irq, node->dev_id, fp);
+                       node->handler(irq, node->dev_id, fp);
                /* if reentrance occured, serve slow handlers again */
                custom.intena = ami_intena_vals[irq];
                if (!server->reentrance) {
@@ -363,19 +383,19 @@ static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
        /* if serial transmit buffer empty, interrupt */
        if (ints & IF_TBE) {
                custom.intreq = IF_TBE;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_TBE), fp);
+               amiga_do_irq(IRQ_AMIGA_TBE, fp);
        }
 
        /* if floppy disk transfer complete, interrupt */
        if (ints & IF_DSKBLK) {
                custom.intreq = IF_DSKBLK;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKBLK), fp);
+               amiga_do_irq(IRQ_AMIGA_DSKBLK, fp);
        }
 
        /* if software interrupt set, interrupt */
        if (ints & IF_SOFT) {
                custom.intreq = IF_SOFT;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_SOFT), fp);
+               amiga_do_irq(IRQ_AMIGA_SOFT, fp);
        }
 }
 
@@ -387,18 +407,18 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
        /* if a blitter interrupt */
        if (ints & IF_BLIT) {
                custom.intreq = IF_BLIT;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_BLIT), fp);
+               amiga_do_irq(IRQ_AMIGA_BLIT, fp);
        }
 
        /* if a copper interrupt */
        if (ints & IF_COPER) {
                custom.intreq = IF_COPER;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_COPPER), fp);
+               amiga_do_irq(IRQ_AMIGA_COPPER, fp);
        }
 
        /* if a vertical blank interrupt */
        if (ints & IF_VERTB)
-               amiga_do_irq_list(IRQ_IDX(IRQ_AMIGA_VERTB), fp, &server);
+               amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
 }
 
 static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
@@ -408,25 +428,25 @@ static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
        /* if audio 0 interrupt */
        if (ints & IF_AUD0) {
                custom.intreq = IF_AUD0;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD0), fp);
+               amiga_do_irq(IRQ_AMIGA_AUD0, fp);
        }
 
        /* if audio 1 interrupt */
        if (ints & IF_AUD1) {
                custom.intreq = IF_AUD1;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD1), fp);
+               amiga_do_irq(IRQ_AMIGA_AUD1, fp);
        }
 
        /* if audio 2 interrupt */
        if (ints & IF_AUD2) {
                custom.intreq = IF_AUD2;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD2), fp);
+               amiga_do_irq(IRQ_AMIGA_AUD2, fp);
        }
 
        /* if audio 3 interrupt */
        if (ints & IF_AUD3) {
                custom.intreq = IF_AUD3;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_AUD3), fp);
+               amiga_do_irq(IRQ_AMIGA_AUD3, fp);
        }
 }
 
@@ -437,13 +457,13 @@ static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
        /* if serial receive buffer full interrupt */
        if (ints & IF_RBF) {
                /* acknowledge of IF_RBF must be done by the serial interrupt */
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_RBF), fp);
+               amiga_do_irq(IRQ_AMIGA_RBF, fp);
        }
 
        /* if a disk sync interrupt */
        if (ints & IF_DSKSYN) {
                custom.intreq = IF_DSKSYN;
-               amiga_do_irq(IRQ_IDX(IRQ_AMIGA_DSKSYN), fp);
+               amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
        }
 }
 
index 7bf579f39cb4948ca78cddce7ca91b4917f04ce5..02b1ad56425063c16c37d930ee3b89fb76e43bdb 100644 (file)
@@ -30,13 +30,13 @@ struct ciabase {
        irq_handler_t irq_list[CIA_IRQS];
 } ciaa_base = {
        &ciaa, 0, 0, IF_PORTS,
-       IRQ2, IRQ_AMIGA_CIAA,
-       IRQ_IDX(IRQ_AMIGA_PORTS),
+       IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
+       IRQ_AMIGA_PORTS,
        "CIAA handler", {0, 0}
 }, ciab_base = {
        &ciab, 0, 0, IF_EXTER,
-       IRQ6, IRQ_AMIGA_CIAB,
-       IRQ_IDX(IRQ_AMIGA_EXTER),
+       IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
+       IRQ_AMIGA_EXTER,
        "CIAB handler", {0, 0}
 };
 
@@ -95,14 +95,14 @@ int cia_request_irq(struct ciabase *base, unsigned int irq,
 
        if (!(base->irq_list[irq].flags & IRQ_FLG_STD)) {
                if (base->irq_list[irq].flags & IRQ_FLG_LOCK) {
-                       printk("%s: IRQ %ld from %s is not replaceable\n",
-                              __FUNCTION__, IRQ_IDX(base->cia_irq + irq),
+                       printk("%s: IRQ %i from %s is not replaceable\n",
+                              __FUNCTION__, base->cia_irq + irq,
                               base->irq_list[irq].devname);
                        return -EBUSY;
                }
-               if (flags & IRQ_FLG_REPLACE) {
-                       printk("%s: %s can't replace IRQ %ld from %s\n", __FUNCTION__,
-                              devname, IRQ_IDX(base->cia_irq + irq),
+               if (!(flags & IRQ_FLG_REPLACE)) {
+                       printk("%s: %s can't replace IRQ %i from %s\n", __FUNCTION__,
+                              devname, base->cia_irq + irq,
                               base->irq_list[irq].devname);
                        return -EBUSY;
                }
@@ -122,8 +122,8 @@ int cia_request_irq(struct ciabase *base, unsigned int irq,
 void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id)
 {
        if (base->irq_list[irq].dev_id != dev_id)
-               printk("%s: removing probably wrong IRQ %ld from %s\n",
-                      __FUNCTION__, IRQ_IDX(base->cia_irq + irq),
+               printk("%s: removing probably wrong IRQ %i from %s\n",
+                      __FUNCTION__, base->cia_irq + irq,
                       base->irq_list[irq].devname);
 
        base->irq_list[irq].handler = NULL;
@@ -139,7 +139,7 @@ static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
        unsigned char ints;
 
        mach_irq = base->cia_irq;
-       irq = SYS_IRQS + IRQ_IDX(mach_irq);
+       irq = SYS_IRQS + mach_irq;
        ints = cia_set_irq(base, CIA_ICR_ALL);
        custom.intreq = base->int_mask;
        for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
@@ -176,7 +176,7 @@ int cia_get_irq_list(struct ciabase *base, char *buf)
 {
        int i, j, len = 0;
 
-       j = IRQ_IDX(base->cia_irq);
+       j = base->cia_irq;
        for (i = 0; i < CIA_IRQS; i++) {
                if (!(base->irq_list[i].flags & IRQ_FLG_STD)) {
                        len += sprintf(buf+len, "cia  %2d: %10d ", j + i,
index 5ed4b6bba63fc2beda57f82ecd6f030e10a5d4b2..8e6ae531cf5ef5adb8956be75a8ae8bc3cad2b47 100644 (file)
@@ -29,7 +29,7 @@
 #include <asm/amigaints.h>
 #include <asm/irq.h>
 #include <asm/machdep.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 u_long amiga_model;
 u_long amiga_eclock;
@@ -56,7 +56,7 @@ extern void amiga_init_IRQ (void);
 extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
 extern int amiga_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                               unsigned long flags, const char *devname, void *dev_id);
-extern int amiga_free_irq (unsigned int irq, void *dev_id);
+extern void amiga_free_irq (unsigned int irq, void *dev_id);
 extern void amiga_enable_irq (unsigned int);
 extern void amiga_disable_irq (unsigned int);
 static void amiga_get_model(char *model);
@@ -74,15 +74,20 @@ extern int amiga_floppy_init (void);
 extern void amiga_floppy_setup(char *, int *);
 #endif
 static void amiga_reset (void);
-static void amiga_waitbut(void);
+static void amiga_wait_key(void);
 extern struct consw fb_con;
 extern struct fb_info *amiga_fb_init(long *);
 extern void zorro_init(void);
-static void ami_savekmsg_init(void);
-static void ami_mem_print(const char *b);
+static void amiga_savekmsg_init(void);
+static void amiga_mem_console_write(const char *b, unsigned int count);
+static void amiga_serial_console_write(const char *s, unsigned int count);
 static void amiga_debug_init(void);
+
 extern void amiga_video_setup(char *, int *);
-extern void amiga_syms_export(void);
+
+static struct console amiga_console_driver = {
+    NULL, NULL, amiga_wait_key
+};
 
 extern void (*kd_mksound)(unsigned int, unsigned int);
 
@@ -151,6 +156,8 @@ void config_amiga(void)
 
   memset(&amiga_hw_present, 0, sizeof(amiga_hw_present));
 
+  amiga_debug_init();
+
   printk("Amiga hardware found: ");
   if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO)
     printk("[%s] ", amiga_models[amiga_model-AMI_500]);
@@ -304,8 +311,8 @@ void config_amiga(void)
   mach_default_handler = &amiga_default_handler;
   mach_request_irq     = amiga_request_irq;
   mach_free_irq        = amiga_free_irq;
-  mach_enable_irq      = amiga_enable_irq;
-  mach_disable_irq     = amiga_disable_irq;
+  enable_irq           = amiga_enable_irq;
+  disable_irq          = amiga_disable_irq;
   mach_get_model       = amiga_get_model;
   mach_get_hardware_list = amiga_get_hardware_list;
   mach_get_irq_list    = amiga_get_irq_list;
@@ -329,18 +336,14 @@ void config_amiga(void)
 
   mach_hwclk           = amiga_hwclk;
   mach_set_clock_mmss  = amiga_set_clock_mmss;
-  mach_mksound         = amiga_mksound;
 #ifdef CONFIG_BLK_DEV_FD
   mach_floppy_init     = amiga_floppy_init;
   mach_floppy_setup    = amiga_floppy_setup;
 #endif
   mach_reset           = amiga_reset;
-  waitbut              = amiga_waitbut;
   conswitchp           = &fb_con;
   mach_fb_init         = amiga_fb_init;
-  mach_debug_init      = amiga_debug_init;
   mach_video_setup     = amiga_video_setup;
-  mach_syms_export     = amiga_syms_export;
   kd_mksound           = amiga_mksound;
 
   /* Fill in the clock values (based on the 700 kHz E-Clock) */
@@ -355,10 +358,6 @@ void config_amiga(void)
   /* initialize chipram allocator */
   amiga_chip_init ();
 
-  /* initialize only once here, not every time the debug level is raised */
-  if (!strcmp( m68k_debug_device, "mem" ))
-    ami_savekmsg_init();
-
   /*
    * if it is an A3000, set the magic bit that forces
    * a hard rekick
@@ -588,7 +587,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime)
        return 0;
 }
 
-static void amiga_waitbut (void)
+static void amiga_wait_key (void)
 {
     int i;
 
@@ -614,33 +613,6 @@ static void amiga_waitbut (void)
     }
 }
 
-void ami_serial_print (const char *str)
-{
-    while (*str) {
-        if (*str == '\n') {
-            custom.serdat = (unsigned char)'\r' | 0x100;
-            while (!(custom.serdatr & 0x2000))
-                ;
-        }
-        custom.serdat = (unsigned char)*str++ | 0x100;
-        while (!(custom.serdatr & 0x2000))
-            ;
-    }
-}
-
-static void amiga_debug_init (void)
-{
-    extern void (*debug_print_proc)(const char *);
-
-    if (!strcmp( m68k_debug_device, "ser" )) {
-        /* no initialization required (?) */
-        debug_print_proc = ami_serial_print;
-    } else if (!strcmp( m68k_debug_device, "mem" )) {
-        /* already initialized by config_amiga() (needed only once) */
-        debug_print_proc = ami_mem_print;
-    }
-}
-
 void dbprintf(const char *fmt , ...)
 {
        static char buf[1024];
@@ -672,8 +644,10 @@ static void amiga_reset (void)
       ("movel    %0,%/d0\n\t"
        "andl     #0xff000000,%/d0\n\t"
        "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
-       ".long    0x4e7b0004\n\t"   /* movec d0,itt0 */
-       ".long    0x4e7b0006\n\t"   /* movec d0,dtt0 */
+       ".chip    68040\n\t"
+       "movec    %%d0,%%itt0\n\t"
+       "movec    %%d0,%%dtt0\n\t"
+       ".chip    68k\n\t"
        "jmp      %0@\n\t"
        : /* no outputs */
        : "a" (jmp_addr040));
@@ -692,7 +666,9 @@ static void amiga_reset (void)
   /* disable translation on '040 now */
   __asm__ __volatile__    
     ("moveq #0,%/d0\n\t"
-     ".long 0x4e7b0003\n\t"         /* movec d0,tc; disable MMU */
+     ".chip 68040\n\t"
+     "movec %%d0,%%tc\n\t"     /* disable MMU */
+     ".chip 68k\n\t"
      : /* no outputs */
      : /* no inputs */
      : "d0");
@@ -718,12 +694,13 @@ static void amiga_reset (void)
 
 }
 
-extern void *amiga_chip_alloc(long size);
 
+    /*
+     *  Debugging
+     */
 
 #define SAVEKMSG_MAXMEM                128*1024
 
-
 #define SAVEKMSG_MAGIC1                0x53415645      /* 'SAVE' */
 #define SAVEKMSG_MAGIC2                0x4B4D5347      /* 'KMSG' */
 
@@ -737,8 +714,15 @@ struct savekmsg {
 
 static struct savekmsg *savekmsg = NULL;
 
+static void amiga_mem_console_write(const char *s, unsigned int count)
+{
+    if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) {
+        memcpy(savekmsg->data+savekmsg->size, s, count);
+        savekmsg->size += count;
+    }
+}
 
-static void ami_savekmsg_init(void)
+static void amiga_savekmsg_init(void)
 {
     savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM);
     savekmsg->magic1 = SAVEKMSG_MAGIC1;
@@ -747,19 +731,88 @@ static void ami_savekmsg_init(void)
     savekmsg->size = 0;
 }
 
+static void amiga_serial_putc(char c)
+{
+    custom.serdat = (unsigned char)c | 0x100;
+    while (!(custom.serdatr & 0x2000))
+       ;
+}
+
+static void amiga_serial_console_write(const char *s, unsigned int count)
+{
+    while (count--) {
+       if (*s == '\n')
+           amiga_serial_putc('\r');
+       amiga_serial_putc(*s++);
+    }
+}
+
+#ifdef CONFIG_SERIAL_CONSOLE
+void amiga_serial_puts(const char *s)
+{
+    amiga_serial_console_write(s, strlen(s));
+}
 
-static void ami_mem_print(const char *b)
+void amiga_serial_gets(char *s, int len)
 {
-    int len;
+    int ch, cnt = 0;
 
-    for (len = 0; b[len]; len++);
-    if (savekmsg->size+len <= SAVEKMSG_MAXMEM) {
-        memcpy(savekmsg->data+savekmsg->size, b, len);
-        savekmsg->size += len;
+    while (1) {
+       while (!(custom.intreqr & IF_RBF))
+           barrier();
+       ch = custom.serdatr & 0xff;
+       /* clear the interrupt, so that another character can be read */
+       custom.intreq = IF_RBF;
+
+       /* Check for backspace. */
+       if (ch == 8 || ch == 127) {
+           if (cnt == 0) {
+               amiga_serial_putc('\007');
+               continue;
+           }
+           cnt--;
+           amiga_serial_puts("\010 \010");
+           continue;
+       }
+
+       /* Check for enter. */
+       if (ch == 10 || ch == 13)
+           break;
+
+       /* See if line is too long. */
+       if (cnt >= len + 1) {
+           amiga_serial_putc(7);
+           cnt--;
+           continue;
+       }
+
+       /* Store and echo character. */
+       s[cnt++] = ch;
+       amiga_serial_putc(ch);
+    }
+    /* Print enter. */
+    amiga_serial_puts("\r\n");
+    s[cnt] = 0;
+}
+#endif
+
+static void amiga_debug_init(void)
+{
+    if (!strcmp( m68k_debug_device, "ser" )) {
+        /* no initialization required (?) */
+       amiga_console_driver.write = amiga_serial_console_write;
+    } else if (!strcmp( m68k_debug_device, "mem" )) {
+       amiga_savekmsg_init();
+       amiga_console_driver.write = amiga_mem_console_write;
     }
+    register_console(&amiga_console_driver);
 }
 
 
+    /*
+     *  Amiga specific parts of /proc
+     */
+
 static void amiga_get_model(char *model)
 {
     strcpy(model, "Amiga ");
index c6cd16e9998e89ed137de1f4cbe87a81f0c9bb10..d74d52c4f1e6960e8d08ff86748b0245fca4f888 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/irq.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 #include <asm/pgtable.h>
 #include <linux/fb.h>
 #include "s3blit.h"
@@ -235,6 +235,7 @@ struct fb_info *Cyber_fb_init(long *mem_start); /* Through amiga_fb_init() */
 static int Cyberfb_switch(int con);
 static int Cyberfb_updatevar(int con);
 static void Cyberfb_blank(int blank);
+static int Cyberfb_setcmap(struct fb_cmap *cmap, int con);
 
 
    /*
@@ -1179,6 +1180,7 @@ struct fb_info *Cyber_fb_init(long *mem_start)
    fb_info.switch_con = &Cyberfb_switch;
    fb_info.updatevar = &Cyberfb_updatevar;
    fb_info.blank = &Cyberfb_blank;
+   fb_info.setcmap = &Cyberfb_setcmap;
 
    do_fb_set_var(&Cyber_fb_predefined[0], 1);
    Cyber_fb_get_var(&disp[0].var, -1);
@@ -1225,6 +1227,16 @@ static void Cyberfb_blank(int blank)
 }
 
 
+   /*
+    *    Set the colormap
+    */
+
+static int Cyberfb_setcmap(struct fb_cmap *cmap, int con)
+{
+   return(Cyber_fb_set_cmap(cmap, 1, con));
+}
+
+
    /*
     *    Get a Video Mode
     */
index 7a762d63c076da0a6e19fce35867e1ed39949e29..acca3e6bc332f0684b233fb185fd98b8bc05e6aa 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/setup.h>
 #include <asm/bitops.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 
 #ifdef CONFIG_ZORRO
@@ -82,6 +82,10 @@ BEGIN_PROD(MEMPHIS)
    PROD("Stormbringer", STORMBRINGER)
 END
 
+BEGIN_PROD(3_STATE)
+   PROD("Megamix 2000 RAM", MEGAMIX_2000)
+END
+
 BEGIN_PROD(COMMODORE2)
    PROD("A2088 XT Bridgeboard", A2088)
    PROD("A2286 AT Bridgeboard", A2286)
@@ -141,8 +145,12 @@ BEGIN_PROD(MICROBOTICS)
    PROD("StarDrive", STARDRIVE)
    PROD("8-Up (Rev A)", 8_UP_A)
    PROD("8-Up (Rev Z)", 8_UP_Z)
+   PROD("Delta Card RAM", DELTA_RAM)
+   PROD("8-Star RAM", 8_STAR_RAM)
+   PROD("8-Star", 8_STAR)
    PROD("VXL RAM", VXL_RAM)
    PROD("VXL-30 Turbo Board", VXL_30)
+   PROD("Delta Card", DELTA)
    PROD("MBX 1200", MBX_1200)
    PROD("Hardframe 2000", HARDFRAME_2000)
    PROD("MBX 1200", MBX_1200_2)
@@ -180,8 +188,8 @@ BEGIN_PROD(SUPRA)
    PROD("SupraDrive 4x4 SCSI Controller", SUPRADRIVE_4x4)
    PROD("2000 DMA HD", SUPRA_2000)
    PROD("500 HD/RAM", SUPRA_500)
+   PROD("500XP/2000 RAM", SUPRA_500XP)
    PROD("500RX/2000 RAM", SUPRA_500RX)
-   PROD("500RX/2000 RAM", SUPRA_500RX_2)
    PROD("2400zi Modem", SUPRA_2400ZI)
    PROD("Wordsync SCSI Controller", WORDSYNC)
    PROD("Wordsync II SCSI Controller", WORDSYNC_II)
@@ -193,6 +201,10 @@ BEGIN_PROD(CSA)
    PROD("12 Gauge SCSI Controller", 12GAUGE)
 END
 
+BEGIN_PROD(MTEC2)
+   PROD("AT500 RAM", AT500_2)
+END
+
 BEGIN_PROD(GVP3)
    PROD("Impact SCSI/Memory", IMPACT)
 END
@@ -203,7 +215,11 @@ END
 
 BEGIN_PROD(POWER_COMPUTING)
    PROD("DKB 3128 RAM", DKB_3128)
+   PROD("Rapid Fire SCSI Controller", RAPID_FIRE)
+   PROD("DKB 1202 RAM", DKB_1202)
    PROD("DKB Cobra / Viper II Turbo Board", VIPER_II_COBRA)
+   PROD("WildFire 060 Turbo Board", WILDFIRE_060)
+   PROD("WildFire 060 Turbo Board", WILDFIRE_060_2)
 END
 
 BEGIN_PROD(GVP)
@@ -257,6 +273,9 @@ BEGIN_PROD(PPI)
    PROD("PP&S A500 68040 Turbo Board", PPS_A500_040)
 END
 
+BEGIN_PROD(XEBEC)
+END
+
 BEGIN_PROD(SPIRIT)
    PROD("HDA 506 Harddisk", HDA_506)
    PROD("OctaByte RAM", OCTABYTE_RAM)
@@ -268,6 +287,7 @@ END
 
 BEGIN_PROD(BSC3)
    PROD("ALF 2 SCSI Controller", ALF_2_SCSI)
+   PROD("ALF 2 SCSI Controller", ALF_2_SCSI_2)
    PROD("ALF 3 SCSI Controller", ALF_3_SCSI_2)
 END
 
@@ -291,9 +311,17 @@ END
 BEGIN_PROD(KUPKE2)
    PROD("Golem SCSI-II Controller", KUPKE_SCSI_II)
    PROD("Golem Box", GOLEM_BOX)
+   PROD("030/882 Turbo Board", KUPKE_TURBO)
    PROD("Golem SCSI/AT Controller", KUPKE_SCSI_AT)
 END
 
+BEGIN_PROD(GVP4)
+   PROD("A2000-RAM8/2", A2000_RAM8)
+END
+
+BEGIN_PROD(INTERWORKS_NET)
+END
+
 BEGIN_PROD(HARDITAL)
    PROD("TQM 68030+68882 Turbo Board", TQM)
 END
@@ -301,10 +329,14 @@ END
 BEGIN_PROD(BSC2)
    PROD("Oktagon 2008 SCSI Controller", OKTAGON_SCSI)
    PROD("Tandem AT-2008/508 IDE Controller", TANDEM)
+   PROD("Alpha RAM 1200", ALPHA_RAM_1200)
    PROD("Oktagon 2008 RAM", OKTAGON_RAM)
    PROD("Alfa Data MultiFace I", MULTIFACE_I)
    PROD("Alfa Data MultiFace II", MULTIFACE_II)
    PROD("Alfa Data MultiFace III", MULTIFACE_III)
+   PROD("Framebuffer", BSC_FRAEMBUFFER)
+   PROD("Graffiti Graphics Board (RAM)", GRAFFITI_RAM)
+   PROD("Graffiti Graphics Board (REG)", GRAFFITI_REG)
    PROD("ISDN MasterCard", ISDN_MASTERCARD)
    PROD("ISDN MasterCard II", ISDN_MASTERCARD_2)
 END
@@ -319,12 +351,15 @@ BEGIN_PROD(IMPULSE)
 END
 
 BEGIN_PROD(IVS)
-   PROD("GrandSlam RAM", GRANDSLAM)
+   PROD("GrandSlam PIC 2 RAM", GRANDSLAM_PIC_2)
+   PROD("GrandSlam PIC 1 RAM", GRANDSLAM_PIC_1)
    PROD("OverDrive HD", IVS_OVERDRIVE)
    PROD("Trumpcard Classic SCSI Controller", TRUMPCARD_CLASSIC)
    PROD("Trumpcard Pro SCSI Controller", TRUMPCARD_PRO)
    PROD("Meta-4 RAM", META_4)
+   PROD("Wavetools Sound Board", WAVETOOLS)
    PROD("Vector SCSI Controller", VECTOR)
+   PROD("Vector SCSI Controller", VECTOR_2)
 END
 
 BEGIN_PROD(VECTOR)
@@ -336,6 +371,7 @@ BEGIN_PROD(XPERT_PRODEV)
    PROD("Visiona Graphics Board (REG)", VISIONA_REG)
    PROD("Merlin Graphics Board (RAM)", MERLIN_RAM)
    PROD("Merlin Graphics Board (REG)", MERLIN_REG)
+   PROD("Merlin Graphics Board (REG)", MERLIN_REG_2)
 END
 
 BEGIN_PROD(HYDRA_SYSTEMS)
@@ -388,7 +424,11 @@ BEGIN_PROD(VILLAGE_TRONIC)
    PROD("Domino Graphics Board (REG)", DOMINO_REG)
    PROD("Picasso II Graphics Board (RAM)", PICASSO_II_RAM)
    PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG)
-   PROD("Picasso II Graphics Board (REG)", PICASSO_II_REG_2)
+   PROD("Picasso II/II+ Graphics Board (Segmented Mode)", PICASSO_II_SEGM)
+   PROD("Picassio IV Graphics Board", PICASSO_IV)
+   PROD("Picassio IV Graphics Board", PICASSO_IV_2)
+   PROD("Picassio IV Graphics Board", PICASSO_IV_3)
+   PROD("Picassio IV Graphics Board", PICASSO_IV_4)
    PROD("Ariadne Ethernet Card", ARIADNE)
 END
 
@@ -402,8 +442,18 @@ BEGIN_PROD(AMITRIX)
    PROD("CD-RAM Memory", AMITRIX_CD_RAM)
 END
 
+BEGIN_PROD(ARMAX)
+   PROD("OmniBus Graphics Board", OMNIBUS)
+END
+
+BEGIN_PROD(NEWTEK)
+   PROD("VideoToaster", VIDEOTOASTER)
+END
+
 BEGIN_PROD(MTEC)
+   PROD("AT500 IDE Controller", AT500)
    PROD("68030 Turbo Board", MTEC_68030)
+   PROD("68020i Turbo Board", MTEC_68020I)
    PROD("A1200 T68030/42 RTC Turbo Board", MTEC_T1230)
    PROD("8MB RAM", MTEC_RAM)
 END
@@ -439,6 +489,11 @@ BEGIN_PROD(MICRONIK)
    PROD("RCA 120 RAM", RCA_120)
 END
 
+BEGIN_PROD(MEGA_MICRO)
+   PROD("SCRAM 500 SCSI Controller", SCRAM_500_SCSI)
+   PROD("SCRAM 500 RAM", SCRAM_500_RAM)
+END
+
 BEGIN_PROD(IMTRONICS2)
    PROD("Hurricane 2800 68030", HURRICANE_2800_3)
    PROD("Hurricane 2800 68030", HURRICANE_2800_4)
@@ -448,6 +503,15 @@ BEGIN_PROD(KUPKE3)
    PROD("Golem HD 3000", GOLEM_3000)
 END
 
+BEGIN_PROD(ITH)
+   PROD("ISDN-Master II", ISDN_MASTER_II)
+END
+
+BEGIN_PROD(VMC)
+   PROD("ISDN Blaster Z2", ISDN_BLASTER_Z2)
+   PROD("HyperCom 4", HYPERCOM_4)
+END
+
 BEGIN_PROD(INFORMATION)
    PROD("ISDN Engine I", ISDN_ENGINE_I)
 END
@@ -479,6 +543,8 @@ BEGIN_PROD(PHASE5)
    PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI)
    PROD("CyberStorm Mk II", CYBERSTORM_II)
    PROD("CyberVision64 Graphics Board", CYBERVISION)
+   PROD("CyberVision64-3D Graphics Board Prototype)", CYBERVISION3D_PRT)
+   PROD("CyberVision64-3D Graphics Board", CYBERVISION3D)
 END
 
 BEGIN_PROD(DPS)
@@ -487,6 +553,7 @@ END
 
 BEGIN_PROD(APOLLO2)
    PROD("A620 68020 Accelerator", A620)
+   PROD("A620 68020 Accelerator", A620_2)
 END
 
 BEGIN_PROD(APOLLO)
@@ -494,6 +561,10 @@ BEGIN_PROD(APOLLO)
    PROD("Turbo Board", APOLLO_TURBO)
 END
 
+BEGIN_PROD(PETSOFF)
+   PROD("Delfina DSP", DELFINA)
+END
+
 BEGIN_PROD(UWE_GERLACH)
    PROD("RAM/ROM", UG_RAM_ROM)
 END
@@ -507,6 +578,7 @@ BEGIN_PROD(MACROSYSTEMS2)
    PROD("Toccata Sound Board", TOCCATA)
    PROD("Retina Z3 Graphics Board", RETINA_Z3)
    PROD("VLab Motion", VLAB_MOTION)
+   PROD("Altais Graphics Board", ALTAIS)
    PROD("Falcon '040 Turbo Board", FALCON_040)
 END
 
@@ -514,11 +586,12 @@ BEGIN_PROD(COMBITEC)
 END
 
 BEGIN_PROD(SKI)
+   PROD("MAST Fireball SCSI Controller", MAST_FIREBALL)
    PROD("SCSI / Dual Serial", SKI_SCSI_SERIAL)
 END
 
 BEGIN_PROD(CAMERON)
-   PROD("Scanner Interface", CAMERON_SCANNER)
+   PROD("Personal A4", PERSONAL_A4)
 END
 
 BEGIN_PROD(REIS_WARE)
@@ -530,6 +603,7 @@ BEGIN_MANUF
    MANUF("Pacific Peripherals", PACIFIC)
    MANUF("Kupke", KUPKE)
    MANUF("Memphis", MEMPHIS)
+   MANUF("3-State", 3_STATE)
    MANUF("Commodore", COMMODORE2)
    MANUF("Commodore", COMMODORE)
    MANUF("Commodore", COMMODORE3)
@@ -546,7 +620,8 @@ BEGIN_MANUF
    MANUF("University of Lowell", UNIV_OF_LOWELL)
    MANUF("Ameristar", AMERISTAR)
    MANUF("Supra", SUPRA)
-   MANUF("CSA", CSA)
+   MANUF("Computer Systems Ass.", CSA)
+   MANUF("M-Tech", MTEC2)
    MANUF("Great Valley Products", GVP3)
    MANUF("ByteBox", BYTEBOX)
    MANUF("Power Computing", POWER_COMPUTING)
@@ -554,6 +629,7 @@ BEGIN_MANUF
    MANUF("Synergy", SYNERGY)
    MANUF("Xetec", XETEC)
    MANUF("Progressive Peripherals", PPI)
+   MANUF("Xebec", XEBEC)
    MANUF("Spirit", SPIRIT)
    MANUF("BSC", BSC)
    MANUF("BSC", BSC3)
@@ -562,6 +638,8 @@ BEGIN_MANUF
    MANUF("Checkpoint Technologies", CHECKPOINT)
    MANUF("ICD", ICD)
    MANUF("Kupke", KUPKE2)
+   MANUF("Great Valley Products", GVP4)
+   MANUF("Interworks Network", INTERWORKS_NET)
    MANUF("Hardital Synthesis", HARDITAL)
    MANUF("BSC", BSC2)
    MANUF("Advanced Systems & Software", ADV_SYS_SOFT)
@@ -582,15 +660,20 @@ BEGIN_MANUF
    MANUF("Village Tronic", VILLAGE_TRONIC)
    MANUF("Utilities Unlimited", UTILITIES_ULTD)
    MANUF("Amitrix", AMITRIX)
-   MANUF("MTEC", MTEC)
+   MANUF("ArMax", ARMAX)
+   MANUF("NewTek", NEWTEK)
+   MANUF("M-Tech", MTEC)
    MANUF("Great Valley Products", GVP2)
    MANUF("Helfrich", HELFRICH2)
    MANUF("MacroSystems", MACROSYSTEMS)
    MANUF("ElBox Computer", ELBOX)
    MANUF("Harms Professional", HARMS_PROF)
    MANUF("Micronik", MICRONIK)
+   MANUF("MegaMicro", MEGA_MICRO)
    MANUF("Imtronics", IMTRONICS2)
    MANUF("Kupke", KUPKE3)
+   MANUF("ITH", ITH)
+   MANUF("VMC", VMC)
    MANUF("Information", INFORMATION)
    MANUF("Vortex", VORTEX)
    MANUF("DataFlyer", DATAFLYER)
@@ -599,6 +682,7 @@ BEGIN_MANUF
    MANUF("DPS", DPS)
    MANUF("Apollo", APOLLO2)
    MANUF("Apollo", APOLLO)
+   MANUF("Petsoff LP", PETSOFF)
    MANUF("Uwe Gerlach", UWE_GERLACH)
    MANUF("MacroSystems", MACROSYSTEMS2)
    MANUF("Combitec", COMBITEC)
@@ -758,7 +842,11 @@ static int identify(int devnum, char *buf)
                   identified = 1;
                   break;
                } else {
-                  epc = *(enum GVP_ident *)ZTWO_VADDR(addr+0x8000) &
+                      /*
+                       * The epc must be read as a short from the
+                       * hardware.
+                       */
+                  epc = *(unsigned short *)ZTWO_VADDR(addr+0x8000) &
                         GVP_PRODMASK;
                   for (k = 0; k < NUM_GVP_PROD; k++)
                      if (Ext_Prod_GVP[k].ID == epc) {
index 959c564513e842721716a31fd936a92a08172549..64c9a62d3eca5ff0ea0f559197c40d0142a815b1 100644 (file)
@@ -2905,6 +2905,12 @@ atafb_blank(int blank)
                do_install_cmap(currcon);
 }
 
+static int
+atafb_setcmap(struct fb_cmap *cmap, int con)
+{
+       return(atari_fb_set_cmap(cmap, 1, con));
+}
+
 struct fb_info *
 atari_fb_init(long *mem_start)
 {
@@ -2999,6 +3005,7 @@ atari_fb_init(long *mem_start)
        fb_info.switch_con=&atafb_switch;
        fb_info.updatevar=&fb_update_var;
        fb_info.blank=&atafb_blank;
+       fb_info.setcmap=&atafb_setcmap;
        var=atari_fb_predefined+default_par-1;
        do_fb_set_var(var,1);
        strcat(fb_info.modename,fb_var_names[default_par-1][0]);
index b8b3b56672a451cd55f1541952748dd19c038f36..b65beefb1415c3075572275d11f0673f7ab510bc 100644 (file)
@@ -56,9 +56,7 @@
  * All interrupt source have an internal number (defined in
  * <asm/atariints.h>): Autovector interrupts are 1..7, then follow ST-MFP,
  * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can
- * be allocated by atari_register_vme_int(). Currently, all int source numbers
- * have the IRQ_MACHSPEC bit set, to keep the general int handling functions
- * in kernel/ints.c from them.
+ * be allocated by atari_register_vme_int().
  *
  * Each interrupt can be of three types:
  * 
@@ -180,7 +178,7 @@ asmlinkage void IRQ_NAME(n);                                                   \
 void atari_slow_irq_##n##_dummy (void) {                                  \
 __asm__ (ALIGN_STR "\n"                                                           \
 SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t"                         \
-"      addql   #1,"SYMBOL_NAME_STR(intr_count)"\n"                        \
+"      addql   #1,"SYMBOL_NAME_STR(local_irq_count)"\n"                   \
        SAVE_ALL "\n"                                                      \
 "      andb    #~(1<<(" #n "&7)),"     /* mask this interrupt */          \
        "("MFP_MK_BASE"+(((" #n "&8)^8)>>2)+((" #n "&16)<<3)):w\n"         \
@@ -192,7 +190,7 @@ SYMBOL_NAME_STR(atari_slow_irq_) #n "_handler:\t"                      \
 "      lea     "SYMBOL_NAME_STR(irq_handler)"+("#n"+8)*8,%%a0\n"          \
 "      pea     %%sp@\n"                /* push addr of frame */           \
 "      movel   %%a0@(4),%%sp@-\n"      /* push handler data */            \
-"      pea     (" #n "+0x10000008)\n"  /* push int number */              \
+"      pea     (" #n "+8)\n"           /* push int number */              \
 "      movel   %%a0@,%%a0\n"                                              \
 "      jbsr    %%a0@\n"                /* call the handler */             \
 "      addql   #8,%%sp\n"                                                 \
@@ -283,7 +281,7 @@ __asm__ (ALIGN_STR "\n"
 SYMBOL_NAME_STR(atari_fast_irq_handler) ":
        orw     #0x700,%%sr             /* disable all interrupts */
 "SYMBOL_NAME_STR(atari_prio_irq_handler) ":\t
-       addql   #1,"SYMBOL_NAME_STR(intr_count)"\n"
+       addql   #1,"SYMBOL_NAME_STR(local_irq_count)"\n"
        SAVE_ALL "
        /* get vector number from stack frame and convert to source */
        bfextu  %%sp@(" FORMATVEC "){#4,#10},%%d0
@@ -296,7 +294,6 @@ SYMBOL_NAME_STR(atari_fast_irq_handler) ":
        lea     %%a0@(%%d0:l:8),%%a0
        pea     %%sp@                   /* push frame address */
        movel   %%a0@(4),%%sp@-         /* push handler data */
-       bset    #28,%%d0                /* set MACHSPEC bit */
        movel   %%d0,%%sp@-             /* push int number */
        movel   %%a0@,%%a0
        jsr     %%a0@                   /* and call the handler */
@@ -587,14 +584,12 @@ unsigned long atari_register_vme_int(void)
                return 0;
 
        free_vme_vec_bitmap |= 1 << i;
-       return (VME_SOURCE_BASE + i) | IRQ_MACHSPEC;
+       return (VME_SOURCE_BASE + i);
 }
 
 
 void atari_unregister_vme_int(unsigned long irq)
 {
-       irq &= ~IRQ_MACHSPEC;
-       
        if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {
                irq -= VME_SOURCE_BASE;
                free_vme_vec_bitmap &= ~(1 << irq);
index 95cc0245f225aa30071cee126bef97dd4540fe36..4f57cb928c10caf12e4d716c88d006059d476e32 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/keyboard.h>
@@ -40,6 +41,15 @@ void (*atari_MIDI_interrupt_hook) (void);
 /* Hook for mouse driver */
 void (*atari_mouse_interrupt_hook) (char *);
 
+/* variables for IKBD self test: */
+
+/* state: 0: off; >0: in progress; >1: 0xf1 received */
+static volatile int ikbd_self_test;
+/* timestamp when last received a char */
+static volatile unsigned long self_test_last_rcv;
+/* bitmap of keys reported as broken */
+static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, };
+
 #define BREAK_MASK     (0x80)
 
 /*
@@ -331,12 +341,15 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
     {
        /* a very fast typist or a slow system, give a warning */
        /* ...happens often if interrupts were disabled for too long */
-       printk( "Keyboard overrun\n" );
+       printk( KERN_DEBUG "Keyboard overrun\n" );
        scancode = acia.key_data;
        /* Turn off autorepeating in case a break code has been lost */
        del_timer( &atakeyb_rep_timer );
        rep_scancode = 0;
-       if (IS_SYNC_CODE(scancode)) {
+       if (ikbd_self_test)
+           /* During self test, don't do resyncing, just process the code */
+           goto interpret_scancode;
+       else if (IS_SYNC_CODE(scancode)) {
            /* This code seem already to be the start of a new packet or a
             * single scancode */
            kb_state.state = KEYBOARD;
@@ -386,10 +399,47 @@ static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp)
                kb_state.buf[0] = scancode;
                break;
 
+             case 0xF1:
+               /* during self-test, note that 0xf1 received */
+               if (ikbd_self_test) {
+                   ++ikbd_self_test;
+                   self_test_last_rcv = jiffies;
+                   break;
+               }
+               /* FALL THROUGH */
+               
              default:
                break_flag = scancode & BREAK_MASK;
                scancode &= ~BREAK_MASK;
 
+               if (ikbd_self_test) {
+                   /* Scancodes sent during the self-test stand for broken
+                    * keys (keys being down). The code *should* be a break
+                    * code, but nevertheless some AT keyboard interfaces send
+                    * make codes instead. Therefore, simply ignore
+                    * break_flag...
+                    * */
+                   int keyval = ataplain_map[scancode], keytyp;
+                   
+                   set_bit( scancode, broken_keys );
+                   self_test_last_rcv = jiffies;
+                   keyval = ataplain_map[scancode];
+                   keytyp = KTYP(keyval) - 0xf0;
+                   keyval = KVAL(keyval);
+                   
+                   printk( KERN_WARNING "Key with scancode %d ", scancode );
+                   if (keytyp == KT_LATIN || keytyp == KT_LETTER) {
+                       if (keyval < ' ')
+                           printk( "('^%c') ", keyval + '@' );
+                       else
+                           printk( "('%c') ", keyval );
+                   }
+                   printk( "is broken -- will be ignored.\n" );
+                   break;
+               }
+               else if (test_bit( scancode, broken_keys ))
+                   break;
+               
                if (break_flag) {
                    del_timer( &atakeyb_rep_timer );
                    rep_scancode = 0;
@@ -815,7 +865,18 @@ int atari_keyb_init(void)
     mfp.active_edge &= ~0x10;
     atari_turnon_irq(IRQ_MFP_ACIA);
 
+    ikbd_self_test = 1;
     ikbd_reset();
+    /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
+     * self-test is finished */
+    self_test_last_rcv = jiffies;
+    while( jiffies < self_test_last_rcv + HZ/4 )
+       barrier();
+    /* if not incremented: no 0xf1 received */
+    if (ikbd_self_test == 1)
+       printk( KERN_ERR "WARNING: keyboard self test failed!\n" );
+    ikbd_self_test = 0;
+    
     ikbd_mouse_disable();
     ikbd_joystick_disable();
 
index ee6c474bba6cf1d610bc768e42d6ea8cb22c5b83..c2a9da86ef696025d534f71ee28cdea4602bde29 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/module.h>
 #include <asm/ptrace.h>
 #include <asm/traps.h>
@@ -8,11 +9,12 @@
 #include <asm/atari_stdma.h>
 
 extern void atari_microwire_cmd( int cmd );
-
+extern int atari_SCC_reset_done;
 
 EXPORT_SYMBOL(atari_mch_cookie);
 EXPORT_SYMBOL(atari_hw_present);
 EXPORT_SYMBOL(is_medusa);
+EXPORT_SYMBOL(is_hades);
 EXPORT_SYMBOL(atari_register_vme_int);
 EXPORT_SYMBOL(atari_unregister_vme_int);
 EXPORT_SYMBOL(stdma_lock);
@@ -23,7 +25,7 @@ EXPORT_SYMBOL(stdma_islocked);
 EXPORT_SYMBOL(atari_mouse_buttons);
 EXPORT_SYMBOL(atari_mouse_interrupt_hook);
 EXPORT_SYMBOL(atari_MIDI_interrupt_hook);
-EXPORT_SYMBOL(atari_mch_cookie);
+EXPORT_SYMBOL(atari_SCC_reset_done);
 EXPORT_SYMBOL(ikbd_write);
 EXPORT_SYMBOL(ikbd_mouse_y0_top);
 EXPORT_SYMBOL(ikbd_mouse_thresh);
index 97a874a37b95af7967e9d5312498aa493776d19a..0d0607da05ce7e587d86e4ac0b6ad9ef4e9d1179 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/machdep.h>
 
+#ifdef CONFIG_KGDB
+#include <asm/kgdb.h>
+#endif
+
 u_long atari_mch_cookie;
 struct atari_hw_present atari_hw_present;
 
+extern char m68k_debug_device[];
+
 static void atari_sched_init(void (*)(int, void *, struct pt_regs *));
 /* atari specific keyboard functions */
 extern int atari_keyb_init(void);
@@ -57,7 +63,7 @@ extern void atari_kbd_leds (unsigned int);
 extern void atari_init_IRQ (void);
 extern int atari_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                               unsigned long flags, const char *devname, void *dev_id);
-extern int atari_free_irq (unsigned int irq, void *dev_id);
+extern void atari_free_irq (unsigned int irq, void *dev_id);
 extern void atari_enable_irq (unsigned int);
 extern void atari_disable_irq (unsigned int);
 extern int atari_get_irq_list (char *buf);
@@ -77,12 +83,17 @@ static void atari_reset( void );
 extern int atari_floppy_init (void);
 extern void atari_floppy_setup(char *, int *);
 #endif
-static void atari_waitbut (void);
 extern struct consw fb_con;
 extern struct fb_info *atari_fb_init(long *);
-static void atari_debug_init (void);
+static void atari_debug_init(void);
 extern void atari_video_setup(char *, int *);
-extern void atari_syms_export(void);
+
+static struct console atari_console_driver;
+
+/* Can be set somewhere, if a SCC master reset has already be done and should
+ * not be repeated; used by kgdb */
+int atari_SCC_reset_done = 0;
+
 
 extern void (*kd_mksound)(unsigned int, unsigned int);
 
@@ -240,6 +251,8 @@ void config_atari(void)
 {
     memset(&atari_hw_present, 0, sizeof(atari_hw_present));
 
+    atari_debug_init();
+
     mach_sched_init      = atari_sched_init;
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
@@ -247,25 +260,21 @@ void config_atari(void)
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
     mach_free_irq        = atari_free_irq;
-    mach_enable_irq      = atari_enable_irq;
-    mach_disable_irq     = atari_disable_irq;
+    enable_irq           = atari_enable_irq;
+    disable_irq          = atari_disable_irq;
     mach_get_model      = atari_get_model;
     mach_get_hardware_list = atari_get_hardware_list;
     mach_get_irq_list   = atari_get_irq_list;
     mach_gettimeoffset   = atari_gettimeoffset;
-    mach_mksound         = atari_mksound;
     mach_reset           = atari_reset;
 #ifdef CONFIG_BLK_DEV_FD
     mach_floppy_init    = atari_floppy_init;
     mach_floppy_setup   = atari_floppy_setup;
 #endif
     conswitchp          = &fb_con;
-    waitbut             = atari_waitbut;
     mach_fb_init         = atari_fb_init;
     mach_max_dma_address = 0xffffff;
-    mach_debug_init     = atari_debug_init;
     mach_video_setup    = atari_video_setup;
-    mach_syms_export     = atari_syms_export;
     kd_mksound          = atari_mksound;
 
     /* ++bjoern: 
@@ -273,7 +282,7 @@ void config_atari(void)
      */
 
     printk( "Atari hardware found: " );
-    if (is_medusa) {
+    if (is_medusa || is_hades) {
         /* There's no Atari video hardware on the Medusa, but all the
          * addresses below generate a DTACK so no bus error occurs! */
     }
@@ -315,7 +324,7 @@ void config_atari(void)
        ATARIHW_SET(SCSI_DMA);
         printk( "TT_SCSI_DMA " );
     }
-    if (hwreg_present( &st_dma.dma_hi )) {
+    if (!is_hades && hwreg_present( &st_dma.dma_hi )) {
        ATARIHW_SET(STND_DMA);
         printk( "STND_DMA " );
     }
@@ -337,21 +346,25 @@ void config_atari(void)
        ATARIHW_SET(YM_2149);
         printk( "YM2149 " );
     }
-    if (!is_medusa && hwreg_present( &tt_dmasnd.ctrl )) {
+    if (!is_medusa && !is_hades && hwreg_present( &tt_dmasnd.ctrl )) {
        ATARIHW_SET(PCM_8BIT);
         printk( "PCM " );
     }
-    if (hwreg_present( (void *)(0xffff8940) )) {
+    if (!is_hades && hwreg_present( &codec.unused5 )) {
        ATARIHW_SET(CODEC);
         printk( "CODEC " );
     }
+    if (hwreg_present( &dsp56k_host_interface.icr )) {
+       ATARIHW_SET(DSP56K);
+        printk( "DSP56K " );
+    }
     if (hwreg_present( &tt_scc_dma.dma_ctrl ) &&
 #if 0
        /* This test sucks! Who knows some better? */
        (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) &&
        (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0)
 #else
-       !is_medusa
+       !is_medusa && !is_hades
 #endif
        ) {
        ATARIHW_SET(SCC_DMA);
@@ -365,7 +378,12 @@ void config_atari(void)
        ATARIHW_SET( ST_ESCC );
        printk( "ST_ESCC " );
     }
-    if (hwreg_present( &tt_scu.sys_mask )) {
+    if (is_hades)
+    {
+        ATARIHW_SET( VME );
+        printk( "VME " );
+    }
+    else if (hwreg_present( &tt_scu.sys_mask )) {
        ATARIHW_SET(SCU);
        /* Assume a VME bus if there's a SCU */
        ATARIHW_SET( VME );
@@ -375,7 +393,7 @@ void config_atari(void)
        ATARIHW_SET(ANALOG_JOY);
         printk( "ANALOG_JOY " );
     }
-    if (hwreg_present( blitter.halftone )) {
+    if (!is_hades && hwreg_present( blitter.halftone )) {
        ATARIHW_SET(BLITTER);
         printk( "BLITTER " );
     }
@@ -384,7 +402,7 @@ void config_atari(void)
         printk( "IDE " );
     }
 #if 1 /* This maybe wrong */
-    if (!is_medusa &&
+    if (!is_medusa && !is_hades &&
        hwreg_present( &tt_microwire.data ) &&
        hwreg_present( &tt_microwire.mask ) &&
        (tt_microwire.mask = 0x7ff,
@@ -402,20 +420,20 @@ void config_atari(void)
         mach_hwclk = atari_hwclk;
         mach_set_clock_mmss = atari_set_clock_mmss;
     }
-    if (hwreg_present( &mste_rtc.sec_ones)) {
+    if (!is_hades && hwreg_present( &mste_rtc.sec_ones)) {
        ATARIHW_SET(MSTE_CLK);
         printk( "MSTE_CLK ");
         mach_gettod = atari_mste_gettod;
         mach_hwclk = atari_mste_hwclk;
         mach_set_clock_mmss = atari_mste_set_clock_mmss;
     }
-    if (!is_medusa &&
+    if (!is_medusa && !is_hades &&
        hwreg_present( &dma_wd.fdc_speed ) &&
        hwreg_write( &dma_wd.fdc_speed, 0 )) {
            ATARIHW_SET(FDCSPEED);
            printk( "FDC_SPEED ");
     }
-    if (!ATARIHW_PRESENT(ST_SCSI)) {
+    if (!is_hades && !ATARIHW_PRESENT(ST_SCSI)) {
        ATARIHW_SET(ACSI);
         printk( "ACSI " );
     }
@@ -426,9 +444,11 @@ void config_atari(void)
          * translation (the one that must not be turned off in
          * head.S...)
          */
-        __asm__ volatile ("moveq #0,%/d0;"
-                          ".long 0x4e7b0004;"  /* movec d0,itt0 */
-                          ".long 0x4e7b0006;"  /* movec d0,dtt0 */
+        __asm__ volatile ("moveq #0,%/d0\n\t"
+                          ".chip 68040\n\t"
+                         "movec %%d0,%%itt0\n\t"
+                         "movec %%d0,%%dtt0\n\t"
+                         ".chip 68k"
                                                  : /* no outputs */
                                                  : /* no inputs */
                                                  : "d0");
@@ -452,13 +472,18 @@ void config_atari(void)
         tt1_val = 0xfe008543;  /* Translate 0xfexxxxxx, enable, cache
                                  * inhibit, read and write, FDC mask = 3,
                                  * FDC val = 4 -> Supervisor only */
-        __asm__ __volatile__ ( "pmove  %0@,%/tt1" : : "a" (&tt1_val) );
+        __asm__ __volatile__ ( ".chip 68030\n\t"
+                               "pmove  %0@,%/tt1\n\t"
+                               ".chip 68k"
+                               : : "a" (&tt1_val) );
     }
     else {
         __asm__ __volatile__
             ( "movel %0,%/d0\n\t"
-              ".long 0x4e7b0005\n\t"   /* movec d0,itt1 */
-              ".long 0x4e7b0007"       /* movec d0,dtt1 */
+             ".chip 68040\n\t"
+             "movec %%d0,%%itt1\n\t"
+             "movec %%d0,%%dtt1\n\t"
+             ".chip 68k"
               :
               : "g" (0xfe00a040)       /* Translate 0xfexxxxxx, enable,
                                          * supervisor only, non-cacheable/
@@ -621,7 +646,7 @@ static void atari_gettod (int *yearp, int *monp, int *dayp,
        we use the fact that in head.S we have set up a mapping
        0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
        in the last 16MB of the address space. */
-    tos_version = is_medusa ? 0xfff : *(unsigned short *)0xFF000002;
+    tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xFF000002;
     *yearp += (tos_version < 0x306) ? 70 : 68;
 }
 
@@ -696,7 +721,7 @@ static int atari_hwclk( int op, struct hwclk_time *t )
 
     /* Tos version at Physical 2.  See above for explanation why we
        cannot use PTOV(2).  */
-    tos_version = is_medusa ? 0xfff : *(unsigned short *)0xff000002;
+    tos_version = (is_medusa || is_hades) ? 0xfff : *(unsigned short *)0xff000002;
 
     ctrl = RTC_READ(RTC_CONTROL); /* control registers are
                                    * independent from the UIP */
@@ -875,13 +900,6 @@ static int atari_set_clock_mmss (unsigned long nowtime)
     return retval;
 }
 
-
-static void atari_waitbut (void)
-{
-    /* sorry, no-op */
-}
-
-
 static inline void ata_mfp_out (char c)
 {
     while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */
@@ -889,12 +907,12 @@ static inline void ata_mfp_out (char c)
     mfp.usart_dta = c;
 }
 
-void ata_mfp_print (const char *str)
+static void atari_mfp_console_write (const char *str, unsigned int count)
 {
-    for( ; *str; ++str ) {
+    while (count--) {
        if (*str == '\n')
            ata_mfp_out( '\r' );
-       ata_mfp_out( *str );
+       ata_mfp_out( *str++ );
     }
 }
 
@@ -907,12 +925,12 @@ static inline void ata_scc_out (char c)
     scc.cha_b_data = c;
 }
 
-void ata_scc_print (const char *str)
+static void atari_scc_console_write (const char *str, unsigned int count)
 {
-    for( ; *str; ++str ) {
+    while (count--) {
        if (*str == '\n')
            ata_scc_out( '\r' );
-       ata_scc_out( *str );
+       ata_scc_out( *str++ );
     }
 }
 
@@ -937,20 +955,20 @@ static int ata_par_out (char c)
     return( 1 );
 }
 
-void ata_par_print (const char *str)
+static void atari_par_console_write (const char *str, unsigned int count)
 {
     static int printer_present = 1;
 
     if (!printer_present)
        return;
 
-    for( ; *str; ++str ) {
+    while (count--) {
        if (*str == '\n')
            if (!ata_par_out( '\r' )) {
                printer_present = 0;
                return;
            }
-       if (!ata_par_out( *str )) {
+       if (!ata_par_out( *str++ )) {
            printer_present = 0;
            return;
        }
@@ -958,11 +976,14 @@ void ata_par_print (const char *str)
 }
 
 
-static void atari_debug_init( void )
+static void atari_debug_init(void)
 {
-    extern void (*debug_print_proc)(const char *);
-    extern char m68k_debug_device[];
-    
+#ifdef CONFIG_KGDB
+       /* if the m68k_debug_device is used by the GDB stub, do nothing here */
+       if (kgdb_initialized)
+               return(NULL);
+#endif
+
     if (!strcmp( m68k_debug_device, "ser" )) {
        /* defaults to ser2 for a Falcon and ser1 otherwise */
        strcpy( m68k_debug_device, 
@@ -979,7 +1000,7 @@ static void atari_debug_init( void )
        mfp.tim_dt_d   = 2;     /* 9600 bps */
        mfp.tim_ct_cd |= 0x01;  /* start timer D, 1:4 */
        mfp.trn_stat  |= 0x01;  /* enable TX */
-       debug_print_proc = ata_mfp_print;
+       atari_console_driver.write = atari_mfp_console_write;
     }
     else if (!strcmp( m68k_debug_device, "ser2" )) {
        /* SCC Modem2 serial port */
@@ -1005,7 +1026,7 @@ static void atari_debug_init( void )
            scc.cha_b_ctrl = *p++;
            MFPDELAY();
        }
-       debug_print_proc = ata_scc_print;
+       atari_console_driver.write = atari_scc_console_write;
     }
     else if (!strcmp( m68k_debug_device, "par" )) {
        /* parallel printer */
@@ -1016,29 +1037,10 @@ static void atari_debug_init( void )
        sound_ym.wd_data = 0;          /* no char */
        sound_ym.rd_data_reg_sel = 14; /* select port A */
        sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */
-       debug_print_proc = ata_par_print;
-    }
-    else
-       debug_print_proc = NULL;
-}
-
-
-void ata_serial_print (const char *str)
-{
-  int c;
-
-  while (c = *str++, c != 0)
-    {
-      if (c == '\n')
-       {
-         while (!(mfp.trn_stat & (1 << 7)))
-           barrier ();
-         mfp.usart_dta = '\r';
-       }
-      while (!(mfp.trn_stat & (1 << 7)))
-       barrier ();
-      mfp.usart_dta = c;
+       atari_console_driver.write = atari_par_console_write;
     }
+    if (atari_console_driver.write)
+       register_console(&atari_console_driver);
 }
 
 /* ++roman:
@@ -1079,7 +1081,8 @@ static void atari_reset (void)
 
     /* On the Medusa, phys. 0x4 may contain garbage because it's no
        ROM.  See above for explanation why we cannot use PTOV(4). */
-    reset_addr = is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004;
+    reset_addr = is_hades ? 0x7fe00030 :
+                 (is_medusa ? 0xe00030 : *(unsigned long *) 0xff000004);
 
     acia.key_ctrl = ACIA_RESET;             /* reset ACIA for switch off OverScan, if it's active */
 
@@ -1159,6 +1162,8 @@ static void atari_get_model(char *model)
            if (is_medusa)
                /* Medusa has TT _MCH cookie */
                strcat (model, "Medusa");
+           else if (is_hades)
+               strcat(model, "Hades");
            else
                strcat (model, "TT");
            break;
@@ -1215,6 +1220,7 @@ static int atari_get_hardware_list(char *buffer)
     ATARIHW_ANNOUNCE(SCU, "System Control Unit");
     ATARIHW_ANNOUNCE(BLITTER, "Blitter");
     ATARIHW_ANNOUNCE(VME, "VME Bus");
+    ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
 
     return(len);
 }
index fa02949fa78938c7bee80daf70daa8e5154027b1..de6014171906d52c38f2b5d409ce687c977a113a 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/major.h>
+#include <linux/poll.h>
 
 #include <asm/atarikb.h>
 #include <asm/atari_joystick.h>
@@ -90,30 +91,28 @@ static long read_joystick(struct inode *inode, struct file *file,
                          char *buffer, unsigned long count)
 {
     int minor = DEVICE_NR(inode->i_rdev);
-    int i;
 
     if (count < 2)
        return -EINVAL;
     if (!joystick[minor].ready)
        return -EAGAIN;
-    put_user(joystick[minor].fire, buffer++);
-    put_user(joystick[minor].dir, buffer++);
-    for (i = 0; i < count; i++)
-       put_user(0, buffer++);
     joystick[minor].ready = 0;
-
-    return i;
+    if (put_user(joystick[minor].fire, buffer++) ||
+       put_user(joystick[minor].dir, buffer++))
+       return -EFAULT;
+    if (count > 2)
+       if (clear_user(buffer, count - 2))
+           return -EFAULT;
+    return count;
 }
 
-static int joystick_select(struct inode *inode, struct file *file, int sel_type, select_table *wait)
+static unsigned int joystick_poll(struct file *file, poll_table *wait)
 {
-    int minor = DEVICE_NR(inode->i_rdev);
+    int minor = DEVICE_NR(file->f_inode->i_rdev);
 
-    if (sel_type != SEL_IN)
-       return 0;
+    poll_wait(&joystick[minor].wait, wait);
     if (joystick[minor].ready)
-       return 1;
-    select_wait(&joystick[minor].wait, wait);
+       return POLLIN | POLLRDNORM;
     return 0;
 }
 
@@ -122,7 +121,7 @@ struct file_operations atari_joystick_fops = {
        read_joystick,
        write_joystick,
        NULL,           /* joystick_readdir */
-       joystick_select,
+       joystick_poll,
        NULL,           /* joystick_ioctl */
        NULL,           /* joystick_mmap */
        open_joystick,
@@ -135,7 +134,7 @@ int atari_joystick_init(void)
     joystick[0].ready = joystick[1].ready = 0;
     joystick[0].wait = joystick[1].wait = NULL;
 
-    if (register_chrdev(MAJOR_NR, "joystick", &atari_joystick_fops))
+    if (register_chrdev(MAJOR_NR, "Joystick", &atari_joystick_fops))
        printk("unable to get major %d for joystick devices\n", MAJOR_NR);
 
     return 0;
index e67a9c4d1f720800a07a1f3f5742f643e1c439c4..822030ebb6b0a2d65a71dc5e8ddaed797e1e8e6a 100644 (file)
@@ -8,14 +8,16 @@
 ifdef CONFIG_AMIGA
 AMIGA_BOOTSTRAP = amiga_bootstrap
 AMIGA_BOOTOBJS := amiga/bootstrap.o amiga/linuxboot.o
-AMIGA_HOSTCC = m68k-cbm-amigados-gcc -I$(TOPDIR)/include
+AMIGA_HOSTCC = m68k-cbm-amigados-gcc
+AMIGA_HOSTINC = -I$(TOPDIR)/include
 AMIGA_HOSTFLAGS=-m68030 -O2 -Wall -Dlinux
 endif
 
 ifdef CONFIG_ATARI
 ATARI_BOOTSTRAP = atari_bootstrap
 ATARI_BOOTOBJS := atari/bootstrap.o
-ATARI_HOSTCC = m68k-mint-gcc -I$(TOPDIR)/include
+ATARI_HOSTCC = m68k-mint-gcc
+ATARI_HOSTINC = -I$(TOPDIR)/include
 ATARI_HOSTFLAGS = -m68030 -m68881 -Dlinux -O2 -Wall
 
 # BOOTP/TFTP support in bootstrap?
@@ -36,27 +38,28 @@ endif
 
 ifdef CONFIG_ATARI
 atari_bootstrap: $(ATARI_BOOTOBJS)
-       $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS)
+       $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -o $@ $(ATARI_BOOTOBJS)
        rm -f ../../../bootstrap
        ln $@ ../../../bootstrap
 endif
 
 ifdef CONFIG_AMIGA
 amiga_bootstrap: $(AMIGA_BOOTOBJS)
-       $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS)
+       $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -o $@ -s -noixemul $(AMIGA_BOOTOBJS)
        rm -f ../../../bootstrap
        ln $@ ../../../bootstrap
 endif
 
 $(AMIGA_BOOTOBJS): %.o: %.c
-       $(AMIGA_HOSTCC) $(AMIGA_HOSTFLAGS) -c $< -o $@
+       $(AMIGA_HOSTCC) $(AMIGA_HOSTINC) $(AMIGA_HOSTFLAGS) -c $< -o $@
 
 $(ATARI_BOOTOBJS): %.o: %.c
-       $(ATARI_HOSTCC) $(ATARI_HOSTFLAGS) -c $< -o $@
+       $(ATARI_HOSTCC) $(ATARI_HOSTINC) $(ATARI_HOSTFLAGS) -c $< -o $@
 
 bootstrap: $(AMIGA_BOOTSTRAP) $(ATARI_BOOTSTRAP)
 
 clean:
-       rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap
+       rm -f *.o amiga/*.o atari/*.o amiga_bootstrap atari_bootstrap \
+          ../../../bootstrap
 
 dep:
index df751f4d22d3b56cc66567c3ef2274560f4dd19f..b109466ed06f95e7d9446d7b380a5527864251a7 100644 (file)
@@ -51,9 +51,8 @@
 
 
 /* Library Bases */
+long __oslibversion = 36;
 extern const struct ExecBase *SysBase;
-const struct ExpansionBase *ExpansionBase;
-const struct GfxBase *GfxBase;
 
 static const char *memfile_name = NULL;
 
@@ -80,24 +79,25 @@ static int Read(int fd, char *buf, int count);
 static void Close(int fd);
 static int FileSize(const char *path);
 static void Sleep(u_long micros);
-static int ModifyBootinfo(struct amiga_bootinfo *bi);
 
 
 static void Usage(void)
 {
     fprintf(stderr,
-           "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n"
-           "Usage: %s [options] [kernel command line]\n\n"
-           "Valid options are:\n"
-           "    -h, --help           Display this usage information\n"
-           "    -k, --kernel file    Use kernel image `file' (default is `vmlinux')\n"
-           "    -r, --ramdisk file   Use ramdisk image `file'\n"
-           "    -d, --debug          Enable debug mode\n"
-           "    -b, --baud speed     Set the serial port speed (default is 9600)\n"
-           "    -m, --memfile file   Use memory file `file'\n"
-           "    -v, --keep-video     Don't reset the video mode\n"
-           "    -t, --model id       Set the Amiga model to `id'\n\n",
-           ProgramName);
+       "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n"
+       "Usage: %s [options] [kernel command line]\n\n"
+       "Basic options:\n"
+       "    -h, --help           Display this usage information\n"
+       "    -k, --kernel file    Use kernel image `file' (default is `vmlinux')\n"
+       "    -r, --ramdisk file   Use ramdisk image `file'\n"
+       "Advanced options:\n"
+       "    -d, --debug          Enable debug mode\n"
+       "    -b, --baud speed     Set the serial port speed (default is 9600)\n"
+       "    -m, --memfile file   Use memory file `file'\n"
+       "    -v, --keep-video     Don't reset the video mode\n"
+       "    -t, --model id       Set the Amiga model to `id'\n"
+       "    -p, --processor cfm  Set the processor type to `cfm\n\n",
+       ProgramName);
     exit(EXIT_FAILURE);
 }
 
@@ -105,7 +105,7 @@ static void Usage(void)
 int main(int argc, char *argv[])
 {
     int i;
-    int debugflag = 0, keep_video = 0;
+    int processor = 0, debugflag = 0, keep_video = 0;
     u_int baud = 0;
     const char *kernel_name = NULL;
     const char *ramdisk_name = NULL;
@@ -117,17 +117,17 @@ int main(int argc, char *argv[])
        if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help"))
            Usage();
        else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel"))
-            if (--argc && !kernel_name) {
-                kernel_name = argv[1];
-                argv++;
-            } else
-                Usage();
+           if (--argc && !kernel_name) {
+               kernel_name = argv[1];
+               argv++;
+           } else
+               Usage();
        else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk"))
-            if (--argc && !ramdisk_name) {
-                ramdisk_name = argv[1];
-                argv++;
-            } else
-                Usage();
+           if (--argc && !ramdisk_name) {
+               ramdisk_name = argv[1];
+               argv++;
+           } else
+               Usage();
        else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug"))
            debugflag = 1;
        else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud"))
@@ -137,19 +137,25 @@ int main(int argc, char *argv[])
            } else
                Usage();
        else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile"))
-            if (--argc && !memfile_name) {
-                memfile_name = argv[1];
-                argv++;
-            } else
-                Usage();
+           if (--argc && !memfile_name) {
+               memfile_name = argv[1];
+               argv++;
+           } else
+               Usage();
        else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video"))
            keep_video = 1;
        else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model"))
-            if (--argc && !model) {
-                model = atoi(argv[1]);
-                argv++;
-            } else
-                Usage();
+           if (--argc && !model) {
+               model = atoi(argv[1]);
+               argv++;
+           } else
+               Usage();
+       else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor"))
+           if (--argc && !processor) {
+               processor = atoi(argv[1]);
+               argv++;
+           } else
+               Usage();
        else
            break;
     }
@@ -158,22 +164,6 @@ int main(int argc, char *argv[])
 
     SysBase = *(struct ExecBase **)4;
 
-    /* open Expansion Library */
-    ExpansionBase = (struct ExpansionBase *)OpenLibrary("expansion.library",
-                                                       36);
-    if (!ExpansionBase) {
-       fputs("Unable to open expansion.library V36 or greater!  Aborting...\n",
-             stderr);
-       exit(EXIT_FAILURE);
-   }
-
-    /* open Graphics Library */
-    GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0);
-    if (!GfxBase) {
-       fputs("Unable to open graphics.library!  Aborting...\n", stderr);
-       exit(EXIT_FAILURE);
-    }
-
     /*
      * Join command line options
      */
@@ -187,9 +177,52 @@ int main(int argc, char *argv[])
        }
     }
 
+    memset(&args.bi, 0, sizeof(args.bi));
+    if (processor) {
+       int cpu = processor/100%10;
+       int fpu = processor/10%10;
+       int mmu = processor%10;
+       if (cpu)
+           args.bi.cputype = 1<<(cpu-1);
+       if (fpu)
+           args.bi.fputype = 1<<(fpu-1);
+       if (mmu)
+           args.bi.mmutype = 1<<(mmu-1);
+    }
+    /*
+     * If we have a memory file, read the memory information from it
+     */
+    if (memfile_name) {
+       FILE *fp;
+       int i;
+
+       if ((fp = fopen(memfile_name, "r")) == NULL) {
+           perror("open memory file");
+           fprintf(stderr, "Cannot open memory file %s\n", memfile_name);
+           return(FALSE);
+       }
+
+       if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) {
+           fprintf(stderr, "memory file does not contain chip memory size\n");
+           fclose(fp);
+           return(FALSE);
+       }
+
+       for (i = 0; i < NUM_MEMINFO; i++)
+           if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr,
+                      &args.bi.memory[i].size) != 2)
+               break;
+
+       fclose(fp);
+       args.bi.num_memory = i;
+    }
+    strncpy(args.bi.command_line, commandline, CL_SIZE);
+    args.bi.command_line[CL_SIZE-1] = '\0';
+    if (model != AMI_UNKNOWN)
+       args.bi.model = model;
+
     args.kernelname = kernel_name;
     args.ramdiskname = ramdisk_name;
-    args.commandline = commandline;
     args.debugflag = debugflag;
     args.keep_video = keep_video;
     args.reset_boards = 1;
@@ -204,14 +237,10 @@ int main(int argc, char *argv[])
     args.close = Close;
     args.filesize = FileSize;
     args.sleep = Sleep;
-    args.modify_bootinfo = ModifyBootinfo;
 
     /* Do The Right Stuff */
     linuxboot(&args);
 
-    CloseLibrary((struct Library *)GfxBase);
-    CloseLibrary((struct Library *)ExpansionBase);
-
     /* if we ever get here, something went wrong */
     exit(EXIT_FAILURE);
 }
@@ -224,6 +253,7 @@ int main(int argc, char *argv[])
 static void Puts(const char *str)
 {
     fputs(str, stderr);
+    fflush(stderr);
 }
 
 static long GetChar(void)
@@ -234,6 +264,7 @@ static long GetChar(void)
 static void PutChar(char c)
 {
     fputc(c, stderr);
+    fflush(stderr);
 }
 
 static void Printf(const char *fmt, ...)
@@ -243,6 +274,7 @@ static void Printf(const char *fmt, ...)
     va_start(args, fmt);
     vfprintf(stderr, fmt, args);
     va_end(args);
+    fflush(stderr);
 }
 
 static int Open(const char *path)
@@ -271,8 +303,8 @@ static int FileSize(const char *path)
     int fd, size = -1;
 
     if ((fd = open(path, O_RDONLY)) != -1) {
-        size = lseek(fd, 0, SEEK_END);
-        close(fd);
+       size = lseek(fd, 0, SEEK_END);
+       close(fd);
     }
     return(size);
 }
@@ -299,46 +331,3 @@ static void Sleep(u_long micros)
        DeleteMsgPort(TimerPort);
     }
 }
-
-
-static int ModifyBootinfo(struct amiga_bootinfo *bi)
-{
-   /*
-    * if we have a memory file, read the memory information from it
-    */
-   if (memfile_name) {
-      FILE *fp;
-      int i;
-
-      if ((fp = fopen(memfile_name, "r")) == NULL) {
-         perror("open memory file");
-         fprintf(stderr, "Cannot open memory file %s\n", memfile_name);
-         return(FALSE);
-      }
-
-      if (fscanf(fp, "%lu", &bi->chip_size) != 1) {
-         fprintf(stderr, "memory file does not contain chip memory size\n");
-         fclose(fp);
-         return(FALSE);
-      }
-                
-      for (i = 0; i < NUM_MEMINFO; i++) {
-         if (fscanf(fp, "%lx %lu", &bi->memory[i].addr, &bi->memory[i].size)
-            != 2)
-            break;
-      }
-
-      fclose(fp);
-
-      if (i != bi->num_memory && i > 0)
-         bi->num_memory = i;
-   }
-
-   /*
-    * change the Amiga model, if necessary
-    */
-   if (model != AMI_UNKNOWN)
-      bi->model = model;
-
-   return(TRUE);
-}
index 45f6fccb04ef503cf69f272788c7419e544e3246..4d072cc759b2b86a68dd10179f745ffa43fdd0d8 100644 (file)
@@ -59,30 +59,6 @@ struct Library;
 struct IORequest;
 
 
-static __inline void CloseLibrary(struct Library *library)
-{
-    register const struct ExecBase *a6 __asm("a6") = SysBase;
-    register struct Library *a1 __asm("a1") = library;
-    __asm __volatile ("jsr a6@(-0x19e)"
-                     : /* no output */
-                     : "r" (a6), "r" (a1)
-                     : "a0","a1","d0","d1", "memory");
-}
-
-static __inline struct Library *OpenLibrary(char *libName,
-                                           unsigned long version)
-{
-    register struct Library * _res  __asm("d0");
-    register const struct ExecBase *a6 __asm("a6") = SysBase;
-    register u_char *a1 __asm("a1") = libName;
-    register unsigned long d0 __asm("d0") = version;
-    __asm __volatile ("jsr a6@(-0x228)"
-                     : "=r" (_res)
-                     : "r" (a6), "r" (a1), "r" (d0)
-                     : "a0","a1","d0","d1", "memory");
-    return _res;
-}
-
 static __inline char OpenDevice(u_char *devName, u_long unit,
                                struct IORequest *ioRequest, u_long flags)
 {
index b7aff74a8b5a4da1ab83acdbc42020dc43732335..d35966686fbd7cf9edac877983cea352a37fd8a5 100644 (file)
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of this archive
  *  for more details.
+ *
+ *  History:
+ *     03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
+ *                 code for ataboot)
+ *     30 Dec 1996 Reverted the CPU detection to the old scheme
+ *                 New boot parameter override scheme (Geert)
+ *      27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert)
+ *       9 Sep 1996 Rewritten option parsing
+ *                 New parameter passing to linuxboot() (linuxboot_args)
+ *                 (Geert)
+ *     18 Aug 1996 Updated for the new boot information structure (Geert)
+ *     10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch]
+ *                 (Geert)
+ *     11 Jul 1995 Support for ELF kernel (untested!) (Andreas)
+ *      7 Mar 1995 Memory block sizes are rounded to a multiple of 256K
+ *                 instead of 1M (Geert)
+ *     31 May 1994 Memory thrash problem solved (Geert)
+ *     11 May 1994 A3640 MapROM check (Geert)
  */
 
 
@@ -29,6 +47,8 @@
 
 
 #define BOOTINFO_COMPAT_1_0    /* bootinfo interface version 1.0 compatible */
+/* support compressed kernels? */
+#define ZKERNEL
 
 #include <stddef.h>
 #include <string.h>
@@ -60,7 +80,7 @@ static Elf32_Ehdr kexec_elf;
 static const struct linuxboot_args *linuxboot_args;
 
 /* Bootinfo */
-static struct amiga_bootinfo bi;
+struct amiga_bootinfo bi;
 
 #ifdef BOOTINFO_COMPAT_1_0
 static struct compat_bootinfo compat_bootinfo;
@@ -75,7 +95,6 @@ static union {
 
 #define kernelname     linuxboot_args->kernelname
 #define ramdiskname    linuxboot_args->ramdiskname
-#define commandline    linuxboot_args->commandline
 #define debugflag      linuxboot_args->debugflag
 #define keep_video     linuxboot_args->keep_video
 #define reset_boards   linuxboot_args->reset_boards
@@ -91,8 +110,6 @@ static union {
 #define Close          linuxboot_args->close
 #define FileSize       linuxboot_args->filesize
 #define Sleep          linuxboot_args->sleep
-#define ModifyBootinfo linuxboot_args->modify_bootinfo
-
 
     /*
      *  Function Prototypes
@@ -115,6 +132,16 @@ static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
                         u_long kernel_size) __attribute__ ((noreturn));
 asmlinkage u_long maprommed(void);
 asmlinkage u_long check346(void);
+#ifdef ZKERNEL
+static int load_zkernel(int fd);
+static int KRead(int fd, void *buf, int cnt);
+static int KSeek(int fd, int offset);
+static int KClose(int fd);
+#else
+#define KRead          Read
+#define KSeek          Seek
+#define KClose         Close
+#endif
 
 
     /*
@@ -174,7 +201,7 @@ const u_long last_amiga_model = AMI_DRACO;
 
 u_long linuxboot(const struct linuxboot_args *args)
 {
-    int kfd = -1, rfd = -1, elf_kernel = 0;
+    int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip;
     int i, j;
     const struct MemHeader *mnp;
     struct ConfigDev *cdp = NULL;
@@ -196,38 +223,42 @@ u_long linuxboot(const struct linuxboot_args *args)
     Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n");
     Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n");
 
-    memset(&bi, 0, sizeof(bi));
+    /* Note: Initial values in bi override detected values */
+    bi = args->bi;
 
     /* machine is Amiga */
     bi.machtype = MACH_AMIGA;
 
     /* determine chipset */
-    bi.chipset = get_chipset();
+    if (!bi.chipset)
+       bi.chipset = get_chipset();
 
     /* determine CPU, FPU and MMU type */
-    get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
+    if (!bi.cputype)
+       get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
 
     /* determine Amiga model */
-    bi.model = get_model(bi.chipset);
+    if (!bi.model)
+       bi.model = get_model(bi.chipset);
     model_mask = (bi.model != AMI_UNKNOWN) ? 1<<bi.model : 0;
 
     /* Memory & AutoConfig based on 'unix_boot.c' by C= */
 
     /* find all of the autoconfig boards in the system */
-    bi.num_autocon = 0;
-    for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++) {
-       if (bi.num_autocon < ZORRO_NUM_AUTO) {
-           /* copy the contents of each structure into our boot info */
-           memcpy(&bi.autocon[bi.num_autocon], cdp, sizeof(struct ConfigDev));
-           /* count this device */
-           bi.num_autocon++;
-       } else
-           Printf("Warning: too many AutoConfig devices. Ignoring device at "
-                  "0x%08lx\n", cdp->cd_BoardAddr);
-    }
-
+    if (!bi.num_autocon)
+       for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++)
+           if (bi.num_autocon < ZORRO_NUM_AUTO)
+               /* copy the contents of each structure into our boot info and
+                  count this device */
+               memcpy(&bi.autocon[bi.num_autocon++], cdp,
+                      sizeof(struct ConfigDev));
+           else
+               Printf("Warning: too many AutoConfig devices. Ignoring device at "
+                      "0x%08lx\n", cdp->cd_BoardAddr);
+
+    do_fast = bi.num_memory ? 0 : 1;
+    do_chip = bi.chip_size ? 0 : 1;
     /* find out the memory in the system */
-    bi.num_memory = 0;
     for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head;
         mnp->mh_Node.ln_Succ;
         mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) {
@@ -266,7 +297,7 @@ u_long linuxboot(const struct linuxboot_args *args)
        mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000);
 
        /* if fast memory */
-       if (mh.mh_Attributes & MEMF_FAST) {
+       if (do_fast && mh.mh_Attributes & MEMF_FAST) {
            /* set the size value to the size of this block and mask off to a
               256K increment */
            u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000;
@@ -279,30 +310,26 @@ u_long linuxboot(const struct linuxboot_args *args)
                    bi.num_memory++;
                } else
                    Printf("Warning: too many memory blocks. Ignoring block "
-                          "of %ldK at 0x%08x\n", size>>10,
+                          "of %ldK at 0x%08x\n", size>>10,
                           (u_long)mh.mh_Lower);
-       } else if (mh.mh_Attributes & MEMF_CHIP)
+       } else if (do_chip && mh.mh_Attributes & MEMF_CHIP)
            /* if CHIP memory, record the size */
            bi.chip_size = (u_long)mh.mh_Upper;
     }
 
     /* get info from ExecBase */
-    bi.vblank = SysBase->VBlankFrequency;
-    bi.psfreq = SysBase->PowerSupplyFrequency;
-    bi.eclock = SysBase->ex_EClockFrequency;
+    if (!bi.vblank)
+       bi.vblank = SysBase->VBlankFrequency;
+    if (!bi.psfreq)
+       bi.psfreq = SysBase->PowerSupplyFrequency;
+    if (!bi.eclock)
+       bi.eclock = SysBase->ex_EClockFrequency;
 
     /* serial port */
-    realbaud = baud ? baud : DEFAULT_BAUD;
-    bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
-
-    /* copy command line options into the kernel command line */
-    strncpy(bi.command_line, commandline, CL_SIZE);
-    bi.command_line[CL_SIZE-1] = '\0';
-
-
-    /* modify the bootinfo, e.g. to change the memory configuration */
-    if (ModifyBootinfo && !ModifyBootinfo(&bi))
-       goto Fail;
+    if (!bi.serper) {
+       realbaud = baud ? baud : DEFAULT_BAUD;
+       bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
+    }
 
     /* display Amiga model */
     if (bi.model >= first_amiga_model && bi.model <= last_amiga_model)
@@ -347,7 +374,7 @@ u_long linuxboot(const struct linuxboot_args *args)
     }
 
     /* display the chipset */
-    switch(bi.chipset) {
+    switch (bi.chipset) {
        case CS_STONEAGE:
            Puts(", old or unknown chipset");
            break;
@@ -457,11 +484,24 @@ u_long linuxboot(const struct linuxboot_args *args)
        Printf("Unable to open kernel file `%s'\n", kernelname);
        goto Fail;
     }
-    if (Read(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
+    if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
        Puts("Unable to read exec header from kernel file\n");
        goto Fail;
     }
 
+#ifdef ZKERNEL
+    if (((unsigned char *)&kexec)[0] == 037 &&
+       (((unsigned char *)&kexec)[1] == 0213 ||
+        ((unsigned char *)&kexec)[1] == 0236)) {
+       /* That's a compressed kernel */
+       Puts("Kernel is compressed\n");
+       if (load_zkernel(kfd)) {
+           Puts("Decompression error -- aborting\n");
+           goto Fail;
+       }
+    }
+#endif
+
     switch (N_MAGIC(kexec)) {
        case ZMAGIC:
            if (debugflag)
@@ -479,8 +519,8 @@ u_long linuxboot(const struct linuxboot_args *args)
 
        default:
            /* Try to parse it as an ELF header */
-           Seek(kfd, 0);
-           if ((Read(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) ==
+           KSeek(kfd, 0);
+           if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) ==
                 sizeof(kexec_elf)) &&
                 (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) {
                elf_kernel = 1;
@@ -501,8 +541,8 @@ u_long linuxboot(const struct linuxboot_args *args)
                    Puts("Unable to allocate memory for program headers\n");
                    goto Fail;
                }
-               Seek(kfd, kexec_elf.e_phoff);
-               if (Read(kfd, (void *)kernel_phdrs,
+               KSeek(kfd, kexec_elf.e_phoff);
+               if (KRead(kfd, (void *)kernel_phdrs,
                         kexec_elf.e_phnum*sizeof(*kernel_phdrs)) !=
                    kexec_elf.e_phnum*sizeof(*kernel_phdrs)) {
                    Puts("Unable to read program headers from kernel file\n");
@@ -557,32 +597,32 @@ u_long linuxboot(const struct linuxboot_args *args)
     /* read the text and data segments from the kernel image */
     if (elf_kernel)
        for (i = 0; i < kexec_elf.e_phnum; i++) {
-           if (Seek(kfd, kernel_phdrs[i].p_offset) == -1) {
+           if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) {
                Printf("Failed to seek to segment %ld\n", i);
                goto Fail;
            }
-           if (Read(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
-                    kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) {
+           if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
+                     kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) {
                Printf("Failed to read segment %ld\n", i);
                goto Fail;
            }
        }
     else {
-       if (Seek(kfd, text_offset) == -1) {
+       if (KSeek(kfd, text_offset) == -1) {
            Puts("Failed to seek to text\n");
            goto Fail;
        }
-       if (Read(kfd, memptr, kexec.a_text) != kexec.a_text) {
+       if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) {
            Puts("Failed to read text\n");
            goto Fail;
        }
        /* data follows immediately after text */
-       if (Read(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) {
+       if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) {
            Puts("Failed to read data\n");
            goto Fail;
        }
     }
-    Close(kfd);
+    KClose(kfd);
     kfd = -1;
 
     /* Check kernel's bootinfo version */
@@ -706,7 +746,7 @@ u_long linuxboot(const struct linuxboot_args *args)
     /* Clean up and exit in case of a failure */
 Fail:
     if (kfd != -1)
-       Close(kfd);
+       KClose(kfd);
     if (rfd != -1)
        Close(rfd);
     if (memptr)
@@ -748,37 +788,17 @@ static u_long get_chipset(void)
      * Determine the CPU Type
      */
 
-/* Dectection of 68030 and up is unreliable, so we check ourself */
-/* Keep consistent with asm/setup.h! */
-/* 24.11.1996 Joerg Dorchain */
-asm( ".text\n"
-ALIGN_STR "\n"
-SYMBOL_NAME_STR(check346) ":
-       orw     #0x700,%sr      | disable ints
-       movec   %vbr,%a0        | get vbr
-       movel   %a0@(11*4),%a1  | save old trap vector (Line F)
-       movel   #L1,%a0@(11*4)  | set L1 as new vector
-       movel   %sp,%d1         | save stack pointer
-       moveq   #2,%d0          | value with exception (030)
-       .long   0xf6208000      | move16 %a0@+,%a0@+, the 030 test instruction
-       nop                     | clear instruction pipeline
-       movel   %d1,%sp         | restore stack pointer
-       movec   %vbr,%a0        | get vbr again
-       moveq   #4,%d0          | value with exception (040)
-       .word   0xf5c8          | plpar %a0@, the 040 test instruction
-       nop                     | clear instruction pipeline
-       moveq   #8,%d0          | value if we come here
-L1:    movel   %d1,%sp         | restore stack pointer
-       movel   %a1,%a0@(11*4)  | restore vector
-       rte"
-);
-
 static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
 {
-    if (SysBase->AttnFlags & (AFF_68030|AFF_68040|AFF_68060))
-        *cpu = Supervisor(check346);
+    *cpu = *fpu = 0;
+    if (SysBase->AttnFlags & AFF_68060)
+       *cpu = CPU_68060;
+    else if (SysBase->AttnFlags & AFF_68040)
+       *cpu = CPU_68040;
+    else if (SysBase->AttnFlags & AFF_68030)
+       *cpu = CPU_68030;
     else if (SysBase->AttnFlags & AFF_68020)
-        *cpu = CPU_68020;
+       *cpu = CPU_68020;
     if (*cpu == CPU_68040 || *cpu == CPU_68060) {
        if (SysBase->AttnFlags & AFF_FPU40)
            *fpu = *cpu;
@@ -786,7 +806,7 @@ static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
        if (SysBase->AttnFlags & AFF_68882)
            *fpu = FPU_68882;
        else if (SysBase->AttnFlags & AFF_68881)
-           *cpu = FPU_68881;
+           *fpu = FPU_68881;
     }
     *mmu = *cpu;
 }
@@ -806,7 +826,7 @@ static u_long get_model(u_long chipset)
     else {
        if (debugflag)
            Puts("    Chipset: ");
-       switch(chipset) {
+       switch (chipset) {
            case CS_STONEAGE:
                if (debugflag)
                    Puts("Old or unknown\n");
@@ -1361,7 +1381,7 @@ static void reset_hydra(const struct ConfigDev *cd)
     Disable();
  
     *nic_cr = 0x21;    /* nic command register: software reset etc. */
-    while(((*nic_isr & 0x80) == 0) && --n)  /* wait for reset to complete */
+    while (((*nic_isr & 0x80) == 0) && --n)  /* wait for reset to complete */
        ;
  
     Enable();
@@ -1373,3 +1393,294 @@ static void reset_a2060(const struct ConfigDev *cd)
 #error reset_a2060: not yet implemented
 }
 #endif
+
+
+#ifdef ZKERNEL
+
+#define        ZFILE_CHUNK_BITS        16  /* chunk is 64 KB */
+#define        ZFILE_CHUNK_SIZE        (1 << ZFILE_CHUNK_BITS)
+#define        ZFILE_CHUNK_MASK        (ZFILE_CHUNK_SIZE-1)
+#define        ZFILE_N_CHUNKS          (2*1024*1024/ZFILE_CHUNK_SIZE)
+
+/* variables for storing the uncompressed data */
+static char *ZFile[ZFILE_N_CHUNKS];
+static int ZFileSize = 0;
+static int ZFpos = 0;
+static int Zwpos = 0;
+
+static int Zinfd = 0;       /* fd of compressed file */
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+                       /*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize = 0;  /* valid bytes in inbuf */
+static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;  /* bytes in output buffer */
+static int exit_code = 0;
+static long bytes_out = 0;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+               
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#define malloc(x)      AllocVec(x, MEMF_FAST | MEMF_PUBLIC)
+#define free(x)                FreeVec(x)
+
+#ifdef LILO
+#include "inflate.c"
+#else
+#include "../../../../lib/inflate.c"
+#endif
+
+static void gzip_mark(void **ptr)
+{
+}
+
+static void gzip_release(void **ptr)
+{
+}
+
+
+/*
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+    if (exit_code)
+       return -1;
+
+    insize = Read(Zinfd, inbuf, INBUFSIZ);
+    if (insize <= 0)
+       return -1;
+
+    inptr = 1;
+    return(inbuf[0]);
+}
+
+/*
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, ch;
+    int chunk = Zwpos >> ZFILE_CHUNK_BITS;
+
+    if (exit_code)
+       return;
+
+    if (chunk >= ZFILE_N_CHUNKS) {
+       error("Compressed image too large! Aborting.\n");
+       return;
+    }
+    if (!ZFile[chunk]) {
+       if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE,
+                                             MEMF_FAST | MEMF_PUBLIC))) {
+           error("Out of memory for decompresing kernel image\n");
+           return;
+       }
+    }
+    memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt);
+    Zwpos += outcnt;
+    
+#define        DISPLAY_BITS 10
+    if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0)
+       PutChar('.');
+    
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+       ch = *in++;
+       c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void error(char *x)
+{
+    Printf("\n%s", x);
+    exit_code = 1;
+}
+
+static inline int call_sub(int (*func)(void), void *stackp)
+{
+    register int _res __asm("d0");
+    register int (*a0)(void) __asm("a0") = func;
+    register int (*a1)(void) __asm("a1") = stackp;
+
+    __asm __volatile ("movel sp,a2;"
+                     "movel a1,sp;"
+                     "jsr a0@;"
+                     "movel a2,sp"
+                     : "=r" (_res)
+                     : "r" (a0), "r" (a1)
+                     : "a0", "a1", "a2", "d0", "d1", "memory");
+    return(_res);
+}
+
+static int load_zkernel(int fd)
+{
+    int i, err = -1;
+#define ZSTACKSIZE     (16384)
+    u_long *zstack;
+    
+    for (i = 0; i < ZFILE_N_CHUNKS; ++i)
+       ZFile[i] = NULL;
+    Zinfd = fd;
+    Seek(fd, 0);
+    
+    if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC)))
+       Puts("Couldn't allocate gunzip buffer\n");
+    else {
+       if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC)))
+           Puts("Couldn't allocate gunzip window\n");
+       else {
+           if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE,
+                                             MEMF_FAST | MEMF_PUBLIC)))
+               Puts("Couldn't allocate gunzip stack\n");
+           else {
+               Puts("Uncompressing kernel image ");
+               makecrc();
+               if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE)))
+                   Puts("done\n");
+               ZFileSize = Zwpos;
+               FreeMem(zstack, ZSTACKSIZE);
+           }
+           FreeMem(window, WSIZE);
+           window = NULL;
+       }
+       FreeMem(inbuf, INBUFSIZ);
+       inbuf = NULL;
+    }
+    Close(Zinfd);      /* input file not needed anymore */
+    return(err);
+}
+
+
+/* Note about the read/lseek wrapper and its memory management: It assumes
+ * that all seeks are only forward, and thus data already read or skipped can
+ * be freed. This is true for current organization of bootstrap and kernels.
+ * Little exception: The struct kexec at the start of the file. After reading
+ * it, there may be a seek back to the end of the file. But this currently
+ * doesn't hurt. (Roman)
+ */
+
+static int KRead(int fd, void *buf, int cnt)
+{
+    unsigned done = 0;
+       
+    if (!ZFileSize)
+       return(Read(fd, buf, cnt));
+    
+    if (ZFpos + cnt > ZFileSize)
+       cnt = ZFileSize - ZFpos;
+    
+    while (cnt > 0) {
+       unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
+       unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
+       unsigned n = cnt;
+
+       if (ZFpos + n > endchunk)
+           n = endchunk - ZFpos;
+       memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n);
+       cnt -= n;
+       buf += n;
+       done += n;
+       ZFpos += n;
+
+       if (ZFpos == endchunk) {
+           FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE);
+           ZFile[chunk] = NULL;
+       }
+    }
+
+    return(done);
+}
+
+
+static int KSeek(int fd, int offset)
+{
+    unsigned oldpos, oldchunk, newchunk;
+
+    if (!ZFileSize)
+       return(Seek(fd, offset));
+
+    oldpos = ZFpos;
+    ZFpos = offset;
+    if (ZFpos < 0) {
+       ZFpos = 0;
+       return(-1);
+    } else if (ZFpos > ZFileSize) {
+       ZFpos = ZFileSize;
+       return(-1);
+    }
+
+    /* free memory of skipped-over data */
+    oldchunk = oldpos >> ZFILE_CHUNK_BITS;
+    newchunk = ZFpos  >> ZFILE_CHUNK_BITS;
+    while(oldchunk < newchunk) {
+       if (ZFile[oldchunk]) {
+           FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE);
+           ZFile[oldchunk] = NULL;
+       }
+       ++oldchunk;
+    }
+    return(ZFpos);
+}
+
+
+static void free_zfile(void)
+{
+    int i;
+
+    for (i = 0; i < ZFILE_N_CHUNKS; ++i)
+       if (ZFile[i]) {
+           FreeMem(ZFile[i], ZFILE_CHUNK_SIZE);
+           ZFile[i] = NULL;
+       }
+}
+
+static int KClose(int fd)
+{
+    if (ZFileSize) {
+       free_zfile();
+       ZFileSize = 0;
+    } else
+       Close(fd);
+    return(0);
+}
+#endif /* ZKERNEL */
index d9c77570c35fe63a50ec0a557b9d074371a8fafe..8ebfe63b44534e03b095f49ce99f1a5dc1bb6c3a 100644 (file)
 
 
 #include <asm/setup.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 
     /*
      *  Amiboot Version
      */
 
-#define AMIBOOT_VERSION                "5.1"
+#define AMIBOOT_VERSION                "5.4"
 
 
     /*
@@ -42,7 +42,7 @@
      */
 
 struct amiga_bootinfo {
-    u_long machtype;                   /* machine type */
+    u_long machtype;                   /* machine type = MACH_AMIGA */
     u_long cputype;                    /* system CPU */
     u_long fputype;                    /* system FPU */
     u_long mmutype;                    /* system MMU */
@@ -67,9 +67,9 @@ struct amiga_bootinfo {
      */
 
 struct linuxboot_args {
+    struct amiga_bootinfo bi;  /* Initial values override detected values */
     const char *kernelname;
     const char *ramdiskname;
-    const char *commandline;
     int debugflag;
     int keep_video;
     int reset_boards;
@@ -84,7 +84,6 @@ struct linuxboot_args {
     void (*close)(int fd);
     int (*filesize)(const char *path);
     void (*sleep)(u_long micros);
-    int (*modify_bootinfo)(struct amiga_bootinfo *bi);
 };
 
 
index db4fc284f8f66021d3276644e996af289c6e3226..affe636b8ca5570c3c882fb8429364935f48e3cb 100644 (file)
@@ -203,18 +203,20 @@ static int eth_rcv( Packet *pkt, int *len );
 /* get_remote_kernel():
  * Perform all necessary steps to get the kernel image
  * from the boot server. If successfull (retval == 0), subsequent calls to
- * kread() can access the data.
+ * kread() can access the data. Fatal errors (i.e., retrying is useless)
+ * return -2, others -1.
  */
 
 int get_remote_kernel( const char *kname /* optional */ )
 
 {      char    image_name[256];
-       
+       int             rv;
+
        /* Check if a Ethernet interface is present and determine the Ethernet
         * address */
        if (check_ethif() < 0) {
                printf( "No Ethernet interface found -- no remote boot possible.\n" );
-               return( -1 );
+               return( -2 );
        }
        
        /* Do a BOOTP request to find out our IP address and the kernel image's
@@ -223,23 +225,23 @@ int get_remote_kernel( const char *kname /* optional */ )
                strcpy( image_name, kname );
        else
                *image_name = 0;
-       if (bootp( image_name ) < 0)
-               return( -1 );
+       if ((rv = bootp( image_name )) < 0)
+               return( rv );
        
        /* Now start a TFTP connection to receive the kernel image */
-       if (tftp( image_name ) < 0)
-               return( -1 );
+       if ((rv = tftp( image_name )) < 0)
+               return( rv );
 
        return( 0 );
 }
 
 
-/* kread(), klseek(), kclose():
+/* ll_read(), ll_lseek(), ll_close():
  * Functions for accessing the received kernel image like with read(),
  * lseek(), close().
  */
 
-int kread( int fd, void *buf, unsigned cnt )
+int ll_read( int fd, void *buf, unsigned cnt )
 
 {      unsigned done = 0;
        
@@ -261,18 +263,26 @@ int kread( int fd, void *buf, unsigned cnt )
                buf += n;
                done += n;
                KFpos += n;
+
+               if (KFpos == endchunk) {
+                       free( KFile[chunk] );
+                       KFile[chunk] = NULL;
+               }
        }
 
        return( done );
 }
 
 
-int klseek( int fd, int where, int whence )
+int ll_lseek( int fd, int where, int whence )
 
 {
+    unsigned oldpos, oldchunk, newchunk;
+
        if (!KFileSize)
                return( lseek( fd, where, whence ) );
 
+    oldpos = KFpos;
        switch( whence ) {
          case SEEK_SET:
                KFpos = where;
@@ -295,11 +305,22 @@ int klseek( int fd, int where, int whence )
                return( -1 );
        }
 
+    /* free memory of skipped-over data */
+    oldchunk = oldpos >> KFILE_CHUNK_BITS;
+    newchunk = KFpos  >> KFILE_CHUNK_BITS;
+    while( oldchunk < newchunk ) {
+               if (KFile[oldchunk]) {
+                       free( KFile[oldchunk] );
+                       KFile[oldchunk] = NULL;
+               }
+               ++oldchunk;
+    }
+    
        return( KFpos );
 }
 
 
-int kclose( int fd )
+int ll_close( int fd )
 
 {
        if (!KFileSize)
@@ -382,7 +403,7 @@ static int bootp( char *image_name )
        }
        if (retry >= BOOTP_RETRYS) {
                printf( "No response from a bootp server\n" );
-               return( -1 );
+               return( -2 );
        }
        
        ServerIPaddr = reply->bootp.siaddr;
@@ -433,7 +454,7 @@ static int tftp( char *image_name )
                printf( "TFTP RREQ: %s\n", ErrStr[-err-1] );
                if (--retries > 0)
                        goto repeat_req;
-               return( -1 );
+               return( err == ETIMEO ? -2 : -1 );
        }
 
        retries = 5;
index 02988edaf68586ab2b6a6d5c6e7cb97cd33fa87a..0ee96cdcc4de6bc2972ac19d079f3dee60edc299 100644 (file)
@@ -34,9 +34,9 @@ typedef unsigned long IPADDR;
 /***************************** Prototypes *****************************/
 
 int get_remote_kernel( const char *kname );
-int kread( int fd, void *buf, unsigned cnt );
-int klseek( int fd, int where, int whence );
-int kclose( int fd );
+int ll_read( int fd, void *buf, unsigned cnt );
+int ll_lseek( int fd, int where, int whence );
+int ll_close( int fd );
 
 /************************* End of Prototypes **************************/
 
index de50717de057f4bdd640a11849b74191ed2bc6fa..84c6a6e4b7ad99b38851f6ed28a89030a3ebbe7f 100644 (file)
@@ -8,6 +8,8 @@
 ** for more details.
 **
 ** History:
+**     01 Feb 1997 Implemented kernel decompression (Roman)
+**     28 Nov 1996 Fixed and tested previous change (James)
 **     27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert)
 **     12 Nov 1996 Fixed and tested previous change (Andreas)
 **     18 Aug 1996 Updated for the new boot information structure (untested!)
@@ -32,6 +34,8 @@
 
 
 #define BOOTINFO_COMPAT_1_0    /* bootinfo interface version 1.0 compatible */
+/* support compressed kernels? */
+#define ZKERNEL
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -159,6 +163,9 @@ extern char copyall, copyallend;
  * ...err! On the Afterburner040 (for the Falcon) it's the same... So we do
  * another test with 0x00ff82fe, that gives a bus error on the Falcon, but is
  * in the range where the Medusa always asserts DTACK.
+ * On the Hades address 0 is writeable as well and it asserts DTACK on
+ * address 0x00ff82fe. To test if the machine is a Hades, address 0xb0000000
+ * is tested. On the Medusa this gives a bus error.
  */
 
 int test_medusa( void )
@@ -177,7 +184,10 @@ int test_medusa( void )
                  "nop          \n\t"
                  "tstb         0x00ff82fe\n\t"
                  "nop          \n\t"
-                 "moveq        #1,%0\n"
+                 "moveq        #1,%0\n\t"
+                 "tstb         0xb0000000\n\t"
+                 "nop          \n\t"
+                 "moveq        #0,%0\n"
                "Lberr:\t"
                  "movel        a1,sp\n\t"
                  "movel        a0,0x8"
@@ -357,11 +367,21 @@ static int check_bootinfo_version(char *memptr)
 #ifdef USE_BOOTP
 # include "bootp.h"
 #else
-# define kread read
-# define klseek        lseek
-# define kclose        close
+# define ll_read       read
+# define ll_lseek      lseek
+# define ll_close      close
 #endif
 
+#ifdef ZKERNEL
+static int load_zkernel( int fd );
+static int kread( int fd, void *buf, unsigned cnt );
+static int klseek( int fd, int where, int whence );
+static int kclose( int fd );
+#else
+# define kread         read
+# define klseek                lseek
+# define kclose                close
+#endif
 
 /* ++andreas: this must be inline due to Super */
 static inline void boot_exit (int) __attribute__ ((noreturn));
@@ -385,16 +405,18 @@ int main(int argc, char *argv[])
     Elf32_Ehdr kexec_elf;
     Elf32_Phdr *kernel_phdrs = NULL;
     u_long start_mem, mem_size, rd_size, text_offset = 0, kernel_size;
+    int prefer_bootp = 1, kname_set = 0, n_knames;
 #ifdef USE_BOOTP
-    int prefer_bootp = 1, kname_set = 0;
+    int err;
 #endif
+    char kname_list[5][64];
     void *bi_ptr;
 
     ramdisk_name = NULL;
     kernel_name = "vmlinux";
 
     /* print the startup message */
-    puts("\fLinux/68k Atari Bootstrap version 2.0"
+    puts("\fLinux/68k Atari Bootstrap version 2.2"
 #ifdef USE_BOOTP
         " (with BOOTP)"
 #endif
@@ -410,11 +432,7 @@ int main(int argc, char *argv[])
     bi.machtype = MACH_ATARI;
 
     /* check arguments */
-#ifdef USE_BOOTP
     while ((ch = getopt(argc, argv, "bdtsk:r:")) != EOF)
-#else
-    while ((ch = getopt(argc, argv, "dtsk:r:")) != EOF)
-#endif
        switch (ch) {
          case 'd':
            debugflag = 1;
@@ -427,18 +445,14 @@ int main(int argc, char *argv[])
            break;
          case 'k':
            kernel_name = optarg;
-#ifdef USE_BOOTP
            kname_set = 1;
-#endif
            break;
          case 'r':
            ramdisk_name = optarg;
            break;
-#ifdef USE_BOOTP
          case 'b':
            prefer_bootp = 0;
            break;
-#endif
          case '?':
          default:
            usage();
@@ -744,38 +758,60 @@ int main(int argc, char *argv[])
     boot_exit(-1);
 #endif /* TEST */
 
+    i = 0;
 #ifdef USE_BOOTP
+    if (!kname_set)
+       kname_list[i++][0] = '\0'; /* default kernel which BOOTP server says */
+#endif
+#ifdef ZKERNEL
+    strcpy( kname_list[i], kernel_name );
+    strcat( kname_list[i], ".gz" );
+    ++i;
+#endif
+    strcpy( kname_list[i++], kernel_name );
+#ifdef ZKERNEL
+    if (!kname_set)
+       strcpy( kname_list[i++], "vmlinuz" );
+#endif
+    n_knames = i;
+
     kfd = -1;
+#ifdef USE_BOOTP
     if (prefer_bootp) {
-       /* First try to get a remote kernel, then use a local kernel (if
-        * present) */
-       if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) {
-           printf( "\nremote boot failed; trying local kernel\n" );
-           if ((kfd = open (kernel_name, O_RDONLY)) == -1) {
-               fprintf (stderr, "Unable to open kernel file %s\n",
-                        kernel_name);
-               boot_exit (EXIT_FAILURE);
-           }
+       for( i = 0; i < n_knames; ++i ) {
+           if ((err = get_remote_kernel( kname_list[i] )) >= 0)
+               goto kernel_open;
+           if (err < -1) /* fatal error; retries don't help... */
+               break;
        }
+       printf( "\nremote boot failed; trying local kernel\n" );
     }
-    else {
-       /* Try BOOTP if local kernel cannot be opened */
-       if ((kfd = open (kernel_name, O_RDONLY)) == -1) {
-           printf( "\nlocal kernel failed; trying remote boot\n" );
-           if (get_remote_kernel( kname_set ? kernel_name : NULL ) < 0) {
-               fprintf (stderr, "Unable to remote boot and "
-                        "to open kernel file %s\n", kernel_name);
-               boot_exit (EXIT_FAILURE);
-           }
-       }
+#endif
+    for( i = 0; i < n_knames; ++i ) {
+       if ((kfd = open( kname_list[i], O_RDONLY )) != -1)
+           goto kernel_open;
     }
-#else
-    /* open kernel executable and read exec header */
-    if ((kfd = open (kernel_name, O_RDONLY)) == -1) {
-       fprintf (stderr, "Unable to open kernel file %s\n", kernel_name);
-       boot_exit (EXIT_FAILURE);
+#ifdef USE_BOOTP
+    if (!prefer_bootp) {
+       printf( "\nlocal kernel failed; trying remote boot\n" );
+       for( i = 0; i < n_knames; ++i ) {
+           if ((err = get_remote_kernel( kname_list[i] )) >= 0)
+               goto kernel_open;
+           if (err < -1) /* fatal error; retries don't help... */
+               break;
+       }
     }
 #endif
+    fprintf( stderr, "Unable to open any kernel file\n(Tried " );
+    for( i = 0; i < n_knames; ++i ) {
+       fprintf( stderr, "%s%s", kname_list[i],
+                i <  n_knames-2 ? ", " :
+                i == n_knames-2 ? ", and " :
+                ")\n" );
+    }
+    boot_exit( EXIT_FAILURE );
+    
+  kernel_open:
 
     if (kread (kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec))
     {
@@ -783,6 +819,19 @@ int main(int argc, char *argv[])
        boot_exit (EXIT_FAILURE);
     }
 
+#ifdef ZKERNEL
+    if (((unsigned char *)&kexec)[0] == 037 &&
+       (((unsigned char *)&kexec)[1] == 0213 ||
+        ((unsigned char *)&kexec)[1] == 0236)) {
+       /* That's a compressed kernel */
+       printf( "Kernel is compressed\n" );
+       if (load_zkernel( kfd )) {
+           printf( "Decompression error -- aborting\n" );
+           boot_exit( EXIT_FAILURE );
+       }
+    }
+#endif
+    
     switch (N_MAGIC(kexec)) {
     case ZMAGIC:
        text_offset = N_TXTOFF(kexec);
@@ -847,18 +896,6 @@ int main(int argc, char *argv[])
     }
     else
        bi.ramdisk.size = 0;
-
-    rd_size = bi.ramdisk.size;
-    if (mem_size - rd_size < MB && bi.num_memory > 1)
-      /* If running low on ST ram load ramdisk into alternate ram.  */
-      bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size;
-    else
-      /* Else hopefully there is enough ST ram. */
-      bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size;
-
-    /* create the bootinfo structure */
-    if (!create_bootinfo())
-       boot_exit (EXIT_FAILURE);
  
     /* calculate the total required amount of memory */
     if (elf_kernel)
@@ -885,6 +922,19 @@ int main(int argc, char *argv[])
       }
     else
       kernel_size = kexec.a_text + kexec.a_data + kexec.a_bss;
+
+    rd_size = bi.ramdisk.size;
+    if (rd_size + kernel_size > mem_size - MB/2 && bi.num_memory > 1)
+      /* If running low on ST ram load ramdisk into alternate ram.  */
+      bi.ramdisk.addr = (u_long) bi.memory[1].addr + bi.memory[1].size - rd_size;
+    else
+      /* Else hopefully there is enough ST ram. */
+      bi.ramdisk.addr = (u_long)start_mem + mem_size - rd_size;
+
+    /* create the bootinfo structure */
+    if (!create_bootinfo())
+       boot_exit (EXIT_FAILURE);
+
     memreq = kernel_size + bi_size;
 #ifdef BOOTINFO_COMPAT_1_0
     if (sizeof(compat_bootinfo) > bi_size)
@@ -997,7 +1047,7 @@ int main(int argc, char *argv[])
     if (debugflag)
     {
        if (bi.ramdisk.size)
-           printf ("RAM disk at %#lx, size is %ldK\n",
+           printf ("RAM disk at %#lx, size is %ld\n",
                    (u_long)(memptr + memreq - rd_size),
                    bi.ramdisk.size);
 
@@ -1192,7 +1242,7 @@ static int create_bootinfo(void)
 static int add_bi_record(u_short tag, u_short size, const void *data)
 {
     struct bi_record *record;
-    u_int size2;
+    u_short size2;
 
     size2 = (sizeof(struct bi_record)+size+3)&-4;
     if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) {
@@ -1238,7 +1288,7 @@ static int create_compat_bootinfo(void)
     else if (bi.cputype & CPU_68060)
        compat_bootinfo.cputype = COMPAT_CPU_68060;
     else {
-       Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype);
+       printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype);
        return(0);
     }
     if (bi.fputype & FPU_68881)
@@ -1250,12 +1300,12 @@ static int create_compat_bootinfo(void)
     else if (bi.fputype & FPU_68060)
        compat_bootinfo.cputype |= COMPAT_FPU_68060;
     else {
-       Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype);
+       printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype);
        return(0);
     }
     compat_bootinfo.num_memory = bi.num_memory;
     if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) {
-       Printf("Warning: using only %d blocks of memory\n",
+       printf("Warning: using only %d blocks of memory\n",
               COMPAT_NUM_MEMINFO);
        compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO;
     }
@@ -1278,3 +1328,275 @@ static int create_compat_bootinfo(void)
     return(1);
 }
 #endif /* BOOTINFO_COMPAT_1_0 */
+
+
+#ifdef ZKERNEL
+
+#define        ZFILE_CHUNK_BITS        16  /* chunk is 64 KB */
+#define        ZFILE_CHUNK_SIZE        (1 << ZFILE_CHUNK_BITS)
+#define        ZFILE_CHUNK_MASK        (ZFILE_CHUNK_SIZE-1)
+#define        ZFILE_N_CHUNKS          (2*1024*1024/ZFILE_CHUNK_SIZE)
+
+/* variables for storing the uncompressed data */
+static char *ZFile[ZFILE_N_CHUNKS];
+static int ZFileSize = 0;
+static int ZFpos = 0;
+static int Zwpos = 0;
+
+static int Zinfd = 0;       /* fd of compressed file */
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#define memzero(s, n)     memset ((s), 0, (n))
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+                       /*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize = 0;  /* valid bytes in inbuf */
+static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0;  /* bytes in output buffer */
+static int exit_code = 0;
+static long bytes_out = 0;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+               
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../../../../lib/inflate.c"
+
+static void gzip_mark( void **ptr )
+{
+}
+
+static void gzip_release( void **ptr )
+{
+}
+
+
+/*
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf( void )
+{
+    if (exit_code)
+       return -1;
+
+    insize = ll_read( Zinfd, inbuf, INBUFSIZ );
+    if (insize <= 0)
+       return -1;
+
+    inptr = 1;
+    return( inbuf[0] );
+}
+
+/*
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window( void )
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, ch;
+    int chunk = Zwpos >> ZFILE_CHUNK_BITS;
+
+    if (chunk >= ZFILE_N_CHUNKS) {
+       fprintf( stderr, "compressed image too large! Aborting.\n" );
+       boot_exit( EXIT_FAILURE );
+    }
+    if (!ZFile[chunk]) {
+       if (!(ZFile[chunk] = (char *)Malloc( ZFILE_CHUNK_SIZE ))) {
+           fprintf( stderr, "Out of memory for decompresing kernel image\n" );
+           boot_exit( EXIT_FAILURE );
+       }
+    }
+    memcpy( ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt );
+    Zwpos += outcnt;
+    
+#define        DISPLAY_BITS 13
+    if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0) {
+       printf( "." );
+       fflush( stdout );
+    }
+    
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+           ch = *in++;
+           c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void error( char *x )
+{
+    fprintf( stderr, "\n%s", x);
+    exit_code = 1;
+}
+
+static int load_zkernel( int fd )
+{
+    int i, err;
+    
+    for( i = 0; i < ZFILE_N_CHUNKS; ++i )
+       ZFile[i] = NULL;
+    Zinfd = fd;
+    ll_lseek( fd, 0, SEEK_SET );
+    
+    if (!(inbuf = (uch *)Malloc( INBUFSIZ ))) {
+       fprintf( stderr, "Couldn't allocate gunzip buffer\n" );
+       boot_exit( EXIT_FAILURE );
+    }
+    if (!(window = (uch *)Malloc( WSIZE ))) {
+       fprintf( stderr, "Couldn't allocate gunzip window\n" );
+       boot_exit( EXIT_FAILURE );
+    }
+
+    printf( "Uncompressing kernel image " );
+    fflush( stdout );
+    makecrc();
+    if (!(err = gunzip()))
+       printf( "done\n" );
+    ZFileSize = Zwpos;
+    ll_close( Zinfd ); /* input file not needed anymore */
+    
+    Mfree( inbuf );
+    Mfree( window );
+    return( err );
+}
+
+/* Note about the read/lseek wrapper and its memory management: It assumes
+ * that all seeks are only forward, and thus data already read or skipped can
+ * be freed. This is true for current organization of bootstrap and kernels.
+ * Little exception: The struct kexec at the start of the file. After reading
+ * it, there may be a seek back to the end of the file. But this currently
+ * doesn't hurt. Same considerations apply to the TFTP file buffers. (Roman)
+ */
+
+static int kread( int fd, void *buf, unsigned cnt )
+{
+    unsigned done = 0;
+       
+    if (!ZFileSize)
+       return( ll_read( fd, buf, cnt ) );
+    
+    if (ZFpos + cnt > ZFileSize)
+       cnt = ZFileSize - ZFpos;
+    
+    while( cnt > 0 ) {
+       unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
+       unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
+       unsigned n = cnt;
+
+       if (ZFpos + n > endchunk)
+           n = endchunk - ZFpos;
+       memcpy( buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n );
+       cnt -= n;
+       buf += n;
+       done += n;
+       ZFpos += n;
+
+       if (ZFpos == endchunk) {
+           Mfree( ZFile[chunk] );
+           ZFile[chunk] = NULL;
+       }
+    }
+
+    return( done );
+}
+
+
+static int klseek( int fd, int where, int whence )
+{
+    unsigned oldpos, oldchunk, newchunk;
+
+    if (!ZFileSize)
+       return( ll_lseek( fd, where, whence ) );
+
+    oldpos = ZFpos;
+    switch( whence ) {
+      case SEEK_SET:
+       ZFpos = where;
+       break;
+      case SEEK_CUR:
+       ZFpos += where;
+       break;
+      case SEEK_END:
+       ZFpos = ZFileSize + where;
+       break;
+      default:
+       return( -1 );
+    }
+    if (ZFpos < 0) {
+       ZFpos = 0;
+       return( -1 );
+    }
+    else if (ZFpos > ZFileSize) {
+       ZFpos = ZFileSize;
+       return( -1 );
+    }
+
+    /* free memory of skipped-over data */
+    oldchunk = oldpos >> ZFILE_CHUNK_BITS;
+    newchunk = ZFpos  >> ZFILE_CHUNK_BITS;
+    while( oldchunk < newchunk ) {
+       if (ZFile[oldchunk]) {
+           Mfree( ZFile[oldchunk] );
+           ZFile[oldchunk] = NULL;
+       }
+       ++oldchunk;
+    }
+    
+    return( ZFpos );
+}
+
+
+static void free_zfile( void )
+{
+    int i;
+
+    for( i = 0; i < ZFILE_N_CHUNKS; ++i )
+       if (ZFile[i]) Mfree( ZFile[i] );
+}
+
+static int kclose( int fd )
+{
+    if (ZFileSize) {
+       free_zfile();
+       return( 0 );
+    }
+    else
+       return( ll_close( fd ) );
+}
+
+
+
+#endif /* ZKERNEL */
index ae32fa9ddb013e24fadefef3f4290a739f65fe94..df6a45a9d12331cdb0a57cc448c618548d5bf650 100644 (file)
@@ -58,6 +58,9 @@ if [ "$CONFIG_AMIGA" = "y" ]; then
   bool 'Amiga ECS chipset support' CONFIG_AMIFB_ECS
   bool 'Amiga AGA chipset support' CONFIG_AMIFB_AGA
   bool 'Amiga Cybervision support' CONFIG_FB_CYBER
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    bool 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
+  fi
 #  bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
 #  if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
 #    bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
@@ -82,15 +85,15 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
   dep_tristate '   SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
 fi
 if [ "$CONFIG_AMIGA" = "y" ]; then
-tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
+  tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
-if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
-comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
-bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
-dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
-fi
+  tristate 'Atari ACSI support' CONFIG_ATARI_ACSI
+  if [ "$CONFIG_ATARI_ACSI" != "n" ]; then
+    comment 'Some devices (e.g. CD jukebox) support multiple LUNs'
+    bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN
+    dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
+  fi
 fi
 
 comment 'Additional Block Devices'
@@ -138,17 +141,23 @@ mainmenu_option next_comment
 comment 'SCSI low-level drivers'
 
 if [ "$CONFIG_AMIGA" = "y" ]; then
-tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
-tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
-bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
-bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI
-bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
-bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
+  tristate 'A3000 WD33C93A support' CONFIG_A3000_SCSI
+  tristate 'A2091 WD33C93A support' CONFIG_A2091_SCSI
+  tristate 'GVP Series II WD33C93A support' CONFIG_GVP11_SCSI
+  bool 'CyberStorm SCSI support' CONFIG_CYBERSTORM_SCSI
+  bool 'CyberStorm SCSI Mk II support' CONFIG_CYBERSTORMII_SCSI
+  bool 'Blizzard 2060 SCSI support' CONFIG_BLZ2060_SCSI
+  bool 'Blizzard 1230IV/1260 SCSI support' CONFIG_BLZ1230_SCSI
+  bool 'Fastlane SCSI support' CONFIG_FASTLANE_SCSI
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    bool 'A4000T SCSI support' CONFIG_A4000T_SCSI
+    bool 'A4091 SCSI support' CONFIG_A4091_SCSI
+    bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI
+  fi
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
-bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY
+  dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
+  bool 'Long delays for Toshiba CD-ROMs' CONFIG_ATARI_SCSI_TOSHIBA_DELAY
 fi
 #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
 endmenu
@@ -202,6 +211,7 @@ comment 'Character devices'
 
 define_bool CONFIG_VT y
 define_bool CONFIG_VT_CONSOLE y
+define_bool CONFIG_FB_CONSOLE y
 
 tristate 'Parallel printer support' CONFIG_PRINTER
 if [ "$CONFIG_AMIGA" = "y" ]; then
@@ -214,13 +224,26 @@ fi
 if [ "$CONFIG_ATARI" = "y" ]; then
   tristate 'Atari MFP serial support' CONFIG_ATARI_MFPSER
   tristate 'Atari SCC serial support' CONFIG_ATARI_SCC
+  if [ "$CONFIG_ATARI_SCC" = "y" -o "$CONFIG_ATARI_SCC" = "m" ]; then
+    bool 'Atari SCC serial DMA support' CONFIG_ATARI_SCC_DMA
+  fi
   tristate 'Atari MIDI serial support' CONFIG_ATARI_MIDI
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    tristate 'Atari DSP56k support (EXPERIMENTAL)' CONFIG_ATARI_DSP56K
+  fi
 fi
 if [ "$CONFIG_AMIGA" = "y" ]; then
   tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
-  bool 'GVP IO-Extender support' CONFIG_GVPIOEXT
+  tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
+  dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
+  dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
 fi
+if [ "$CONFIG_ATARI_MFPSER" = "y" -o "$CONFIG_ATARI_SCC" = "y" -o \
+     "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
+     "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" ]; then
+  bool 'Serial console support' CONFIG_SERIAL_CONSOLE
+fi
 bool 'Support for user serial device modules' CONFIG_USERIAL
 bool 'Watchdog Timer Support'  CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
@@ -228,6 +251,9 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then
   bool '   Software Watchdog' CONFIG_SOFT_WATCHDOG
 fi
 bool 'Support for user misc device modules' CONFIG_UMISC
+if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_ATARI" = "y" ]; then
+  define_bool CONFIG_ABSTRACT_CONSOLE y
+fi
 endmenu
 
 mainmenu_option next_comment
@@ -247,4 +273,5 @@ bool 'Kernel profiling support' CONFIG_PROFILE
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
+bool 'Remote debugging support' CONFIG_KGDB
 endmenu
index fbd998081f8c03519b8a6cab73abb1c1bc2eb245..376249c90d1490b8266d6527f52ed46cb5070f78 100644 (file)
@@ -61,7 +61,7 @@
 #endif
 #ifdef CONFIG_FB_CYBER
 #include "../amiga/s3blit.h"
-#endif /* CONFIG_FB_CYBER */
+#endif
 #include <linux/fb.h>
 #include <asm/font.h>
 #include <asm/machdep.h>
@@ -70,7 +70,7 @@
 #include <asm/uaccess.h>
 
 #include "../../../drivers/char/vt_kern.h"   /* vt_cons and vc_resize_con() */
-
+#include "../../../drivers/char/console_struct.h"
 
 /* Import console_blanked from console.c */
 
@@ -95,6 +95,7 @@ extern int console_blanked;
 #undef CONFIG_FBCON_24PACKED
 #undef CONFIG_FBCON_32PACKED
 #undef CONFIG_FBCON_CYBER
+#undef CONFIG_FBCON_RETINAZ3
 
 
 /* Monochrome is default */
@@ -117,7 +118,18 @@ extern int console_blanked;
 #ifndef CONFIG_FBCON_CYBER
 #define CONFIG_FBCON_CYBER
 #endif
-#endif /* CONFIG_FB_CYBER */
+#endif
+
+/* RetinaZ3 Graphics Board */
+
+#ifdef CONFIG_FB_RETINAZ3
+#ifndef CONFIG_FBCON_RETINAZ3
+#define CONFIG_FBCON_RETINAZ3
+#endif
+#ifndef CONFIG_FBCON_8PACKED
+#define CONFIG_FBCON_8PACKED
+#endif
+#endif
 
 #endif /* CONFIG_AMIGA */
 
@@ -151,9 +163,9 @@ extern int console_blanked;
 #undef CONFIG_FBCON_IPLAN2
 #endif
 
-#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_8PACKED) || \
-    defined(CONFIG_FBCON_16PACKED) || defined(CONFIG_FBCON_24PACKED) || \
-    defined(CONFIG_FBCON_32PACKED)
+#if defined(CONFIG_FBCON_CYBER) || defined(CONFIG_FBCON_RETINAZ3) || \
+    defined(CONFIG_FBCON_8PACKED) || defined(CONFIG_FBCON_16PACKED) || \
+    defined(CONFIG_FBCON_24PACKED) || defined(CONFIG_FBCON_32PACKED)
 #define CONFIG_FBCON_PACKED
 #else
 #undef CONFIG_FBCON_PACKED
@@ -224,21 +236,24 @@ static __inline__ int CURSOR_UNDRAWN(void)
     *    Interface used by the world
     */
 
-static u_long fbcon_startup(u_long kmem_start, char **display_desc);
+static u_long fbcon_startup(u_long kmem_start, const char **display_desc);
 static void fbcon_init(struct vc_data *conp);
 static int fbcon_deinit(struct vc_data *conp);
 static int fbcon_changevar(int con);
 static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
                        int width);
-static int fbcon_putc(struct vc_data *conp, int c, int y, int x);
-static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
-                       int x);
+static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx);
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy,
+                       int xx);
 static int fbcon_cursor(struct vc_data *conp, int mode);
 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
 static int fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                        int height, int width);
 static int fbcon_switch(struct vc_data *conp);
 static int fbcon_blank(int blank);
+static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
+static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
 
 
    /*
@@ -264,14 +279,22 @@ static __inline__ void memset_even_8p(void *d, size_t count, u_long val1,
                                       u_long val2, u_long val3, u_long val4);
 static __inline__ void memmove_8p_col(void *d, void *s, int h, int bpr);
 static __inline__ void expand8dl(u_char c, u_long *ret1, u_long *ret2);
-static __inline__ void memclear_2p_col(void *d, size_t h, u_short val, int bpr);
+static __inline__ void memclear_2p_col(void *d, size_t h, u_short val,
+                                      int bpr);
 static __inline__ void memset_even_2p(void *d, size_t count, u_long val);
 static __inline__ void memmove_2p_col(void *d, void *s, int h, int bpr);
 static __inline__ u_short expand2w(u_char c);
 static __inline__ u_long expand2l(u_char c);
 static __inline__ u_short dup2w(u_char c);
-static __inline__ int real_y(struct display *p, int y);
+static __inline__ int real_y(struct display *p, int yy);
 static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
+static __inline__ void updatescrollmode(struct display *p);
+static __inline__ void ywrap_up(int unit, struct display *p, int count);
+static __inline__ void ywrap_down(int unit, struct display *p, int count);
+static __inline__ void ypan_up(int unit, struct vc_data *conp,
+                              struct display *p, int count);
+static __inline__ void ypan_down(int unit, struct vc_data *conp,
+                                struct display *p, int count);
 static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
                             int height, int width, u_int y_break);
 
@@ -285,11 +308,11 @@ static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
                        int height, int width);
 static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
                        int height, int width);
-static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
-                      int x);
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx);
 static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x);
-static void rev_char_mono(struct display *p, int x, int y);
+                       int count, int yy, int xx);
+static void rev_char_mono(struct display *p, int xx, int yy);
 #endif /* CONFIG_FBCON_MONO */
 
 
@@ -302,11 +325,11 @@ static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
                        int height, int width);
 static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
                        int height, int width);
-static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
-                      int x);
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx);
 static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x);
-static void rev_char_ilbm(struct display *p, int x, int y);
+                       int count, int yy, int xx);
+static void rev_char_ilbm(struct display *p, int xx, int yy);
 #endif /* CONFIG_FBCON_ILBM */
 
 
@@ -319,11 +342,11 @@ static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
                        int height, int width);
 static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
                        int height, int width);
-static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
-                      int x);
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx);
 static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x);
-static void rev_char_plan(struct display *p, int x, int y);
+                       int count, int yy, int xx);
+static void rev_char_plan(struct display *p, int xx, int yy);
 #endif /* CONFIG_FBCON_PLANES */
 
 
@@ -336,11 +359,11 @@ static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
                           int height, int width);
 static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
                           int sx, int height, int width);
-static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x);
+static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int yy,
+                         int xx);
 static void putcs_2_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x);
-static void rev_char_2_plane(struct display *display, int x, int y);
+                          const char *s, int count, int yy, int xx);
+static void rev_char_2_plane(struct display *display, int xx, int yy);
 #endif /* CONFIG_FBCON_2PLANE */
 
 
@@ -353,11 +376,11 @@ static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
                           int height, int width);
 static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
                           int sx, int height, int width);
-static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x);
+static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int yy,
+                         int xx);
 static void putcs_4_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x);
-static void rev_char_4_plane(struct display *p, int x, int y);
+                          const char *s, int count, int yy, int xx);
+static void rev_char_4_plane(struct display *p, int xx, int yy);
 #endif /* CONFIG_FBCON_4PLANE */
 
 
@@ -370,11 +393,11 @@ static void bmove_8_plane(struct display *p, int sy, int sx, int dy, int dx,
                           int height, int width);
 static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
                           int sx, int height, int width);
-static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x);
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy,
+                         int xx);
 static void putcs_8_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x);
-static void rev_char_8_plane(struct display *display, int x, int y);
+                          const char *s, int count, int yy, int xx);
+static void rev_char_8_plane(struct display *display, int xx, int yy);
 #endif /* CONFIG_FBCON_8PLANE */
 
 
@@ -387,11 +410,11 @@ static void bmove_8_packed(struct display *p, int sy, int sx, int dy, int dx,
                            int height, int width);
 static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
                            int sx, int height, int width);
-static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
-                          int x);
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int yy,
+                          int xx);
 static void putcs_8_packed(struct vc_data *conp, struct display *p,
-                           const char *s, int count, int y, int x);
-static void rev_char_8_packed(struct display *p, int x, int y);
+                           const char *s, int count, int yy, int xx);
+static void rev_char_8_packed(struct display *p, int xx, int yy);
 #endif /* CONFIG_FBCON_8PACKED */
 
 
@@ -405,10 +428,10 @@ static void bmove_16_packed(struct display *p, int sy, int sx, int dy, int dx,
 static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
                             int sx, int height, int width);
 static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
-                           int y, int x);
+                           int yy, int xx);
 static void putcs_16_packed(struct vc_data *conp, struct display *p,
-                            const char *s, int count, int y, int x);
-static void rev_char_16_packed(struct display *p, int x, int y);
+                            const char *s, int count, int yy, int xx);
+static void rev_char_16_packed(struct display *p, int xx, int yy);
 #endif */ CONFIG_FBCON_8PACKED */
 
 
@@ -421,22 +444,38 @@ static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
                         int height, int width);
 static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
                         int height, int width);
-static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
-                       int x);
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy,
+                       int xx);
 static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
-                        int count, int y, int x);
-static void rev_char_cyber(struct display *p, int x, int y);
+                        int count, int yy, int xx);
+static void rev_char_cyber(struct display *p, int xx, int yy);
 
 extern void Cyber_WaitQueue(u_short fifo);
 extern void Cyber_WaitBlit(void);
 extern void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
                          u_short desty, u_short width, u_short height,
                          u_short mode);
-extern void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
+extern void Cyber_RectFill(u_short xx, u_short yy, u_short width, u_short height,
                            u_short mode, u_short color);
-extern void Cyber_MoveCursor(u_short x, u_short y);
+extern void Cyber_MoveCursor(u_short xx, u_short yy);
 #endif /* CONFIG_FBCON_CYBER */
 
+#ifdef CONFIG_FBCON_RETINAZ3
+static void clear_retz3(struct vc_data *conp, struct display *p, int
+                       sy, int sx, int height, int width);
+static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width);
+extern void retz3_bitblt(struct fb_var_screeninfo *scr,
+                        unsigned short srcx, unsigned short srcy, unsigned
+                        short destx, unsigned short desty, unsigned short
+                        width, unsigned short height, unsigned short cmd,
+                        unsigned short mask);
+static void putc_retz3(struct vc_data *conp, struct display *p, int c,
+                      int yy, int xx);
+static void putcs_retz3(struct vc_data *conp, struct display *p, const
+                       char *s, int count, int yy, int xx);
+static void rev_char_retz3(struct display *p, int xx, int yy);
+#endif
 
    /*
     *    `switch' for the Low Level Operations
@@ -447,10 +486,10 @@ struct display_switch {
                   int width);
     void (*clear)(struct vc_data *conp, struct display *p, int sy, int sx,
                   int height, int width);
-    void (*putc)(struct vc_data *conp, struct display *p, int c, int y, int x);
+    void (*putc)(struct vc_data *conp, struct display *p, int c, int yy, int xx);
     void (*putcs)(struct vc_data *conp, struct display *p, const char *s,
-                  int count, int y, int x);
-    void (*rev_char)(struct display *p, int x, int y);
+                  int count, int yy, int xx);
+    void (*rev_char)(struct display *p, int xx, int yy);
 };
 
 
@@ -509,8 +548,15 @@ static struct display_switch dispsw_cyber = {
 };
 #endif /* CONFIG_FBCON_CYBER */
 
+#ifdef CONFIG_FBCON_RETINAZ3
+static struct display_switch dispsw_retz3 = {
+   bmove_retz3, clear_retz3, putc_retz3,
+   putcs_retz3, rev_char_retz3
+};
+#endif
+
 
-static u_long fbcon_startup(u_long kmem_start, char **display_desc)
+static u_long fbcon_startup(u_long kmem_start, const char **display_desc)
 {
    int irqres = 0;
 
@@ -566,6 +612,19 @@ static int fbcon_changevar(int con)
 }
 
 
+static __inline__ void updatescrollmode(struct display *p)
+{
+   if (divides(p->ywrapstep, p->fontheight) &&
+       divides(p->fontheight, p->var.yres_virtual))
+      p->scrollmode = SCROLL_YWRAP;
+   else if (divides(p->ypanstep, p->fontheight) &&
+            p->var.yres_virtual >= p->var.yres+p->fontheight)
+      p->scrollmode = SCROLL_YPAN;
+   else
+      p->scrollmode = SCROLL_YMOVE;
+}
+
+
 static void fbcon_setup(int con, int setcol, int init)
 {
    struct display *p = &disp[con];
@@ -579,16 +638,12 @@ static void fbcon_setup(int con, int setcol, int init)
                      &p->fontdata) || p->fontwidth != 8)
           getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
                          &p->fontheight, &p->fontdata);
-   if (p->fontwidth != 8)
-      panic("fbcon_setup: No support for fontwidth != 8");
-
-   if (divides(p->ywrapstep, p->fontheight) && divides(p->fontheight, p->var.yres_virtual))
-      p->scrollmode = SCROLL_YWRAP;
-   else if (divides(p->ypanstep, p->fontheight) &&
-            p->var.yres_virtual >= p->var.yres+p->fontheight)
-      p->scrollmode = SCROLL_YPAN;
-   else
-      p->scrollmode = SCROLL_YMOVE;
+   if (p->fontwidth != 8) {
+      /* ++Geert: changed from panic() to `correct and continue' */
+      printk("fbcon_setup: No support for fontwidth != 8");
+      p->fontwidth = 8;
+   }
+   updatescrollmode(p);
 
    nr_cols = p->var.xres/p->fontwidth;
    nr_rows = p->var.yres/p->fontheight;
@@ -638,7 +693,8 @@ static void fbcon_setup(int con, int setcol, int init)
    if (p->type == FB_TYPE_INTERLEAVED_PLANES && p->type_aux != 2) {
       if (p->line_length) {
          p->next_line = p->line_length*p->var.bits_per_pixel;
-         p->next_plane = p->line_length;
+         p->next_plane = p->line_length
+;
       } else {
          p->next_line = p->type_aux;
          p->next_plane = p->type_aux/p->var.bits_per_pixel;
@@ -658,13 +714,18 @@ static void fbcon_setup(int con, int setcol, int init)
 #endif /* CONFIG_FBCON_PLANES */
 #ifdef CONFIG_FBCON_PACKED
    if (p->type == FB_TYPE_PACKED_PIXELS) {
-      p->next_line = p->var.xres_virtual*p->var.bits_per_pixel>>3;
+      p->next_line = (p->var.xres_virtual*p->var.bits_per_pixel)>>3;
       p->next_plane = 0;
 #ifdef CONFIG_FBCON_CYBER
       if (p->var.accel == FB_ACCEL_CYBERVISION)
          p->dispsw = &dispsw_cyber;
       else
-#endif /* CONFIG_FBCON_CYBER */
+#endif
+#ifdef CONFIG_FBCON_RETINAZ3
+      if (p->var.accel == FB_ACCEL_RETINAZ3)
+         p->dispsw = &dispsw_retz3;
+      else
+#endif
 #ifdef CONFIG_FBCON_8PACKED
       if (p->var.bits_per_pixel == 8)
          p->dispsw = &dispsw_8_packed;
@@ -1399,12 +1460,12 @@ static __inline__ u_short dup2w(u_char c)
  * restriction is simplicity & efficiency at the moment.
  */
 
-static __inline__ int real_y(struct display *p, int y)
+static __inline__ int real_y(struct display *p, int yy)
 {
    int rows = p->vrows;
 
-   y += p->yscroll;
-   return(y < rows ? y : y-rows);
+   yy += p->yscroll;
+   return(yy < rows ? yy : yy-rows);
 }
 
 
@@ -1436,7 +1497,7 @@ static int fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
 }
 
 
-static int fbcon_putc(struct vc_data *conp, int c, int y, int x)
+static int fbcon_putc(struct vc_data *conp, int c, int yy, int xx)
 {
    int unit = conp->vc_num;
    struct display *p = &disp[unit];
@@ -1444,17 +1505,17 @@ static int fbcon_putc(struct vc_data *conp, int c, int y, int x)
    if (!p->can_soft_blank && console_blanked)
       return(0);
 
-   if ((p->cursor_x == x) && (p->cursor_y == y))
+   if ((p->cursor_x == xx) && (p->cursor_y == yy))
        CURSOR_UNDRAWN();
 
-   p->dispsw->putc(conp, p, c, real_y(p, y), x);
+   p->dispsw->putc(conp, p, c, real_y(p, yy), xx);
 
    return(0);
 }
 
 
-static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
-                       int x)
+static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int yy,
+                       int xx)
 {
    int unit = conp->vc_num;
    struct display *p = &disp[unit];
@@ -1462,10 +1523,10 @@ static int fbcon_putcs(struct vc_data *conp, const char *s, int count, int y,
    if (!p->can_soft_blank && console_blanked)
       return(0);
 
-   if ((p->cursor_y == y) && (x <= p->cursor_x) && (p->cursor_x < x+count))
+   if ((p->cursor_y == yy) && (xx <= p->cursor_x) && (p->cursor_x < xx+count))
       CURSOR_UNDRAWN();
 
-   p->dispsw->putcs(conp, p, s, count, real_y(p, y), x);
+   p->dispsw->putcs(conp, p, s, count, real_y(p, yy), xx);
 
    return(0);
 }
@@ -1520,6 +1581,62 @@ static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
 }
 
 
+static __inline__ void ywrap_up(int unit, struct display *p, int count)
+{
+   p->yscroll += count;
+   if (p->yscroll >= p->vrows) /* Deal with wrap */
+      p->yscroll -= p->vrows;
+   p->var.xoffset = 0;
+   p->var.yoffset = p->yscroll*p->fontheight;
+   p->var.vmode |= FB_VMODE_YWRAP;
+   fb_info->updatevar(unit);
+}
+
+
+static __inline__ void ywrap_down(int unit, struct display *p, int count)
+{
+   p->yscroll -= count;
+   if (p->yscroll < 0)         /* Deal with wrap */
+      p->yscroll += p->vrows;
+   p->var.xoffset = 0;
+   p->var.yoffset = p->yscroll*p->fontheight;
+   p->var.vmode |= FB_VMODE_YWRAP;
+   fb_info->updatevar(unit);
+}
+
+
+static __inline__ void ypan_up(int unit, struct vc_data *conp,
+                              struct display *p, int count)
+{
+   p->yscroll += count;
+   if (p->yscroll+conp->vc_rows > p->vrows) {
+      p->dispsw->bmove(p, p->yscroll, 0, 0, 0, conp->vc_rows-count,
+                      conp->vc_cols);
+      p->yscroll = 0;
+   }
+   p->var.xoffset = 0;
+   p->var.yoffset = p->yscroll*p->fontheight;
+   p->var.vmode &= ~FB_VMODE_YWRAP;
+   fb_info->updatevar(unit);
+}
+
+
+static __inline__ void ypan_down(int unit, struct vc_data *conp,
+                                struct display *p, int count)
+{
+   p->yscroll -= count;
+   if (p->yscroll < 0) {
+      p->yscroll = p->vrows-conp->vc_rows;
+      p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, conp->vc_rows-count,
+                      conp->vc_cols);
+   }
+   p->var.xoffset = 0;
+   p->var.yoffset = p->yscroll*p->fontheight;
+   p->var.vmode &= ~FB_VMODE_YWRAP;
+   fb_info->updatevar(unit);
+}
+
+
 static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
 {
    int unit = conp->vc_num;
@@ -1536,84 +1653,98 @@ static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
 
    switch (dir) {
       case SM_UP:
-         if (t == 0 && b == conp->vc_rows &&
-             vt_cons[unit]->vc_mode == KD_TEXT) {
-            if (count > conp->vc_rows)             /* Maximum realistic size */
-               count = conp->vc_rows;
-            switch (p->scrollmode) {
-               case SCROLL_YWRAP:
-                  p->yscroll += count;
-                  if (p->yscroll >= p->vrows) /* Deal with wrap */
-                     p->yscroll -= p->vrows;
-                  p->var.xoffset = 0;
-                  p->var.yoffset = p->yscroll*p->fontheight;
-                  p->var.vmode |= FB_VMODE_YWRAP;
-                  fb_info->updatevar(unit);
-                  break;
-
-               case SCROLL_YPAN:
-                  p->yscroll += count;
-                  if (p->yscroll+conp->vc_rows > p->vrows) {
-                     p->dispsw->bmove(p, p->yscroll, 0, 0, 0, b-count,
-                                      conp->vc_cols);
-                     p->yscroll = 0;
-                  }
-                  p->var.xoffset = 0;
-                  p->var.yoffset = p->yscroll*p->fontheight;
-                  p->var.vmode &= ~FB_VMODE_YWRAP;
-                  fb_info->updatevar(unit);
-                  break;
-
-               case SCROLL_YMOVE:
-                  p->dispsw->bmove(p, count, 0, 0, 0, b-count, conp->vc_cols);
-                  break;
-            }
-         } else
-            fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
-         fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+        if (count > conp->vc_rows)     /* Maximum realistic size */
+           count = conp->vc_rows;
+        if (vt_cons[unit]->vc_mode == KD_TEXT)
+           switch (p->scrollmode) {
+              case SCROLL_YWRAP:
+                 if (b-t-count > 3*conp->vc_rows>>2) {
+                    if (t > 0)
+                       fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols);
+                    ywrap_up(unit, p, count);
+                    if (conp->vc_rows-b > 0)
+                       fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b,
+                                   conp->vc_cols);
+                 } else
+                    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
+                                conp->vc_cols);
+                 fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+                 break;
+
+              case SCROLL_YPAN:
+                 if (b-t-count > 3*conp->vc_rows>>2) {
+                    if (t > 0)
+                       fbcon_bmove(conp, 0, 0, count, 0, t, conp->vc_cols);
+                    ypan_up(unit, conp, p, count);
+                    if (conp->vc_rows-b > 0)
+                       fbcon_bmove(conp, b-count, 0, b, 0, conp->vc_rows-b,
+                                   conp->vc_cols);
+                 } else
+                    fbcon_bmove(conp, t+count, 0, t, 0, b-t-count,
+                                conp->vc_cols);
+                 fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+                 break;
+
+              case SCROLL_YMOVE:
+                 p->dispsw->bmove(p, t+count, 0, t, 0, b-t-count,
+                                  conp->vc_cols);
+                 p->dispsw->clear(conp, p, b-count, 0, count, conp->vc_cols);
+                 break;
+           }
+        else {
+           fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
+           fbcon_clear(conp, b-count, 0, count, conp->vc_cols);
+        }
          break;
 
       case SM_DOWN:
-         if (t == 0 && b == conp->vc_rows &&
-             vt_cons[unit]->vc_mode == KD_TEXT) {
-            if (count > conp->vc_rows)             /* Maximum realistic size */
-               count = conp->vc_rows;
-            switch (p->scrollmode) {
-               case SCROLL_YWRAP:
-                  p->yscroll -= count;
-                  if (p->yscroll < 0)              /* Deal with wrap */
-                     p->yscroll += p->vrows;
-                  p->var.xoffset = 0;
-                  p->var.yoffset = p->yscroll*p->fontheight;
-                  p->var.vmode |= FB_VMODE_YWRAP;
-                  fb_info->updatevar(unit);
-                  break;
-
-               case SCROLL_YPAN:
-                  p->yscroll -= count;
-                  if (p->yscroll < 0) {
-                     p->yscroll = p->vrows-conp->vc_rows;
-                     p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, b-count,
-                                      conp->vc_cols);
-                  }
-                  p->var.xoffset = 0;
-                  p->var.yoffset = p->yscroll*p->fontheight;
-                  p->var.vmode &= ~FB_VMODE_YWRAP;
-                  fb_info->updatevar(unit);
-                  break;
-
-               case SCROLL_YMOVE:
-                  p->dispsw->bmove(p, 0, 0, count, 0, b-count, conp->vc_cols);
-                  break;
-            }
-         } else
-            fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
-
-         /* Fixed bmove() should end Arno's frustration with copying?
-          * Confucius says:
-          *    Man who copies in wrong direction, end up with trashed data
-          */
-         fbcon_clear(conp, t, 0, count, conp->vc_cols);
+        if (count > conp->vc_rows)     /* Maximum realistic size */
+           count = conp->vc_rows;
+        if (vt_cons[unit]->vc_mode == KD_TEXT)
+           switch (p->scrollmode) {
+              case SCROLL_YWRAP:
+                 if (b-t-count > 3*conp->vc_rows>>2) {
+                    if (conp->vc_rows-b > 0)
+                       fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b,
+                                   conp->vc_cols);
+                    ywrap_down(unit, p, count);
+                    if (t > 0)
+                       fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols);
+                 } else
+                    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
+                                conp->vc_cols);
+                 fbcon_clear(conp, t, 0, count, conp->vc_cols);
+                 break;
+
+              case SCROLL_YPAN:
+                 if (b-t-count > 3*conp->vc_rows>>2) {
+                    if (conp->vc_rows-b > 0)
+                       fbcon_bmove(conp, b, 0, b-count, 0, conp->vc_rows-b,
+                                   conp->vc_cols);
+                    ypan_down(unit, conp, p, count);
+                    if (t > 0)
+                       fbcon_bmove(conp, count, 0, 0, 0, t, conp->vc_cols);
+                 } else
+                    fbcon_bmove(conp, t, 0, t+count, 0, b-t-count,
+                                conp->vc_cols);
+                 fbcon_clear(conp, t, 0, count, conp->vc_cols);
+                 break;
+
+              case SCROLL_YMOVE:
+                 p->dispsw->bmove(p, t, 0, t+count, 0, b-t-count,
+                                  conp->vc_cols);
+                 p->dispsw->clear(conp, p, t, 0, count, conp->vc_cols);
+                 break;
+           }
+        else {
+           /*
+            * Fixed bmove() should end Arno's frustration with copying?
+            * Confucius says:
+            *    Man who copies in wrong direction, end up with trashed data
+            */
+           fbcon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
+           fbcon_clear(conp, t, 0, count, conp->vc_cols);
+        }
          break;
 
       case SM_LEFT:
@@ -1832,14 +1963,7 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
                /* Adjust the virtual screen-size to fontheight*rows */
                p->var.yres_virtual = (p->var.yres/h)*h;
                p->vrows = p->var.yres_virtual/h;
-               if (divides(p->ywrapstep, p->fontheight))
-                       p->scrollmode = SCROLL_YWRAP;
-               else if (divides(p->ypanstep, p->fontheight) &&
-                                p->var.yres_virtual >= p->var.yres+p->fontheight)
-                       p->scrollmode = SCROLL_YPAN;
-               else
-                       p->scrollmode = SCROLL_YMOVE;
-
+               updatescrollmode(p);
                vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
        }
        else if (unit == fg_console)
@@ -1854,6 +1978,38 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
        return( 0 );
 }
 
+static unsigned short palette_red[16];
+static unsigned short palette_green[16];
+static unsigned short palette_blue[16];
+
+static struct fb_cmap palette_cmap  = {
+    0, 16, palette_red, palette_green, palette_blue, NULL
+};
+
+static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
+{
+    int unit = conp->vc_num;
+    struct display *p = &disp[unit];
+    int i, j, k;
+    u_char val;
+
+    if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked))
+       return(-EINVAL);
+    for (i = j = 0; i < 16; i++) {
+       k = table[i];
+       val = conp->vc_palette[j++];
+       palette_red[k] = (val<<8)|val;
+       val = conp->vc_palette[j++];
+       palette_green[k] = (val<<8)|val;
+       val = conp->vc_palette[j++];
+       palette_blue[k] = (val<<8)|val;
+    }
+    palette_cmap.len = 1<<p->var.bits_per_pixel;
+    if (palette_cmap.len > 16)
+       palette_cmap.len = 16;
+    return(fb_info->setcmap(&palette_cmap, unit));
+}
+
 
 /* ====================================================================== */
 
@@ -1882,8 +2038,8 @@ static void bmove_mono(struct display *p, int sy, int sx, int dy, int dx,
    u_char *src, *dest;
    u_int rows;
 
-   if (sx == 0 && sy == 0 && width == p->next_line) {
-      src = p->screen_base;
+   if (sx == 0 && dx == 0 && width == p->next_line) {
+      src = p->screen_base+sy*p->fontheight*width;
       dest = p->screen_base+dy*p->fontheight*width;
       mymemmove(dest, src, height*p->fontheight*width);
    } else if (dy <= sy) {
@@ -1928,28 +2084,28 @@ static void clear_mono(struct vc_data *conp, struct display *p, int sy, int sx,
 }
 
 
-static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
-                      int x)
+static void putc_mono(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
 {
    u_char *dest, *cdat;
-   u_int rows, bold, reverse, underline;
+   u_int rows, bold, revs, underl;
    u_char d;
 
    c &= 0xff;
 
-   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest = p->screen_base + yy*p->fontheight*p->next_line + xx;
    cdat = p->fontdata+c*p->fontheight;
    bold = attr_bold(p,conp);
-   reverse = attr_reverse(p,conp);
-   underline = attr_underline(p,conp);
+   revs = attr_reverse(p,conp);
+   underl = attr_underline(p,conp);
 
    for (rows = p->fontheight; rows--; dest += p->next_line) {
       d = *cdat++;
-      if (underline && !rows)
+      if (underl && !rows)
          d = 0xff;
       else if (bold)
          d |= d>>1;
-      if (reverse)
+      if (revs)
          d = ~d;
       *dest = d;
    }
@@ -1957,16 +2113,16 @@ static void putc_mono(struct vc_data *conp, struct display *p, int c, int y,
 
 
 static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x)
+                       int count, int yy, int xx)
 {
    u_char *dest, *dest0, *cdat;
-   u_int rows, bold, reverse, underline;
+   u_int rows, bold, revs, underl;
    u_char c, d;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    bold = attr_bold(p,conp);
-   reverse = attr_reverse(p,conp);
-   underline = attr_underline(p,conp);
+   revs = attr_reverse(p,conp);
+   underl = attr_underline(p,conp);
 
    while (count--) {
       c = *s++;
@@ -1974,11 +2130,11 @@ static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
       cdat = p->fontdata+c*p->fontheight;
       for (rows = p->fontheight; rows--; dest += p->next_line) {
          d = *cdat++;
-         if (underline && !rows)
+         if (underl && !rows)
             d = 0xff;
          else if (bold)
             d |= d>>1;
-         if (reverse)
+         if (revs)
             d = ~d;
          *dest = d;
       }
@@ -1986,12 +2142,12 @@ static void putcs_mono(struct vc_data *conp, struct display *p, const char *s,
 }
 
 
-static void rev_char_mono(struct display *p, int x, int y)
+static void rev_char_mono(struct display *p, int xx, int yy)
 {
    u_char *dest;
    u_int rows;
 
-   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest = p->screen_base + yy*p->fontheight*p->next_line + xx;
    for (rows = p->fontheight; rows--; dest += p->next_line)
       *dest = ~*dest;
 }
@@ -2017,8 +2173,9 @@ static void rev_char_mono(struct display *p, int x, int y)
 static void bmove_ilbm(struct display *p, int sy, int sx, int dy, int dx,
                        int height, int width)
 {
-   if (sx == 0 && sy == 0 && width == p->next_plane)
-      mymemmove(p->screen_base+dy*p->fontheight*p->next_line, p->screen_base,
+   if (sx == 0 && dx == 0 && width == p->next_plane)
+      mymemmove(p->screen_base+dy*p->fontheight*p->next_line,
+               p->screen_base+sy*p->fontheight*p->next_line,
                 height*p->fontheight*p->next_line);
    else {
       u_char *src, *dest;
@@ -2068,8 +2225,8 @@ static void clear_ilbm(struct vc_data *conp, struct display *p, int sy, int sx,
 }
 
 
-static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
-                      int x)
+static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
 {
    u_char *dest, *cdat;
    u_int rows, i;
@@ -2078,7 +2235,7 @@ static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
 
    c &= 0xff;
 
-   dest = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest = p->screen_base + yy*p->fontheight*p->next_line + xx;
    cdat = p->fontdata+c*p->fontheight;
    fg0 = attr_fgcol(p,conp);
    bg0 = attr_bgcol(p,conp);
@@ -2114,14 +2271,14 @@ static void putc_ilbm(struct vc_data *conp, struct display *p, int c, int y,
  *                      address, to reduce the number of expensive Chip RAM
  *                      accesses.
  *
- *    Experiments on my A4000/040 revealed that this makes a console switch on a
- *    640x400 screen with 256 colors about 3 times faster.
+ *    Experiments on my A4000/040 revealed that this makes a console
+ *    switch on a 640x400 screen with 256 colors about 3 times faster.
  *
  *                                                                Geert
  */
 
 static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x)
+                       int count, int yy, int xx)
 {
    u_char *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
    u_int rows, i;
@@ -2129,15 +2286,15 @@ static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
    u_long d;
    int fg0, bg0, fg, bg;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    fg0 = attr_fgcol(p,conp);
    bg0 = attr_bgcol(p,conp);
 
    while (count--)
-      if (x&3 || count < 3) {   /* Slow version */
+      if (xx & 3 || count < 3) {   /* Slow version */
          c1 = *s++;
          dest = dest0++;
-         x++;
+         xx++;
 
          cdat1 = p->fontdata+c1*p->fontheight;
          for (rows = p->fontheight; rows--;) {
@@ -2191,19 +2348,19 @@ static void putcs_ilbm(struct vc_data *conp, struct display *p, const char *s,
          }
          s += 4;
          dest0 += 4;
-         x += 4;
+         xx += 4;
          count -= 3;
       }
 }
 
 
-static void rev_char_ilbm(struct display *p, int x, int y)
+static void rev_char_ilbm(struct display *p, int xx, int yy)
 {
    u_char *dest, *dest0;
    u_int rows, i;
    int mask;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    mask = p->fgcol ^ p->bgcol;
 
    /*
@@ -2239,8 +2396,8 @@ static void bmove_plan(struct display *p, int sy, int sx, int dy, int dx,
    u_char *src, *dest, *src0, *dest0;
    u_int i, rows;
 
-   if (sx == 0 && sy == 0 && width == p->next_line) {
-      src = p->screen_base;
+   if (sx == 0 && dx == 0 && width == p->next_line) {
+      src = p->screen_base+sy*p->fontheight*width;
       dest = p->screen_base+dy*p->fontheight*width;
       for (i = p->var.bits_per_pixel; i--;) {
          mymemmove(dest, src, height*p->fontheight*width);
@@ -2301,8 +2458,8 @@ static void clear_plan(struct vc_data *conp, struct display *p, int sy, int sx,
 }
 
 
-static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
-                      int x)
+static void putc_plan(struct vc_data *conp, struct display *p, int c, int yy,
+                      int xx)
 {
    u_char *dest, *dest0, *cdat, *cdat0;
    u_int rows, i;
@@ -2311,7 +2468,7 @@ static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
 
    c &= 0xff;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    cdat0 = p->fontdata+c*p->fontheight;
    fg = attr_fgcol(p,conp);
    bg = attr_bgcol(p,conp);
@@ -2344,7 +2501,7 @@ static void putc_plan(struct vc_data *conp, struct display *p, int c, int y,
  */
 
 static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
-                       int count, int y, int x)
+                       int count, int yy, int xx)
 {
    u_char *dest, *dest0, *dest1;
    u_char *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
@@ -2353,15 +2510,15 @@ static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
    u_long d;
    int fg0, bg0, fg, bg;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    fg0 = attr_fgcol(p,conp);
    bg0 = attr_bgcol(p,conp);
 
    while (count--)
-      if (x&3 || count < 3) {   /* Slow version */
+      if (xx & 3 || count < 3) {   /* Slow version */
          c1 = *s++;
          dest1 = dest0++;
-         x++;
+         xx++;
 
          cdat10 = p->fontdata+c1*p->fontheight;
          fg = fg0;
@@ -2424,19 +2581,19 @@ static void putcs_plan(struct vc_data *conp, struct display *p, const char *s,
          }
          s += 4;
          dest0 += 4;
-         x += 4;
+         xx += 4;
          count -= 3;
       }
 }
 
 
-static void rev_char_plan(struct display *p, int x, int y)
+static void rev_char_plan(struct display *p, int xx, int yy)
 {
    u_char *dest, *dest0;
    u_int rows, i;
    int mask;
 
-   dest0 = p->screen_base+y*p->fontheight*p->next_line+x;
+   dest0 = p->screen_base + yy*p->fontheight*p->next_line + xx;
    mask = p->fgcol ^ p->bgcol;
 
    /*
@@ -2499,8 +2656,8 @@ static void bmove_2_plane(struct display *p, int sy, int sx, int dy, int dx,
                 * done with memmove()
                 */
                mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
-                                  p->screen_base + sy * p->next_line * p->fontheight,
-                                  p->next_line * height * p->fontheight);
+                         p->screen_base + sy * p->next_line * p->fontheight,
+                         p->next_line * height * p->fontheight);
     } else {
         int rows, cols;
         u_char *src;
@@ -2607,8 +2764,8 @@ static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
     int bytes = p->next_line;
     int lines = height * p->fontheight;
     ulong  size;
-       u_long          cval;
-       u_short                 pcval;
+    u_long          cval;
+    u_short                    pcval;
 
     cval = expand2l (COLOR_2P (attr_bgcol_ec(p,conp)));
 
@@ -2650,43 +2807,45 @@ static void clear_2_plane(struct vc_data *conp, struct display *p, int sy,
 }
 
 
-static void putc_2_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x)
+static void putc_2_plane(struct vc_data *conp, struct display *p, int
+                        c, int yy, int xx)
 {
-   u_char   *dest;
-    u_char   *cdat;
-    int rows;
-    int bytes = p->next_line;
-       ulong                     eorx, fgx, bgx, fdx;
+       u_char   *dest;
+       u_char   *cdat;
+       int rows;
+       int bytes = p->next_line;
+       ulong    eorx, fgx, bgx, fdx;
 
        c &= 0xff;
 
-    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
-    cdat  = p->fontdata + (c * p->fontheight);
+       dest  = p->screen_base + yy * p->fontheight * bytes +
+               (xx >> 1)*4 + (xx & 1);
+       cdat  = p->fontdata + (c * p->fontheight);
 
        fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
        bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
        eorx  = fgx ^ bgx;
 
-    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+       for(rows = p->fontheight ; rows-- ; dest += bytes) {
                fdx = dup2w(*cdat++);
                __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
-                                                          : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+                                     : "a" (dest), "d" ((fdx & eorx) ^ bgx));
        }
 }
 
 
 static void putcs_2_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x)
+                          const char *s, int count, int yy, int xx)
 {
        u_char   *dest, *dest0;
-    u_char   *cdat, c;
-    int rows;
-    int bytes;
-       ulong                     eorx, fgx, bgx, fdx;
-
-    bytes = p->next_line;
-    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*4 + (x & 1);
+       u_char   *cdat, c;
+       int rows;
+       int bytes;
+       ulong    eorx, fgx, bgx, fdx;
+
+       bytes = p->next_line;
+       dest0 = p->screen_base + yy * p->fontheight * bytes
+               + (xx >> 1)*4 + (xx & 1);
        fgx   = expand2w(COLOR_2P(attr_fgcol(p,conp)));
        bgx   = expand2w(COLOR_2P(attr_bgcol(p,conp)));
        eorx  = fgx ^ bgx;
@@ -2699,32 +2858,33 @@ static void putcs_2_plane(struct vc_data *conp, struct display *p,
                for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
                        fdx = dup2w(*cdat++);
                        __asm__ __volatile__ ("movepw %1,%0@(0)" : /* no outputs */
-                                                                  : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+                                             : "a" (dest), "d" ((fdx & eorx) ^ bgx));
                }
                INC_2P(dest0);
        }
 }
 
 
-static void rev_char_2_plane(struct display *p, int x, int y)
+static void rev_char_2_plane(struct display *p, int xx, int yy)
 {
-   u_char *dest;
-   int j;
-   int bytes;
-
-   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*4 + (x & 1);
-   j = p->fontheight;
-   bytes = p->next_line;
-   while (j--)
-     {
-      /* This should really obey the individual character's
-       * background and foreground colors instead of simply
-       * inverting.
-       */
-       dest[0] = ~dest[0];
-       dest[2] = ~dest[2];
-       dest += bytes;
-     }
+       u_char *dest;
+       int j;
+       int bytes;
+
+       dest = p->screen_base + yy * p->fontheight * p->next_line +
+               (xx >> 1)*4 + (xx & 1);
+       j = p->fontheight;
+       bytes = p->next_line;
+       while (j--)
+       {
+               /* This should really obey the individual character's
+                * background and foreground colors instead of simply
+                * inverting.
+                */
+               dest[0] = ~dest[0];
+               dest[2] = ~dest[2];
+               dest += bytes;
+       }
 }
 #endif /* CONFIG_FBCON_2PLANE */
 
@@ -2763,8 +2923,8 @@ static void bmove_4_plane(struct display *p, int sy, int sx, int dy, int dx,
                 * done with memmove()
                 */
                mymemmove(p->screen_base + dy * p->next_line * p->fontheight,
-                                  p->screen_base + sy * p->next_line * p->fontheight,
-                                  p->next_line * height * p->fontheight);
+                         p->screen_base + sy * p->next_line * p->fontheight,
+                         p->next_line * height * p->fontheight);
     } else {
         int rows, cols;
         u_char *src;
@@ -2871,9 +3031,9 @@ static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
     int bytes = p->next_line;
     int lines = height * p->fontheight;
     ulong  size;
-       u_long          cval1, cval2, pcval;
+    u_long          cval1, cval2, pcval;
 
-       expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
+    expand4dl(attr_bgcol_ec(p,conp), &cval1, &cval2);
 
     if (sx == 0 && width == bytes/4) {
 
@@ -2913,43 +3073,45 @@ static void clear_4_plane(struct vc_data *conp, struct display *p, int sy,
 }
 
 
-static void putc_4_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x)
+static void putc_4_plane(struct vc_data *conp, struct display *p, int
+                        c, int yy, int xx)
 {
        u_char   *dest;
-    u_char   *cdat;
-    int rows;
-    int bytes = p->next_line;
-       ulong                     eorx, fgx, bgx, fdx;
+       u_char   *cdat;
+       int rows;
+       int bytes = p->next_line;
+       ulong     eorx, fgx, bgx, fdx;
 
        c &= 0xff;
 
-    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
-    cdat  = p->fontdata + (c * p->fontheight);
+       dest  = p->screen_base + yy * p->fontheight * bytes +
+               (xx >> 1)*8 + (xx & 1);
+       cdat  = p->fontdata + (c * p->fontheight);
 
        fgx   = expand4l(attr_fgcol(p,conp));
        bgx   = expand4l(attr_bgcol(p,conp));
        eorx  = fgx ^ bgx;
 
-    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+       for(rows = p->fontheight ; rows-- ; dest += bytes) {
                fdx = dup4l(*cdat++);
                __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
-                                                          : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+                                     : "a" (dest), "d" ((fdx & eorx) ^ bgx));
        }
 }
 
 
 static void putcs_4_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x)
+                          const char *s, int count, int yy, int xx)
 {
        u_char   *dest, *dest0;
-    u_char   *cdat, c;
-    int rows;
-    int bytes;
-       ulong                     eorx, fgx, bgx, fdx;
-
-    bytes = p->next_line;
-    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*8 + (x & 1);
+       u_char   *cdat, c;
+       int rows;
+       int bytes;
+       ulong     eorx, fgx, bgx, fdx;
+
+       bytes = p->next_line;
+       dest0 = p->screen_base + yy * p->fontheight * bytes
+               + (xx >> 1)*8 + (xx & 1);
        fgx   = expand4l(attr_fgcol(p,conp));
        bgx   = expand4l(attr_bgcol(p,conp));
        eorx  = fgx ^ bgx;
@@ -2969,20 +3131,21 @@ static void putcs_4_plane(struct vc_data *conp, struct display *p,
                for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
                        fdx = dup4l(*cdat++);
                        __asm__ __volatile__ ("movepl %1,%0@(0)" : /* no outputs */
-                                                                  : "a" (dest), "d" ((fdx & eorx) ^ bgx));
+                                             : "a" (dest), "d" ((fdx & eorx) ^ bgx));
                }
                INC_4P(dest0);
        }
 }
 
 
-static void rev_char_4_plane(struct display *p, int x, int y)
+static void rev_char_4_plane(struct display *p, int xx, int yy)
 {
    u_char *dest;
    int j;
    int bytes;
 
-   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*8 + (x & 1);
+   dest = p->screen_base + yy * p->fontheight * p->next_line +
+          (xx >> 1)*8 + (xx & 1);
    j = p->fontheight;
    bytes = p->next_line;
 
@@ -3150,15 +3313,16 @@ static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
     int bytes = p->next_line;
     int lines = height * p->fontheight;
     ulong  size;
-       u_long          cval1, cval2, cval3, cval4, pcval1, pcval2;
+    u_long          cval1, cval2, cval3, cval4, pcval1, pcval2;
 
-       expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4);
+    expand8ql(attr_bgcol_ec(p,conp), cval1, cval2, cval3, cval4);
 
     if (sx == 0 && width == bytes/8) {
 
         offset = sy * bytes * p->fontheight;
         size   = lines * bytes;
-               memset_even_8p(p->screen_base+offset, size, cval1, cval2, cval3, cval4);
+               memset_even_8p(p->screen_base+offset, size, cval1,
+                              cval2, cval3, cval4);
 
     } else {
 
@@ -3193,48 +3357,50 @@ static void clear_8_plane(struct vc_data *conp, struct display *p, int sy,
 }
 
 
-static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int y,
-                         int x)
+static void putc_8_plane(struct vc_data *conp, struct display *p, int c, int yy,
+                         int xx)
 {
        u_char   *dest;
-    u_char   *cdat;
-    int rows;
-    int bytes = p->next_line;
-       ulong                     eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+       u_char   *cdat;
+       int rows;
+       int bytes = p->next_line;
+       ulong     eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
 
        c &= 0xff;
 
-    dest  = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
-    cdat  = p->fontdata + (c * p->fontheight);
+       dest  = p->screen_base + yy * p->fontheight * bytes +
+               (xx >> 1)*16 + (xx & 1);
+       cdat  = p->fontdata + (c * p->fontheight);
 
        expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
        expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
        eorx1  = fgx1 ^ bgx1; eorx2  = fgx2 ^ bgx2;
 
-    for(rows = p->fontheight ; rows-- ; dest += bytes) {
+       for(rows = p->fontheight ; rows-- ; dest += bytes) {
                fdx = dup4l(*cdat++);
                __asm__ __volatile__
                        ("movepl %1,%0@(0)\n\t"
-                         "movepl %2,%0@(8)"
-                         : /* no outputs */
-                         : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
-                           "d" ((fdx & eorx2) ^ bgx2)
+                        "movepl %2,%0@(8)"
+                        : /* no outputs */
+                        : "a" (dest), "d" ((fdx & eorx1) ^ bgx1),
+                        "d" ((fdx & eorx2) ^ bgx2)
                        );
        }
 }
 
 
 static void putcs_8_plane(struct vc_data *conp, struct display *p,
-                          const char *s, int count, int y, int x)
+                          const char *s, int count, int yy, int xx)
 {
        u_char   *dest, *dest0;
-    u_char   *cdat, c;
-    int rows;
-    int bytes;
-       ulong                     eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
+       u_char   *cdat, c;
+       int rows;
+       int bytes;
+       ulong     eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
 
-    bytes = p->next_line;
-    dest0 = p->screen_base + y * p->fontheight * bytes + (x>>1)*16 + (x & 1);
+       bytes = p->next_line;
+       dest0 = p->screen_base + yy * p->fontheight * bytes
+               + (xx >> 1)*16 + (xx & 1);
 
        expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
        expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
@@ -3267,30 +3433,31 @@ static void putcs_8_plane(struct vc_data *conp, struct display *p,
 }
 
 
-static void rev_char_8_plane(struct display *p, int x, int y)
+static void rev_char_8_plane(struct display *p, int xx, int yy)
 {
-   u_char *dest;
-   int j;
-   int bytes;
-
-   dest = p->screen_base + y * p->fontheight * p->next_line + (x>>1)*16 + (x & 1);
-   j = p->fontheight;
-   bytes = p->next_line;
-
-   while (j--)
-     {
-      /* This should really obey the individual character's
-       * background and foreground colors instead of simply
-       * inverting. For 8 plane mode, only the lower 4 bits of the
-       * color are inverted, because only that color registers have
-       * been set up.
-       */
-       dest[0] = ~dest[0];
-       dest[2] = ~dest[2];
-       dest[4] = ~dest[4];
-       dest[6] = ~dest[6];
-       dest += bytes;
-     }
+       u_char *dest;
+       int j;
+       int bytes;
+
+       dest = p->screen_base + yy * p->fontheight * p->next_line
+               + (xx >> 1)*16 + (xx & 1);
+       j = p->fontheight;
+       bytes = p->next_line;
+
+       while (j--)
+       {
+               /* This should really obey the individual character's
+                * background and foreground colors instead of simply
+                * inverting. For 8 plane mode, only the lower 4 bits of the
+                * color are inverted, because only that color registers have
+                * been set up.
+                */
+               dest[0] = ~dest[0];
+               dest[2] = ~dest[2];
+               dest[4] = ~dest[4];
+               dest[6] = ~dest[6];
+               dest += bytes;
+       }
 }
 #endif /* CONFIG_FBCON_8PLANE */
 
@@ -3378,8 +3545,8 @@ static void clear_8_packed(struct vc_data *conp, struct display *p, int sy,
 }
 
 
-static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
-                          int x)
+static void putc_8_packed(struct vc_data *conp, struct display *p, int c,
+                         int yy, int xx)
 {
        u_char *dest,*cdat;
        int bytes=p->next_line,rows;
@@ -3387,7 +3554,7 @@ static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
 
        c &= 0xff;
 
-       dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+       dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
        cdat = p->fontdata + c * p->fontheight;
 
        fgx=attr_fgcol(p,conp);
@@ -3408,13 +3575,13 @@ static void putc_8_packed(struct vc_data *conp, struct display *p, int c, int y,
 
 
 static void putcs_8_packed(struct vc_data *conp, struct display *p,
-                           const char *s, int count, int y, int x)
+                           const char *s, int count, int yy, int xx)
 {
        u_char *cdat, c, *dest, *dest0;
        int rows,bytes=p->next_line;
        u_long eorx, fgx, bgx;
 
-       dest0 = p->screen_base + y * p->fontheight * bytes + x * 8;
+       dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8;
        fgx=attr_fgcol(p,conp);
        bgx=attr_bgcol(p,conp);
        fgx |= (fgx << 8);
@@ -3437,12 +3604,12 @@ static void putcs_8_packed(struct vc_data *conp, struct display *p,
 }
 
 
-static void rev_char_8_packed(struct display *p, int x, int y)
+static void rev_char_8_packed(struct display *p, int xx, int yy)
 {
        u_char *dest;
        int bytes=p->next_line, rows;
 
-       dest = p->screen_base + y * p->fontheight * bytes + x * 8;
+       dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
        for (rows = p->fontheight ; rows-- ; dest += bytes) {
                ((u_long *)dest)[0] ^= 0x0f0f0f0f;
                ((u_long *)dest)[1] ^= 0x0f0f0f0f;
@@ -3539,7 +3706,7 @@ static void clear_16_packed(struct vc_data *conp, struct display *p, int sy,
 
 
 static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
-                           int y, int x)
+                           int yy, int xx)
 {
        u_char *dest,*cdat;
        int bytes=p->next_line,rows;
@@ -3547,7 +3714,7 @@ static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
 
        c &= 0xff;
 
-       dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+       dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
        cdat = p->fontdata + c * p->fontheight;
 
        fgx = attr_fgcol(p,conp);
@@ -3573,13 +3740,13 @@ static void putc_16_packed(struct vc_data *conp, struct display *p, int c,
 
 /* TODO */
 static void putcs_16_packed(struct vc_data *conp, struct display *p,
-                            const char *s, int count, int y, int x)
+                            const char *s, int count, int yy, int xx)
 {
        u_char *cdat, c, *dest, *dest0;
        int rows,bytes=p->next_line;
        u_long eorx, fgx, bgx;
 
-       dest0 = p->screen_base + y * p->fontheight * bytes + x * 16;
+       dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16;
        fgx = attr_fgcol(p,conp);
        fgx = packed16_cmap[fgx];
        bgx = attr_bgcol(p,conp);
@@ -3606,12 +3773,12 @@ static void putcs_16_packed(struct vc_data *conp, struct display *p,
 }
 
 
-static void rev_char_16_packed(struct display *p, int x, int y)
+static void rev_char_16_packed(struct display *p, int xx, int yy)
 {
        u_char *dest;
        int bytes=p->next_line, rows;
 
-       dest = p->screen_base + y * p->fontheight * bytes + x * 16;
+       dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
        for (rows = p->fontheight ; rows-- ; dest += bytes) {
                ((u_long *)dest)[0] ^= 0xffffffff;
                ((u_long *)dest)[1] ^= 0xffffffff;
@@ -3641,87 +3808,90 @@ static void bmove_cyber(struct display *p, int sy, int sx, int dy, int dx,
 }
 
 
-static void clear_cyber(struct vc_data *conp, struct display *p, int sy, int sx,
-                        int height, int width)
+static void clear_cyber(struct vc_data *conp, struct display *p, int
+                       sy, int sx, int height, int width)
 {
-   u_char bg;
+       unsigned char bg;
         
        sx *= 8; width *= 8;
        bg = attr_bgcol_ec(p,conp);
-   Cyber_RectFill((u_short)sx, (u_short)(sy*p->fontheight), (u_short)width,
-                  (u_short)(height*p->fontheight), (u_short)S3_NEW,
-                  (u_short)bg); 
+       Cyber_RectFill((u_short)sx,
+                      (u_short)(sy*p->fontheight),
+                      (u_short)width,
+                      (u_short)(height*p->fontheight),
+                      (u_short)S3_NEW, 
+                      (u_short)bg); 
 }
 
 
-static void putc_cyber(struct vc_data *conp, struct display *p, int c, int y,
-                       int x)
+static void putc_cyber(struct vc_data *conp, struct display *p, int c, int yy,
+                       int xx)
 {
        u_char *dest, *cdat;
        u_long tmp;
-       u_int rows, reverse, underline
+       u_int rows, revs, underl
        u_char d;
-   u_char fg, bg;
+       u_char fg, bg;
 
-   c &= 0xff;
+       c &= 0xff;
 
        dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
        cdat = p->fontdata+(c*p->fontheight);
-   fg = disp->fgcol;
-   bg = disp->bgcol;
-       reverse = conp->vc_reverse;
-       underline = conp->vc_underline;
+       fg = disp->fgcol;
+       bg = disp->bgcol;
+       revs = conp->vc_reverse;
+       underl = conp->vc_underline;
 
    Cyber_WaitBlit();
        for (rows = p->fontheight; rows--; dest += p->next_line) {
                d = *cdat++;
 
-               if (underline && !rows)
+               if (underl && !rows)
                        d = 0xff;
-               if (reverse)
+               if (revs)
                        d = ~d;
 
-      tmp =  ((d & 0x80) ? fg : bg) << 24;
-      tmp |= ((d & 0x40) ? fg : bg) << 16;
-      tmp |= ((d & 0x20) ? fg : bg) << 8;
-      tmp |= ((d & 0x10) ? fg : bg);
-      *((u_long*) dest) = tmp;
-      tmp =  ((d & 0x8) ? fg : bg) << 24;
-      tmp |= ((d & 0x4) ? fg : bg) << 16;
-      tmp |= ((d & 0x2) ? fg : bg) << 8;
-      tmp |= ((d & 0x1) ? fg : bg);
-      *((u_long*) dest + 1) = tmp;
+               tmp =  ((d & 0x80) ? fg : bg) << 24;
+               tmp |= ((d & 0x40) ? fg : bg) << 16;
+               tmp |= ((d & 0x20) ? fg : bg) << 8;
+               tmp |= ((d & 0x10) ? fg : bg);
+               *((u_long*) dest) = tmp;
+               tmp =  ((d & 0x8) ? fg : bg) << 24;
+               tmp |= ((d & 0x4) ? fg : bg) << 16;
+               tmp |= ((d & 0x2) ? fg : bg) << 8;
+               tmp |= ((d & 0x1) ? fg : bg);
+               *((u_long*) dest + 1) = tmp;
        }
 }
 
 
 static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
-                        int count, int y, int x)
+                        int count, int yy, int xx)
 {
        u_char *dest, *dest0, *cdat;
-   u_long tmp;
-       u_int rows, reverse, underline;
+       u_long tmp;
+       u_int rows, revs, underl;
        u_char c, d;
-   u_char fg, bg;
+       u_char fg, bg;
 
        dest0 = p->screen_base+y*p->fontheight*p->next_line+8*x;
-   fg = disp->fgcol;
-   bg = disp->bgcol;
-       reverse = conp->vc_reverse;
-       underline = conp->vc_underline;
+       fg = disp->fgcol;
+       bg = disp->bgcol;
+       revs = conp->vc_reverse;
+       underl = conp->vc_underline;
 
    Cyber_WaitBlit();
        while (count--) {
                c = *s++;
                dest = dest0;
-      dest0 += 8;
+               dest0 += 8;
                cdat = p->fontdata+(c*p->fontheight);
                for (rows = p->fontheight; rows--; dest += p->next_line) {
                        d = *cdat++;
 
-                       if (underline && !rows)
+                       if (underl && !rows)
                                d = 0xff;
-                       if (reverse)
+                       if (revs)
                                d = ~d;
 
          tmp =  ((d & 0x80) ? fg : bg) << 24;
@@ -3739,32 +3909,208 @@ static void putcs_cyber(struct vc_data *conp, struct display *p, const char *s,
 }
 
 
-static void rev_char_cyber(struct display *p, int x, int y)
+static void rev_char_cyber(struct display *p, int xx, int yy)
 {
-       u_char *dest;
-       u_int rows;
-   u_char fg, bg;
+       unsigned char *dest;
+       unsigned int rows;
+       unsigned char fg, bg;
 
-   fg = disp->fgcol;
-   bg = disp->bgcol;
+       fg = disp->fgcol;
+       bg = disp->bgcol;
 
        dest = p->screen_base+y*p->fontheight*p->next_line+8*x;
    Cyber_WaitBlit();
        for (rows = p->fontheight; rows--; dest += p->next_line) {
                *dest = (*dest == fg) ? bg : fg;
-      *(dest+1) = (*(dest + 1) == fg) ? bg : fg;
-      *(dest+2) = (*(dest + 2) == fg) ? bg : fg;
-      *(dest+3) = (*(dest + 3) == fg) ? bg : fg;
-      *(dest+4) = (*(dest + 4) == fg) ? bg : fg;
-      *(dest+5) = (*(dest + 5) == fg) ? bg : fg;
-      *(dest+6) = (*(dest + 6) == fg) ? bg : fg;
-      *(dest+7) = (*(dest + 7) == fg) ? bg : fg;
+               *(dest+1) = (*(dest + 1) == fg) ? bg : fg;
+               *(dest+2) = (*(dest + 2) == fg) ? bg : fg;
+               *(dest+3) = (*(dest + 3) == fg) ? bg : fg;
+               *(dest+4) = (*(dest + 4) == fg) ? bg : fg;
+               *(dest+5) = (*(dest + 5) == fg) ? bg : fg;
+               *(dest+6) = (*(dest + 6) == fg) ? bg : fg;
+               *(dest+7) = (*(dest + 7) == fg) ? bg : fg;
        }
 }
 
 #endif /* CONFIG_FBCON_CYBER */
 
 
+#ifdef CONFIG_FBCON_RETINAZ3
+
+/*
+ *    RetinaZ3 (accelerated)
+ */
+
+#define Z3BLTcopy              0xc0
+#define Z3BLTset               0xf0
+
+static void clear_retz3(struct vc_data *conp, struct display *p, int
+                       sy, int sx, int height, int width)
+{
+       unsigned short col;
+       int fontwidth = p->fontwidth;
+
+       sx *= fontwidth;
+       width *= fontwidth;
+
+       col = attr_bgcol_ec(p, conp);
+       col &= 0xff;
+       col |= (col << 8);
+
+       retz3_bitblt(&p->var,
+                    (unsigned short)sx,
+                    (unsigned short)(sy*p->fontheight),
+                    (unsigned short)sx,
+                    (unsigned short)(sy*p->fontheight),
+                    (unsigned short)width,
+                    (unsigned short)(height*p->fontheight),
+                    Z3BLTset,
+                    col); 
+}
+
+static void bmove_retz3(struct display *p, int sy, int sx, int dy, int dx,
+                        int height, int width)
+{
+       int fontwidth = p->fontwidth;
+
+       sx *= fontwidth;
+       dx *= fontwidth;
+       width *= fontwidth;
+
+       retz3_bitblt(&p->var,
+                    (unsigned short)sx,
+                    (unsigned short)(sy*p->fontheight),
+                    (unsigned short)dx,
+                    (unsigned short)(dy*p->fontheight),
+                    (unsigned short)width,
+                    (unsigned short)(height*p->fontheight),
+                    Z3BLTcopy,
+                    0xffff);
+}
+
+static void putc_retz3(struct vc_data *conp, struct display *p,
+                      int c, int yy, int xx)
+{
+       unsigned char *dest, *cdat;
+       unsigned long tmp;
+       unsigned int rows, revs, underl, bytes;
+       unsigned char d;
+       unsigned char fg, bg;
+   
+       c &= 0xff;
+
+       bytes = p->next_line;
+
+       dest = p->screen_base + yy*p->fontheight*bytes
+               + xx*p->var.bits_per_pixel;
+       cdat = p->fontdata + c * p->fontheight;
+
+       fg = disp->fgcol;
+       bg = disp->bgcol;
+       revs = conp->vc_reverse;
+       underl = conp->vc_underline;
+
+       for (rows = p->fontheight; rows--; dest += bytes) {
+               d = *cdat++;
+
+               if (underl && !rows)
+                       d = 0xff;
+               if (revs)
+                       d = ~d;
+
+               tmp =  ((d & 0x80) ? fg : bg) << 24;
+               tmp |= ((d & 0x40) ? fg : bg) << 16;
+               tmp |= ((d & 0x20) ? fg : bg) << 8;
+               tmp |= ((d & 0x10) ? fg : bg);
+               *((unsigned long*) dest) = tmp;
+               tmp =  ((d & 0x8) ? fg : bg) << 24;
+               tmp |= ((d & 0x4) ? fg : bg) << 16;
+               tmp |= ((d & 0x2) ? fg : bg) << 8;
+               tmp |= ((d & 0x1) ? fg : bg);
+               *((unsigned long*) dest + 1) = tmp;
+       }
+}
+
+
+static void putcs_retz3(struct vc_data *conp, struct display *p,
+                       const char *s, int count, int yy, int xx)
+{
+       unsigned char *dest, *dest0, *cdat;
+       unsigned long tmp;
+       unsigned int rows, revs, underl, bytes;
+       unsigned char c, d;
+       unsigned char fg, bg;
+
+       bytes = p->next_line;
+
+       dest0 = p->screen_base + yy*p->fontheight*bytes
+               + xx * p->var.bits_per_pixel;
+       fg = disp->fgcol;
+       bg = disp->bgcol;
+       revs = conp->vc_reverse;
+       underl = conp->vc_underline;
+
+       while (count--) {
+               c = *s++;
+               dest = dest0;
+               dest0 += 8;
+
+               cdat = p->fontdata + c * p->fontheight;
+               for (rows = p->fontheight; rows--; dest += bytes) {
+                       d = *cdat++;
+
+                       if (underl && !rows)
+                               d = 0xff;
+                       if (revs)
+                               d = ~d;
+
+                       tmp =  ((d & 0x80) ? fg : bg) << 24;
+                       tmp |= ((d & 0x40) ? fg : bg) << 16;
+                       tmp |= ((d & 0x20) ? fg : bg) << 8;
+                       tmp |= ((d & 0x10) ? fg : bg);
+                       *((unsigned long*) dest) = tmp;
+                       tmp =  ((d & 0x8) ? fg : bg) << 24;
+                       tmp |= ((d & 0x4) ? fg : bg) << 16;
+                       tmp |= ((d & 0x2) ? fg : bg) << 8;
+                       tmp |= ((d & 0x1) ? fg : bg);
+                       *((unsigned long*) dest + 1) = tmp;
+               }
+       }
+}
+
+static void rev_char_retz3(struct display *p, int xx, int yy)
+{
+       unsigned char *dest;
+       int bytes=p->next_line, rows;
+       unsigned int bpp, mask;
+
+       bpp = p->var.bits_per_pixel;
+
+       switch (bpp){
+       case 8:
+               mask = 0x0f0f0f0f;
+               break;
+       case 16:
+               mask = 0xffffffff;
+               break;
+       case 24:
+               mask = 0xffffffff; /* ??? */
+               break;
+       default:
+               printk("illegal depth for rev_char_retz3(), bpp = %i\n", bpp);
+               return;
+       }
+
+       dest = p->screen_base + yy * p->fontheight * bytes + xx * bpp;
+
+       for (rows = p->fontheight ; rows-- ; dest += bytes) {
+               ((unsigned long *)dest)[0] ^= mask;
+               ((unsigned long *)dest)[1] ^= mask;
+       }
+}
+
+#endif
+
 /* ====================================================================== */
 
    /*
@@ -3774,5 +4120,5 @@ static void rev_char_cyber(struct display *p, int x, int y)
 struct consw fb_con = {
    fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
    fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
-   fbcon_blank, fbcon_get_font, fbcon_set_font
+   fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette
 };
index a080c12a76d8c23b7a38840dbd35415747209662..b858085581ad1eabce041b3344cb801ea49a7bd4 100644 (file)
@@ -22,7 +22,7 @@
     *    Interface used by the world
     */
 
-static u_long txtcon_startup(u_long kmem_start, char **display_desc);
+static u_long txtcon_startup(u_long kmem_start, const char **display_desc);
 static void txtcon_init(struct vc_data *conp);
 static int txtcon_deinit(struct vc_data *conp);
 static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
@@ -36,10 +36,12 @@ static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                         int height, int width);
 static int txtcon_switch(struct vc_data *conp);
 static int txtcon_blank(int blank);
+static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
+static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int txtcon_set_palette(struct vc_data *conp, unsigned char *table);
 
 
-
-static u_long txtcon_startup(u_long kmem_start, char **display_desc)
+static u_long txtcon_startup(u_long kmem_start, const char **display_desc)
 {
    *display_desc = "Not yet implemented";
    return(kmem_start);
@@ -113,6 +115,24 @@ static int txtcon_blank(int blank)
 }
 
 
+static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+{
+   return(0);
+}
+
+
+static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data)
+{
+   return(0);
+}
+
+
+static int txtcon_set_palette(struct vc_data *conp, unsigned char *table)
+{
+   return(0);
+}
+
+
 /* ====================================================================== */
 
    /*
@@ -122,6 +142,6 @@ static int txtcon_blank(int blank)
 struct consw txt_con = {
    txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc,
    txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch,
-   txtcon_blank
+   txtcon_blank, txtcon_get_font, txtcon_set_font, txtcon_set_palette
 };
 
index 554583f90968d7ab3e1c0d637376fdf6efe05efe..65f71d5a9abd2e6cc2344ce4fea43eb142fb6975 100644 (file)
@@ -46,6 +46,7 @@ CONFIG_AMIFB_OCS=y
 CONFIG_AMIFB_ECS=y
 CONFIG_AMIFB_AGA=y
 # CONFIG_FB_CYBER is not set
+# CONFIG_FB_RETINAZ3 is not set
 # CONFIG_AMIGA_GSP is not set
 # CONFIG_GSP_RESOLVER is not set
 # CONFIG_GSP_A2410 is not set
@@ -79,9 +80,10 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_FIREWALL is not set
 # CONFIG_NET_ALIAS is not set
 CONFIG_INET=y
-# CONFIG_IP_FORWARD is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ACCT is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
 
 #
 # (it is safe to leave these untouched)
@@ -123,18 +125,19 @@ CONFIG_BLK_DEV_SR=y
 # SCSI low-level drivers
 #
 CONFIG_A3000_SCSI=y
-# CONFIG_A2091_SCSI is not set
-# CONFIG_GVP11_SCSI is not set
+CONFIG_A2091_SCSI=y
+CONFIG_GVP11_SCSI=y
 # CONFIG_CYBERSTORM_SCSI is not set
 # CONFIG_CYBERSTORMII_SCSI is not set
 # CONFIG_BLZ2060_SCSI is not set
 # CONFIG_BLZ1230_SCSI is not set
+# CONFIG_FASTLANE_SCSI is not set
 CONFIG_ATARI_SCSI=y
 
 #
 # Network device support
 #
-# CONFIG_NETDEVICES is not set
+CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_SLIP is not set
 # CONFIG_PPP is not set
@@ -164,6 +167,7 @@ CONFIG_NFS_FS=y
 # CONFIG_HPFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_AFFS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_UFS_FS is not set
 
 #
@@ -176,6 +180,8 @@ CONFIG_AMIGAMOUSE=y
 CONFIG_ATARIMOUSE=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 # CONFIG_GVPIOEXT is not set
+# CONFIG_GVPIOEXT_LP is not set
+# CONFIG_GVPIOEXT_PLIP is not set
 # CONFIG_MULTIFACE_III_TTY is not set
 # CONFIG_USERIAL is not set
 # CONFIG_WATCHDOG is not set
index 4e4eab64ef436a03c6a15cebc242cc5c2473f341..5768516bd5042d5a17f06758926e6917bc4d1563 100644 (file)
@@ -513,9 +513,12 @@ copyout:
        movel   12(%sp),%d0     | count
        subl    #1,%d0          | dec count by 1 for dbra
        movel   #1,%d1
-       movec   %d1,%DFC                | set dfc for user data space
+
+|      DFC is already set
+|      movec   %d1,%DFC                | set dfc for user data space
 moreout:
        moveb   (%a0)+,%d1      | fetch supervisor byte
+out_ea:
        movesb  %d1,(%a1)+      | write user byte
        dbf     %d0,moreout
        rts
@@ -526,11 +529,24 @@ copyin:
        movel   12(%sp),%d0     | count
        subl    #1,%d0          | dec count by 1 for dbra
        movel   #1,%d1
-       movec   %d1,%SFC                | set sfc for user space
+|      SFC is already set
+|      movec   %d1,%SFC                | set sfc for user space
 morein:
+in_ea:
        movesb  (%a0)+,%d1      | fetch user byte
        moveb   %d1,(%a1)+      | write supervisor byte
        dbf     %d0,morein
        rts
 
+       .section .fixup,#alloc,#execinstr
+       .even
+1:
+       jbra    SYMBOL_NAME(fpsp040_die)
+
+       .section __ex_table,#alloc
+       .align  4
+
+       .long   in_ea,1b
+       .long   out_ea,1b
+
        |end
index 3e0e307015c924610317130ab0cbe55fa741f7e9..b58e0635b5059b6794eb60fde2620fac1bc701e4 100644 (file)
@@ -153,7 +153,7 @@ _060_dmem_read_byte:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmrbs                   | supervisor
 dmrbu: clr.l           %d0                     | clear whole longword
-       movs.b          (%a0),%d0               | fetch user byte
+dmrbuae:movs.b         (%a0),%d0               | fetch user byte
        bras            dmrbr
 dmrbs: clr.l           %d0                     | clear whole longword
        move.b          (%a0),%d0               | fetch super byte
@@ -190,7 +190,7 @@ _060_imem_read_word:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmrws                   | supervisor
 dmrwu: clr.l           %d0                     | clear whole longword
-       movs.w          (%a0), %d0              | fetch user word
+dmrwuae:movs.w         (%a0), %d0              | fetch user word
        bras            dmrwr
 dmrws: clr.l           %d0                     | clear whole longword
        move.w          (%a0), %d0              | fetch super word
@@ -226,7 +226,8 @@ _060_dmem_read_long:
 _060_imem_read_long:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmrls                   | supervisor
-dmrlu: movs.l          (%a0),%d0               | fetch user longword
+dmrlu:
+dmrluae:movs.l         (%a0),%d0               | fetch user longword
        bras            dmrlr
 dmrls: move.l          (%a0),%d0               | fetch super longword
 dmrlr: clr.l           %d1                     | return success
@@ -248,7 +249,8 @@ dmrlr:      clr.l           %d1                     | return success
 _060_dmem_write_byte:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmwbs                   | supervisor
-dmwbu: movs.b          %d0,(%a0)               | store user byte
+dmwbu:
+dmwbuae:movs.b         %d0,(%a0)               | store user byte
        bras            dmwbr
 dmwbs: move.b          %d0,(%a0)               | store super byte
 dmwbr: clr.l           %d1                     | return success
@@ -270,7 +272,8 @@ dmwbr:      clr.l           %d1                     | return success
 _060_dmem_write_word:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmwws                   | supervisor
-dmwwu: movs.w          %d0,(%a0)               | store user word
+dmwwu:
+dmwwuae:movs.w         %d0,(%a0)               | store user word
        bras            dmwwr
 dmwws: move.w          %d0,(%a0)               | store super word
 dmwwr: clr.l           %d1                     | return success
@@ -292,7 +295,8 @@ dmwwr:      clr.l           %d1                     | return success
 _060_dmem_write_long:
        btst            #0x5,0x4(%a6)           | check for supervisor state
        bnes            dmwls                   | supervisor
-dmwlu: movs.l          %d0,(%a0)               | store user longword
+dmwlu:
+dmwluae:movs.l         %d0,(%a0)               | store user longword
        bra             dmwlr
 dmwls: move.l          %d0,(%a0)               | store super longword
 dmwlr: clr.l           %d1                     | return success
@@ -322,9 +326,10 @@ _copyout:
     subq.l      #1,%d0
 moreout:
        move.b          (%a0)+,%d1              | fetch supervisor byte
+copyoutae:
        movs.b          %d1,(%a1)+              | store user byte
        dbra            %d0,moreout             | are we through yet?
-    moveq              #0,%d0                  | return success
+       moveq           #0,%d0                  | return success
        rts
 
 |
@@ -337,11 +342,12 @@ _copyin:
        move.l          12(%sp),%d0             | count
     subq.l      #1,%d0
 morein:
+copyinae:      
        movs.b          (%a0)+,%d1              | fetch user byte
        move.b          %d1,(%a1)+              | write supervisor byte
        subq.l          #0x1,%d0                | are we through yet?
        dbra            %d0,morein              | are we through yet?
-    moveq              #0,%d0                  | return success
+       moveq           #0,%d0                  | return success
        rts
 
 |###########################################################################
@@ -374,3 +380,22 @@ _060_real_trace:
        .global         _060_real_access
 _060_real_access:
        bral    SYMBOL_NAME(buserr)
+
+
+
+| Execption handling for movs access to illegal memory 
+       .section .fixup,#alloc,#execinstr
+       .even
+1:     moveq           #-1,%d1
+       rts
+.section __ex_table,#alloc
+       .align 4
+       .long   dmrbuae,1b
+       .long   dmrwuae,1b
+       .long   dmrluae,1b
+       .long   dmwbuae,1b
+       .long   dmwwuae,1b
+       .long   dmwluae,1b
+       .long   copyoutae,1b
+       .long   copyinae,1b
+       .text
index efe34dcf487921c4dad2453c5cc9b7c3e6750f06..67d87c1b9dcb27557a6f49ec19a18a200b2cdbc7 100644 (file)
@@ -19,6 +19,10 @@ O_OBJS += console.o
 endif
 OX_OBJS := m68k_ksyms.o
 
+ifdef CONFIG_KGDB
+O_OBJS += kgdb.o
+endif
+
 head.o: head.S
 
 include $(TOPDIR)/Rules.make
index 30229926dc87561a66b036e7854b7b3ad720479c..468ae0b5958b1f3a708a9bf01d45879c9e3c8a7d 100644 (file)
@@ -20,7 +20,7 @@
  *     'unsigned long con_init(unsigned long)'
  *     'int con_open(struct tty_struct *tty, struct file * filp)'
  *     'void con_write(struct tty_struct * tty)'
- *     'void console_print(const char * b)'
+ *     'void vt_console_print(const char * b)'
  *     'void update_screen(int new_console)'
  *
  *     'void do_blank_screen(int)'
  * interrupt, as we use trap-gates. Hopefully all is well.
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
+#include <linux/console.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include "../../../drivers/char/vt_kern.h"
 #include "../../../drivers/char/consolemap.h"
 #include "../../../drivers/char/selection.h"
+#include "../../../drivers/char/console_struct.h"
 
 
 #ifndef MIN
@@ -146,12 +149,13 @@ static void gotoxy(int currcons, int new_x, int new_y);
 static void save_cur(int currcons);
 static void blank_screen(void);
 static void unblank_screen(void);
+static int con_open(struct tty_struct *, struct file *);
 extern void change_console(unsigned int);
 static inline void set_cursor(int currcons);
 static void reset_terminal(int currcons, int do_clear);
 extern void reset_vc(unsigned int new_console);
 extern void vt_init(void);
-extern void register_console(void (*proc)(const char *));
+static void set_vesa_blanking(unsigned long arg);
 extern void vesa_blank(void);
 extern void vesa_unblank(void);
 extern void compute_shiftstate(void);
@@ -170,6 +174,7 @@ int       video_mode_512ch = 0;     /* 512-character mode */
 static unsigned short console_charmask = 0x0ff;
 
 static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
+struct vc vc_cons [MAX_NR_CONSOLES];
 
 /* used by kbd_bh - set by keyboard_interrupt */
        int do_poke_blanked_console = 0;
@@ -189,13 +194,6 @@ int last_console = 0;
 int want_console = -1;
 int kmsg_redirect = 0;
 
-static struct vc {
-       struct vc_data *d;
-
-       /* might add  scrmem, vt_struct, kbd  at some time,
-          to have everything in one place - the disadvantage
-          would be that vc_cons etc can no longer be static */
-} vc_cons [MAX_NR_CONSOLES];
 struct consw *conswitchp;
 
 #define cols            (vc_cons[currcons].d->vc_cols)
@@ -270,8 +268,6 @@ struct consw *conswitchp;
 #define        vtnewvt         (vt_cons[currcons]->vt_newvt)
 #endif
 
-#define structsize     (sizeof(struct vc_data) + sizeof(struct vt_struct))
-
 int vc_cons_allocated(unsigned int i)
 {
        return (i < MAX_NR_CONSOLES && vc_cons[i].d);
@@ -621,8 +617,7 @@ void scrollback(int l)
        return;
 }
 
-static void scrup(int currcons, unsigned int t, unsigned int b,
-                 int nr)
+static void scrup(int currcons, unsigned int t, unsigned int b, int nr)
 {
        unsigned short *p;
        int i;
@@ -636,10 +631,10 @@ static void scrup(int currcons, unsigned int t, unsigned int b,
 
        p = video_mem_start + (b - nr) * cols;
        for (i = nr * cols; i > 0; i--)
-         *p++ = video_erase_char;
+               *p++ = video_erase_char;
 
        if (currcons != fg_console)
-         return;
+               return;
 /*
  * Arno:
  * Scrolling has now been moved to amicon.c where it should have
@@ -812,8 +807,8 @@ static void csi_X(int currcons, int vpar) /* erase the following vpar positions
        if (!vpar)
                vpar++;
 
-       start=pos;
-       count=(vpar > cols-x) ? (cols-x) : vpar;
+       start = pos;
+       count = (vpar > cols-x) ? (cols-x) : vpar;
 
        if (currcons == fg_console)
                sw->con_clear(vc_cons[currcons].d,y,x,1,count);
@@ -1008,7 +1003,7 @@ void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
        respond_string(buf, tty);
 }
 
-/* invoked via ioctl(TIOCLINUX) */
+/* invoked via ioctl(TIOCLINUX) and through set_selection */
 int mouse_reporting(void)
 {
        int currcons = fg_console;
@@ -1309,12 +1304,12 @@ static inline void insert_char(int currcons)
        unsigned short *p = pos;
 
        for (i = cols - x - 2; i >= 0; i--)
-         p[i + 1] = p[i];
+               p[i + 1] = p[i];
        *pos = video_erase_char;
        need_wrap = 0;
 
        if (currcons != fg_console)
-         return;
+               return;
 
        /* Arno:
         * Move the remainder of the line (-1 character) one spot to the right
@@ -1338,19 +1333,19 @@ static void csi_at(int currcons, unsigned int nr)
 
        p = pos + cols - x - nr;
        while (--p >= pos)
-         p[nr] = *p;
+               p[nr] = *p;
        for (i = 0; i < nr; i++)
-         *++p = video_erase_char;
+               *++p = video_erase_char;
        need_wrap = 0;
 
        if (currcons != fg_console)
-         return;
+               return;
 
        sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
                       1, cols - x - nr);
        while (nr--)
-         sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
-                       y, x + nr);
+               sw->con_putc (vc_cons[currcons].d,
+                             video_erase_char & 0x00ff, y, x + nr);
 }
 
 static void csi_L(int currcons, unsigned int nr)
@@ -1645,9 +1640,9 @@ static int do_con_write(struct tty_struct * tty, int from_user,
                         */
                        
                        /* Only use this for the foreground console,
-                           where we really draw the chars */
+                          where we really draw the chars */
 
-                        if (count > 2 &&
+                       if (count > 2 &&
                            !decim && !utf && currcons == fg_console) { 
                                static char putcs_buf[256];
                                char   *p     = putcs_buf;
@@ -1660,13 +1655,11 @@ static int do_con_write(struct tty_struct * tty, int from_user,
                                if (nextx == cols) {
                                        sw->con_putc(vc_cons[currcons].d,
                                                     *putcs_buf, y, x);
-                                       pos--;
+                                       ((unsigned short *)pos)--;
                                        need_wrap = decawm;
                                        continue;
                                }
                                
-                               /* TAB TAB TAB - Arghh!!!! */
-
                                while (count)
                                {
                                        enable_bh(CONSOLE_BH);
@@ -2129,12 +2122,13 @@ void poke_blanked_console(void)
 
 /* DPC: New version of console_print using putcs */
 
-void console_print(const char * b)
+#ifdef CONFIG_VT_CONSOLE
+void vt_console_print(const char * b, unsigned int count)
 {
    int currcons = fg_console;
    unsigned char c;
    const char *start = b;
-   ushort count      = 0;
+   ushort cnt        = 0;
    ushort myx        = x;
    static int printing = 0;
 
@@ -2147,7 +2141,7 @@ void console_print(const char * b)
 
    if (!vc_cons_allocated(currcons)) {
           /* impossible */
-          printk("console_print: tty %d not allocated ??\n", currcons+1);
+          printk("vt_console_print: tty %d not allocated ??\n", currcons+1);
           printing = 0;
           return;
    }
@@ -2157,52 +2151,51 @@ void console_print(const char * b)
 
    /* Contrived structure to try to emulate original need_wrap behaviour
     * Problems caused when we have need_wrap set on '\n' character */
-   
-   while ((c = *(b++)) != 0) {
-       if (c == 10 || c == 13 || c == 8 || need_wrap) {
-           if ((count = b - start - 1) > 0) {
-               sw->con_putcs(vc_cons[currcons].d, start, count ,
-                             y, x);
-               x += count;
-              if (need_wrap)
-                x--;
-           }
-
-          if (c == 8) {        /* backspace */
-              bs(currcons);
-              start = b;
-              myx = x;
-              continue;
+
+   while (count-- > 0) {
+          c = *(b++);
+          if (c == 10 || c == 13 || c == 8 || need_wrap) {
+                       if ((cnt = b - start - 1) > 0) {
+                               sw->con_putcs(vc_cons[currcons].d,
+                                             start, cnt, y, x);
+                               x += cnt;
+                               if (need_wrap)
+                                       x--;
+                  }
+
+                  if (c == 8) {        /* backspace */
+                          bs(currcons);
+                          start = b;
+                          myx = x;
+                          continue;
+                  }
+                  if (c != 13)
+                          lf(currcons);
+                  cr(currcons);
+
+                  if (c == 10 || c == 13) {
+                          start = b; myx = x; continue;
+                  }
+
+                  start = b-1; myx = x;
           }
-           if (c != 13)
-               lf(currcons);
-           cr(currcons);
-
-           if (c == 10 || c == 13) {
-               start = b; myx = x; continue;
-           }
-
-           start = b-1; myx = x;
-       }
-
-       *pos = c | (attr << 8);
-       if (myx == cols - 1) {
-           need_wrap = 1;
-           continue;
-       }
-       pos++;
-       myx++;
+
+          *pos = c | (attr << 8);
+          if (myx == cols - 1) {
+                  need_wrap = 1;
+                  continue;
+          }
+          pos++;
+          myx++;
    }
 
-   if ((count = b - start -1) > 0) {
-       sw->con_putcs(vc_cons[currcons].d, start, count ,
-                     y, x);
-       x += count;
-       if (x == cols)
-        {
-          x--;
-           need_wrap = 1;
-        }
+   if ((cnt = b - start) > 0) {
+          sw->con_putcs(vc_cons[currcons].d, start, cnt, y, x);
+          x += cnt;
+          if (x == cols){
+                  x--;
+                  need_wrap = 1;
+          }
    }
    
    set_cursor(currcons);
@@ -2210,6 +2203,18 @@ void console_print(const char * b)
    printing = 0;
 }
 
+static int vt_console_device(void)
+{
+       return MKDEV(TTY_MAJOR, fg_console + 1);
+}
+
+extern void keyboard_wait_for_keypress(void);
+
+struct console vt_console_driver = {
+       vt_console_print, do_unblank_screen,
+        keyboard_wait_for_keypress, vt_console_device
+};
+#endif
 
 /*
  * con_throttle and con_unthrottle are only used for
@@ -2280,7 +2285,7 @@ static void console_bh(void)
  */
 unsigned long con_init(unsigned long kmem_start)
 {
-       char *display_desc = "????";
+       const char *display_desc = "????";
        unsigned int currcons = 0;
        extern int serial_debug;
 
@@ -2354,14 +2359,15 @@ unsigned long con_init(unsigned long kmem_start)
        printable = 1;
 
        /* If "serdebug" cmd line option was present, don't register for printk */
+#ifdef CONFIG_VT_CONSOLE
        if (!serial_debug)
-               register_console(console_print);
+               register_console(&vt_console_driver);
        printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
                can_do_color ? "colour":"mono",
                display_desc,
                cols,rows,
                MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
-
+#endif
        init_bh(CONSOLE_BH, console_bh);
        return kmem_start;
 }
@@ -2527,7 +2533,7 @@ static void unblank_screen(void)
 /*
  * Allocate the console screen memory.
  */
-int con_open(struct tty_struct *tty, struct file * filp)
+static int con_open(struct tty_struct *tty, struct file * filp)
 {
        unsigned int currcons;
        int i;
@@ -2664,7 +2670,7 @@ int con_adjust_height(unsigned long fontheight)
        return -EINVAL;
 }
 
-void set_vesa_blanking(int arg)
+static void set_vesa_blanking(unsigned long arg)
 {
        char *argp = (char *)arg + 1;
        unsigned int mode;
index 7f6edcaa3aaae9d4132b7e71956d2809186e338b..cdd88eb9b9262ca1b058e180da903b4c248cee85 100644 (file)
 #include <linux/linkage.h>
 #include <asm/setup.h>
 #include <asm/segment.h>
+#ifdef CONFIG_KGDB
+#include <asm/kgdb.h>
+.globl SYMBOL_NAME(kgdb_registers)
+#endif
 
 LENOSYS = 38
 
@@ -66,7 +70,7 @@ LTASK_BLOCKED = 16
 LTASK_FLAGS    = 20
 
 /* the following macro is used when enabling interrupts */
-#if defined(CONFIG_ATARI_ONLY)
+#if defined(MACH_ATARI_ONLY)
        /* block out HSYNC on the atari */
 #define ALLOWINT 0xfbff
 #define        MAX_NOINT_IPL   3
@@ -87,11 +91,23 @@ LFORMATVEC  = 0x2E
  * regs are a2-a6 and d6-d7 preserved by C code
  * the kernel doesn't mess with usp unless it needs to
  */
+#ifndef CONFIG_KGDB
 #define SAVE_ALL                       \
        clrl    %sp@-;    /* stk_adj */ \
        movel   %d0,%sp@-; /* orig d0 */        \
        movel   %d0,%sp@-; /* d0 */     \
        moveml  %d1-%d5/%a0-%a1,%sp@-
+#else
+/* Need to save the "missing" registers for kgdb...
+ */
+#define SAVE_ALL                                               \
+       clrl    %sp@-;    /* stk_adj */                         \
+       movel   %d0,%sp@-; /* orig d0 */                        \
+       movel   %d0,%sp@-; /* d0 */                             \
+       moveml  %d1-%d5/%a0-%a1,%sp@-;                          \
+       moveml  %d6-%d7,SYMBOL_NAME(kgdb_registers)+GDBOFFA_D6; \
+       moveml  %a2-%a6,SYMBOL_NAME(kgdb_registers)+GDBOFFA_A2
+#endif
 
 #define RESTORE_ALL                    \
        moveml  %sp@+,%a0-%a1/%d1-%d5;  \
@@ -244,7 +260,7 @@ SYMBOL_NAME_LABEL(inthandler)
        movel   %d0,%sp@(LORIG_D0)      | a -1 in the ORIG_D0 field
                                        | signifies that the stack frame
                                        | is NOT for syscall
-       addql   #1,SYMBOL_NAME(intr_count)
+       addql   #1,SYMBOL_NAME(local_irq_count)
                                        |  put exception # in d0
        bfextu %sp@(LFORMATVEC){#4,#10},%d0
 
@@ -255,27 +271,26 @@ SYMBOL_NAME_LABEL(inthandler)
 
 SYMBOL_NAME_LABEL(ret_from_interrupt)
        /* check if we need to do software interrupts */
-1:
-       movel   SYMBOL_NAME(intr_count),%d1
+       movel   SYMBOL_NAME(local_irq_count),%d1
        subql   #1,%d1
        jne     4f
-       bfextu  %sp@(LSR){#5,#3},%d0    | Check for nested interrupt.
+#if 0
+               bfextu  %sp@(LSR){#5,#3},%d0    | Check for nested interrupt.
 #if MAX_NOINT_IPL > 0
        cmpiw   #MAX_NOINT_IPL,%d0
 #endif
        jhi     4f
-2:
+#endif
        movel   SYMBOL_NAME(bh_active),%d0
        andl    SYMBOL_NAME(bh_mask),%d0
-       jne     3f
+       jeq     3f
 
-       clrl    SYMBOL_NAME(intr_count) | deliver signals, reschedule etc..
-       jra     SYMBOL_NAME(ret_from_exception)
-3:     
        jbsr    SYMBOL_NAME(do_bottom_half)
-       jbra    2b
+3:     
+       clrl    SYMBOL_NAME(local_irq_count)
+       jra     SYMBOL_NAME(ret_from_exception)
 4:
-       movel   %d1,SYMBOL_NAME(intr_count)
+       movel   %d1,SYMBOL_NAME(local_irq_count)
        RESTORE_ALL
 
 
@@ -339,8 +354,10 @@ SYMBOL_NAME_LABEL(resume)
        /* save sr */
        movew   %sr,%a0@(LTSS_SR)
 
+#if 0
        /* disable interrupts */
        oriw    #0x0700,%sr
+#endif
 
        /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
        movec   %sfc,%d0
@@ -361,18 +378,18 @@ SYMBOL_NAME_LABEL(resume)
        fsave   %a0@(LTSS_FPCTXT+27*4)
 
 #if defined(CONFIG_M68060)
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
        btst    #3,SYMBOL_NAME(m68k_cputype)+3
        beqs    1f
 #endif
        /* The 060 FPU keeps status in bits 15-8 of the first longword */
        tstb    %a0@(LTSS_FPCTXT+27*4+2)
        jeq     3f
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
        jra     2f
 #endif
 #endif /* CONFIG_M68060 */
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
 1:     tstb    %a0@(LTSS_FPCTXT+27*4)
        jeq     3f
 #endif
@@ -388,12 +405,12 @@ SYMBOL_NAME_LABEL(resume)
        tstb    %d2
        jne     4f
 
-#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060)
+#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
        /* 68040 or 68060 ? */
        tstl    SYMBOL_NAME(m68k_is040or060)
        bnes    1f
 #endif
-#if defined(CONFIG_M68020_OR_M68030)
+#if defined(CPU_M68020_OR_M68030)
        /*
         * switch address space
         */
@@ -407,11 +424,11 @@ SYMBOL_NAME_LABEL(resume)
        pmove   %a1@(LTSS_CRP),%crp
 #endif
 
-#if defined(CONFIG_M68020_OR_M68030) && defined(CONFIG_M68040_OR_M68060)
+#if defined(CPU_M68020_OR_M68030) && defined(CPU_M68040_OR_M68060)
        jra     2f      /* skip m68040 stuff */
 1:
 #endif
-#if defined(CONFIG_M68040_OR_M68060)
+#if defined(CPU_M68040_OR_M68060)
        /*
         * switch address space
         */
@@ -434,24 +451,24 @@ SYMBOL_NAME_LABEL(resume)
        movec   %d0,%cacr
 #endif /* CONFIG_M68060 */
        .chip   68k
-#endif /* CONFIG_M68040_OR_M68060 */
+#endif /* CPU_M68040_OR_M68060 */
 2:
 4:
        /* restore floating point context */
 
 #if defined(CONFIG_M68060)
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
        btst    #3,SYMBOL_NAME(m68k_cputype)+3
        beqs    1f
 #endif
        /* The 060 FPU keeps status in bits 15-8 of the first longword */
        tstb    %a1@(LTSS_FPCTXT+27*4+2)
        jeq     3f
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
        jra     2f
 #endif
 #endif /* CONFIG_M68060 */
-#if !defined(CONFIG_M68060_ONLY)
+#if !defined(CPU_M68060_ONLY)
 1:     tstb    %a1@(LTSS_FPCTXT+27*4)
        jeq     3f
 #endif 
@@ -647,8 +664,11 @@ SYMBOL_NAME_LABEL(sys_call_table)
        .long SYMBOL_NAME(sys_nanosleep)
        .long SYMBOL_NAME(sys_mremap)
        .long SYMBOL_NAME(sys_setresuid)
-       .long SYMBOL_NAME(sys_getresuid)
+       .long SYMBOL_NAME(sys_getresuid)        /* 165 */
        .long SYMBOL_NAME(sys_ni_syscall)       /* for vm86 */
+       .long SYMBOL_NAME(sys_query_module)
+       .long SYMBOL_NAME(sys_poll)
+       .long SYMBOL_NAME(sys_ni_syscall)       /* will be sys_nfsservctl */
        .rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
                .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index 987e00ec8ee0cd33908962494e20c1bbec295286..c2b72aa2ddd86728a0bf97641c25bbcca6112c09 100644 (file)
@@ -73,6 +73,7 @@
 
 .globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt)
 .globl SYMBOL_NAME(availmem), SYMBOL_NAME(is_medusa)
+.globl SYMBOL_NAME(is_hades)
 .globl SYMBOL_NAME(m68k_pgtable_cachemode)
 .globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir)
 
@@ -234,9 +235,59 @@ ENTRY(_start)
        movew   #0x2700,%sr
 #endif
 
+/*
+   If running on an Atari, determine the I/O base of the
+   serial port and test if we are running on a Medusa or Hades.
+   This test is necessary here, because on the Hades the serial
+   port is only accessible in the high I/O memory area.
+
+   The test whether it is a Medusa is done by writing to the byte at
+   phys. 0x0. This should result in a bus error on all other machines.
+
+   ...should, but doesn't. The Afterburner040 for the Falcon has the
+   same behaviour (0x0..0x7 are no ROM shadow). So we have to do
+   another test to distinguish Medusa and AB040. This is a
+   read attempt for 0x00ff82fe phys. that should bus error on a Falcon
+   (+AB040), but is in the range where the Medusa always asserts DTACK.
+
+   The test for the Hades is done by reading address 0xb0000000. This
+   should give a bus error on the Medusa.
+ */
+
+#ifdef CONFIG_ATARI
+       is_not_atari(Lnotypetest)
+
+       moveq   #0,%d3                  /* base addr for others: 0x00000000 */
+       moveq   #0,%d2                  /* no Hades */
+       movec   %d3,%vbr
+       lea     %pc@(Ltest_berr),%a0
+       movel   %a0,0x8
+       movel   %sp,%a0
+       moveb   0x0,%d1
+       clrb    0x0
+       nop
+       moveb   %d1,0x0
+       nop
+       tstb    0x00ff82fe
+       nop
+       movel   #0xff000000,%d3         /* Medusa base addr: 0xff000000 */
+       tstb    0xb0000000
+       nop
+       movel   #0xff000000,%d2         /* Computer is a Hades */
+       moveq   #0,%d3
+Ltest_berr:
+       movel   %a0,%sp
+       lea     %pc@(SYMBOL_NAME(is_hades)),%a0
+       movel   %d2,%a0@
+       lea     %pc@(SYMBOL_NAME(is_medusa)),%a0
+       movel   %d3,%a0@
+Lnotypetest:
+#endif
+
 /*
  * Initialize serial port
  */
+
        jbsr Lserial_init
 
        putr()
@@ -491,35 +542,16 @@ Lnotami:
 
    For the Medusa it is better to map the I/O region transparently
    (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are
-   accessible only in the high area. The test whether it is a Medusa
-   is done by writing to the byte at phys. 0x0. This should result
-   in a bus error on all other machines.
+   accessible only in the high area.
 
-   ...should, but doesn't. The Afterburner040 for the Falcon has the
-   same behaviour (0x0..0x7 are no ROM shadow). So we have to do
-   another test to distinguish Medusa and AB040. This is a
-   read attempt for 0x00ff82fe phys. that should bus error on a Falcon
-   (+AB040), but is in the range where the Medusa always asserts DTACK.
+   On the Hades all I/O registers are only accessible in the high
+   area.
 */
 
-       moveq   #0,%d3                  /* base addr for others: 0x00000000 */
-       movec   %d3,%vbr
-       lea     %pc@(Ltest_berr),%a0
-       movel   %a0,0x8
-       movel   %sp,%a0
-       moveb   0x0,%d1
-       clrb    0x0
-       nop
-       moveb   %d1,0x0
-       nop
-       tstb    0x00ff82fe
-       nop
-       movel   #0xff000000,%d3         /* Medusa base addr: 0xff000000 */
-Ltest_berr:
-       movel   %a0,%sp
-       lea     %pc@(SYMBOL_NAME(is_medusa)),%a0
-       movel   %d3,%a0@
-
+       movel   %pc@(is_medusa),%d3
+       bne     1f
+       movel   %pc@(is_hades),%d3
+1:
        /* Let the root table point to the new pointer table */
        lea     %a4@(PTR_TABLE_SIZE<<2),%a4
        movel   %a4,%a0
@@ -979,19 +1011,20 @@ Lserial_init:
 #ifdef CONFIG_ATARI
        cmpil   #MACH_ATARI,%d4
        jne     4f
+       movel   %pc@(Liobase),%a1
 #ifdef USE_PRINTER
-       bclr    #0,LSTMFP_IERB
-       bclr    #0,LSTMFP_DDR
-       moveb   #LPSG_CONTROL,LPSG_SELECT
-       moveb   #0xff,LPSG_WRITE
-       moveb   #LPSG_IO_B,LPSG_SELECT
-       clrb    LPSG_WRITE
-       moveb   #LPSG_IO_A,LPSG_SELECT
-       moveb   LPSG_READ,%d0
+       bclr    #0,%a1@(LSTMFP_IERB)
+       bclr    #0,%a1@(LSTMFP_DDR)
+       moveb   #LPSG_CONTROL,%a1@(LPSG_SELECT)
+       moveb   #0xff,%a1@(LPSG_WRITE)
+       moveb   #LPSG_IO_B,%a1@(LPSG_SELECT)
+       clrb    %a1@(LPSG_WRITE)
+       moveb   #LPSG_IO_A,%a1@(LPSG_SELECT)
+       moveb   %a1@(LPSG_READ),%d0
        bset    #5,%d0
-       moveb   %d0,LPSG_WRITE
+       moveb   %d0,%a1@(LPSG_WRITE)
 #elif defined(USE_SCC)
-       lea     LSCC_CTRL_B,%a0
+       lea     %a1@(LSCC_CTRL_B),%a0
        lea     %pc@(scc_initable:w),%a1
 2:     moveb   %a1@+,%d0
        jmi     3f
@@ -1000,12 +1033,12 @@ Lserial_init:
        jra     2b
 3:     clrb    %a0@
 #elif defined(USE_MFP)
-       bclr    #1,LMFP_TSR
-       moveb   #0x88,LMFP_UCR
-       andb    #0x70,LMFP_TDCDR
-       moveb   #2,LMFP_TDDR
-       orb     #1,LMFP_TDCDR
-       bset    #1,LMFP_TSR
+       bclr    #1,%a1@(LMFP_TSR)
+       moveb   #0x88,%a1@(LMFP_UCR)
+       andb    #0x70,%a1@(LMFP_TDCDR)
+       moveb   #2,%a1@(LMFP_TDDR)
+       orb     #1,%a1@(LMFP_TDCDR)
+       bset    #1,%a1@(LMFP_TSR)
 #endif
 4:
 #endif
@@ -1141,5 +1174,7 @@ SYMBOL_NAME_LABEL(availmem)
        .long 0
 SYMBOL_NAME_LABEL(is_medusa)
        .long 0
+SYMBOL_NAME_LABEL(is_hades)
+       .long 0
 SYMBOL_NAME_LABEL(m68k_pgtable_cachemode)
        .long 0
index 8656b2979dd464ed3710e3c6aa5531658b7a0a8b..f49c38cd38444caeb7d6a6a793e550439216bbbc 100644 (file)
@@ -50,6 +50,24 @@ volatile unsigned int num_spurious;
 #define NUM_IRQ_NODES 100
 static irq_node_t nodes[NUM_IRQ_NODES];
 
+unsigned int local_irq_count[NR_CPUS];
+
+int __m68k_bh_counter;
+
+static void dummy_enable_irq(unsigned int irq);
+static void dummy_disable_irq(unsigned int irq);
+static int dummy_request_irq(unsigned int irq,
+               void (*handler) (int, void *, struct pt_regs *),
+               unsigned long flags, const char *devname, void *dev_id);
+static void dummy_free_irq(unsigned int irq, void *dev_id);
+
+void (*enable_irq) (unsigned int) = dummy_enable_irq;
+void (*disable_irq) (unsigned int) = dummy_disable_irq;
+
+int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
+                      unsigned long, const char *, void *) = dummy_request_irq;
+void (*mach_free_irq) (unsigned int, void *) = dummy_free_irq;
+
 /*
  * void init_IRQ(void)
  *
@@ -92,14 +110,30 @@ irq_node_t *new_irq_node(void)
        return NULL;
 }
 
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-                unsigned long flags, const char *devname, void *dev_id)
+/*
+ * We will keep these functions until I have convinced Linus to move
+ * the declaration of them from include/linux/sched.h to
+ * include/asm/irq.h.
+ */
+int request_irq(unsigned int irq,
+               void (*handler) (int, void *, struct pt_regs *),
+               unsigned long flags, const char *devname, void *dev_id)
 {
-       if (irq & IRQ_MACHSPEC)
-               return mach_request_irq(IRQ_IDX(irq), handler, flags, devname, dev_id);
+       return mach_request_irq(irq, handler, flags, devname, dev_id);
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+       mach_free_irq(irq, dev_id);
+}
 
+int sys_request_irq(unsigned int irq, 
+                    void (*handler)(int, void *, struct pt_regs *), 
+                    unsigned long flags, const char *devname, void *dev_id)
+{
        if (irq < IRQ1 || irq > IRQ7) {
-               printk("%s: Incorrect IRQ %d from %s\n", __FUNCTION__, irq, devname);
+               printk("%s: Incorrect IRQ %d from %s\n",
+                      __FUNCTION__, irq, devname);
                return -ENXIO;
        }
 
@@ -109,7 +143,7 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
                               __FUNCTION__, irq, irq_list[irq].devname);
                        return -EBUSY;
                }
-               if (flags & IRQ_FLG_REPLACE) {
+               if (!(flags & IRQ_FLG_REPLACE)) {
                        printk("%s: %s can't replace IRQ %d from %s\n",
                               __FUNCTION__, devname, irq, irq_list[irq].devname);
                        return -EBUSY;
@@ -122,13 +156,8 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
        return 0;
 }
 
-void free_irq(unsigned int irq, void *dev_id)
+void sys_free_irq(unsigned int irq, void *dev_id)
 {
-       if (irq & IRQ_MACHSPEC) {
-               mach_free_irq(IRQ_IDX(irq), dev_id);
-               return;
-       }
-
        if (irq < IRQ1 || irq > IRQ7) {
                printk("%s: Incorrect IRQ %d\n", __FUNCTION__, irq);
                return;
@@ -157,31 +186,42 @@ int probe_irq_off (unsigned long irqs)
        return 0;
 }
 
-void enable_irq(unsigned int irq)
+static void dummy_enable_irq(unsigned int irq)
+{
+       printk("calling uninitialized enable_irq()\n");
+}
+
+static void dummy_disable_irq(unsigned int irq)
+{
+       printk("calling uninitialized disable_irq()\n");
+}
+
+static int dummy_request_irq(unsigned int irq,
+               void (*handler) (int, void *, struct pt_regs *),
+               unsigned long flags, const char *devname, void *dev_id)
 {
-       if ((irq & IRQ_MACHSPEC) && mach_enable_irq)
-               mach_enable_irq(IRQ_IDX(irq));
+       printk("calling uninitialized request_irq()\n");
+       return 0;
 }
 
-void disable_irq(unsigned int irq)
+static void dummy_free_irq(unsigned int irq, void *dev_id)
 {
-       if ((irq & IRQ_MACHSPEC) && mach_disable_irq)
-               mach_disable_irq(IRQ_IDX(irq));
+       printk("calling uninitialized disable_irq()\n");
 }
 
 asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
 {
-       if (vec < VEC_INT1 || vec > VEC_INT7) {
+       if (vec >= VEC_INT1 && vec <= VEC_INT7) {
+               vec -= VEC_SPUR;
+               kstat.interrupts[vec]++;
+               irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
+       } else {
                if (mach_process_int)
                        mach_process_int(vec, fp);
                else
                        panic("Can't process interrupt vector %ld\n", vec);
                return;
        }
-
-       vec -= VEC_SPUR;
-       kstat.interrupts[vec]++;
-       irq_list[vec].handler(vec, irq_list[vec].dev_id, fp);
 }
 
 int get_irq_list(char *buf)
index a34e94cb14d1d20af9165810ed1d3bb0d9b1cd54..3138d99df53f3a9ade222957b323f2eb82266488 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/linkage.h>
 #include <linux/sched.h>
@@ -11,6 +12,8 @@
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/hardirq.h>
 
 asmlinkage long long __ashrdi3 (long long, int);
 extern char m68k_debug_device[];
@@ -31,13 +34,15 @@ EXPORT_SYMBOL(mm_vtop);
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(mm_end_of_chunk);
 EXPORT_SYMBOL(m68k_debug_device);
-EXPORT_SYMBOL(request_irq);
-EXPORT_SYMBOL(free_irq);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(local_irq_count);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
 
 /* The following are special because they're not called
    explicitly (the C compiler generates them).  Fortunately,
index ed0f28aa53dc51fac0adf49f15adaa6786766735..5422831a8d262a9555825cf5a9a9fa67cff939f8 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/malloc.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
+#include <linux/reboot.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -43,6 +44,7 @@ asmlinkage int sys_idle(void)
                goto out;
 
        /* endless idle loop with no priority at all */
+       current->priority = -100;
        current->counter = -100;
        for (;;)
                schedule();
@@ -52,12 +54,23 @@ out:
        return ret;
 }
 
-void hard_reset_now(void)
+void machine_restart(char * __unused)
 {
        if (mach_reset)
                mach_reset();
 }
 
+void machine_halt(void)
+{
+}
+
+void machine_power_off(void)
+{
+#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
+       apm_set_power_state(APM_STATE_OFF);
+#endif
+}
+
 void show_regs(struct pt_regs * regs)
 {
        printk("\n");
@@ -169,7 +182,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 
 /* Fill in the fpu structure for a core dump.  */
 
-int dump_fpu (struct user_m68kfp_struct *fpu)
+int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
 {
   char fpustate[216];
 
@@ -207,7 +220,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
        if (dump->start_stack < TASK_SIZE)
                dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 
-       dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump)));
+       dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
        sw = ((struct switch_stack *)regs) - 1;
        dump->regs.d1 = regs->d1;
        dump->regs.d2 = regs->d2;
@@ -230,7 +243,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
        dump->regs.pc = regs->pc;
        dump->regs.fmtvec = (regs->format << 12) | regs->vector;
        /* dump floating point stuff */
-       dump->u_fpvalid = dump_fpu (&dump->m68kfp);
+       dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
 }
 
 /*
index 407ebd6246d7c879325f584e244018b91f06a16a..70e341b3108f6dc73d52ed2a5e8e37374f06bfd7 100644 (file)
@@ -324,7 +324,6 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
        struct task_struct *child;
-       struct user * dummy = NULL;
        int ret;
 
        lock_kernel();
index fd12b3224d9ac57b20b6442a47a23ac1f8dbd3bb..dfd91d0d42a8fc6eeb09bcd790ed7205069412ed 100644 (file)
@@ -55,11 +55,6 @@ static struct mem_info m68k_ramdisk = { 0, 0 };
 static char m68k_command_line[CL_SIZE];
 char saved_command_line[CL_SIZE];
 
-/* setup some dummy routines */
-static void dummy_waitbut(void)
-{
-}
-
 void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *));
 /* machine dependent keyboard functions */
 int (*mach_keyb_init) (void);
@@ -68,11 +63,6 @@ void (*mach_kbd_leds) (unsigned int) = NULL;
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void);
 void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
-int (*mach_request_irq) (unsigned int, void (*)(int, void *, struct pt_regs *),
-                         unsigned long, const char *, void *);
-int (*mach_free_irq) (unsigned int, void *);
-void (*mach_enable_irq) (unsigned int) = NULL;
-void (*mach_disable_irq) (unsigned int) = NULL;
 void (*mach_get_model) (char *model) = NULL;
 int (*mach_get_hardware_list) (char *buffer) = NULL;
 int (*mach_get_irq_list) (char *) = NULL;
@@ -82,19 +72,15 @@ unsigned long (*mach_gettimeoffset) (void);
 void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
 int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
-void (*mach_mksound)( unsigned int count, unsigned int ticks );
 void (*mach_reset)( void );
-void (*waitbut)(void) = dummy_waitbut;
 struct fb_info *(*mach_fb_init)(long *);
 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
-void (*mach_debug_init)(void);
 void (*mach_video_setup) (char *, int *);
 #ifdef CONFIG_BLK_DEV_FD
 int (*mach_floppy_init) (void) = NULL;
 void (*mach_floppy_setup) (char *, int *) = NULL;
 void (*mach_floppy_eject) (void) = NULL;
 #endif
-void (*mach_syms_export)(void) = NULL;
 
 extern int amiga_parse_bootinfo(const struct bi_record *);
 extern int atari_parse_bootinfo(const struct bi_record *);
@@ -105,10 +91,6 @@ extern void config_mac(void);
 extern void config_sun3(void);
 extern void config_apollo(void);
 
-extern void register_console(void (*proc)(const char *));
-extern void ami_serial_print(const char *str);
-extern void ata_serial_print(const char *str);
-
 #define MASK_256K 0xfffc0000
 
 
@@ -167,12 +149,6 @@ void setup_arch(char **cmdline_p, unsigned long * memory_start_p,
        int i;
        char *p, *q;
 
-       /* machtype is set up by head.S, thus we know our gender */
-       if (MACH_IS_AMIGA)
-               register_console(ami_serial_print);
-       if (MACH_IS_ATARI)
-               register_console(ata_serial_print);
-
        /* The bootinfo is located right after the kernel bss */
        m68k_parse_bootinfo((const struct bi_record *)&_end);
 
index daf4c15366b3e9af03ac5f83e2d99c692e35c70c..c60e82b0b5c792386b8c00e656b9b16ad8be7492 100644 (file)
@@ -291,20 +291,23 @@ static inline void setup_frame (struct sigaction * sa, struct pt_regs *regs,
        tframe = frame;
 
        /* return address points to code on stack */
-       put_user((ulong)(frame+4), tframe); tframe++;
+
+       if(put_user((ulong)(frame+4), tframe))
+               do_exit(SIGSEGV);
+       tframe++;
        if (current->exec_domain && current->exec_domain->signal_invmap)
-           put_user(current->exec_domain->signal_invmap[signr], tframe);
+           __put_user(current->exec_domain->signal_invmap[signr], tframe);
        else
-           put_user(signr, tframe);
+           __put_user(signr, tframe);
        tframe++;
 
-       put_user(regs->vector, tframe); tframe++;
+       __put_user(regs->vector, tframe); tframe++;
        /* "scp" parameter.  points to sigcontext */
-       put_user((ulong)(frame+6), tframe); tframe++;
+       __put_user((ulong)(frame+6), tframe); tframe++;
 
 /* set up the return code... */
-       put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */
-       put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */
+       __put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */
+       __put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */
 
 /* Flush caches so the instructions will be correctly executed. (MA) */
        cache_push_v ((unsigned long)frame, (int)tframe - (int)frame);
index 4cbe4a9e887db5624d61eec529852f6ae797279e..5acfd1cbd2ba04f85056bfb695a34c0af1f554ba 100644 (file)
@@ -34,15 +34,11 @@ asmlinkage int sys_pipe(unsigned long * fildes)
        int error;
 
        lock_kernel();
-       error = verify_area(VERIFY_WRITE,fildes,8);
-       if (error)
-               goto out;
        error = do_pipe(fd);
-       if (error)
-               goto out;
-       put_user(fd[0],0+fildes);
-       put_user(fd[1],1+fildes);
-out:
+       if (!error) {
+               if (copy_to_user(fildes, fd, 2*sizeof(int)))
+                       error = -EFAULT;
+       }
        unlock_kernel();
        return error;
 }
@@ -70,10 +66,10 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
        struct mmap_arg_struct a;
 
        lock_kernel();
-       error = verify_area(VERIFY_READ, arg, sizeof(*arg));
-       if (error)
+       error = -EFAULT;
+       if (copy_from_user(&a, arg, sizeof(a)))
                goto out;
-       copy_from_user(&a, arg, sizeof(a));
+
        if (!(a.flags & MAP_ANONYMOUS)) {
                error = -EBADF;
                if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
@@ -98,15 +94,11 @@ struct sel_arg_struct {
 asmlinkage int old_select(struct sel_arg_struct *arg)
 {
        struct sel_arg_struct a;
-       int ret = -EFAULT;
 
-       lock_kernel();
        if (copy_from_user(&a, arg, sizeof(a)))
-               goto out;
-       ret = sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-out:
-       unlock_kernel();
-       return ret;
+               return -EFAULT;
+       /* sys_select() does the appropriate kernel locking */
+       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
 }
 
 /*
@@ -134,9 +126,8 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
                        ret = -EINVAL;
                        if (!ptr)
                                goto out;
-                       if ((ret = verify_area (VERIFY_READ, ptr, sizeof(long))))
+                       if ((ret = get_user(fourth.__pad, (void **) ptr)))
                                goto out;
-                       get_user(fourth.__pad, (void **)ptr);
                        ret = sys_semctl (first, second, third, fourth);
                        goto out;
                        }
@@ -183,22 +174,13 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
                        switch (version) {
                        case 0: default: {
                                ulong raddr;
-                               if ((ret = verify_area(VERIFY_WRITE, (ulong*) third, sizeof(ulong))))
-                                       goto out;
                                ret = sys_shmat (first, (char *) ptr, second, &raddr);
                                if (ret)
                                        goto out;
-                               put_user (raddr, (ulong *) third);
-                               ret = 0;
-                               goto out;
-                               }
-                       case 1: /* iBCS2 emulator entry point */
-                               ret = -EINVAL;
-                               if (get_fs() != get_ds())
-                                       goto out;
-                               ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
+                               ret = put_user (raddr, (ulong *) third);
                                goto out;
                        }
+                       }
                case SHMDT: 
                        ret = sys_shmdt ((char *)ptr);
                        goto out;
@@ -212,8 +194,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
                        ret = -EINVAL;
                        goto out;
                }
-       else
-               ret = -EINVAL;
+       ret = -EINVAL;
 out:
        unlock_kernel();
        return ret;
index 354ae88bbf89c3ebb0350a8eda9d42d874d1b14d..1cc547907be84d0f8d65237e7a494032fb747a16 100644 (file)
 #include <linux/linkage.h>
 
 #include <asm/setup.h>
+#include <asm/fpu.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/traps.h>
 #include <asm/pgtable.h>
 #include <asm/machdep.h>
+#ifdef CONFIG_KGDB
+#include <asm/kgdb.h>
+#endif
 
 /* assembler routines */
 asmlinkage void system_call(void);
@@ -140,10 +144,9 @@ static inline void console_verbose(void)
 {
        extern int console_loglevel;
        console_loglevel = 15;
-       mach_debug_init();
 }
 
-char *vec_names[] = {
+static char *vec_names[] = {
        "RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
        "ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
        "PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
@@ -162,17 +165,17 @@ char *vec_names[] = {
        "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
        "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
        "FPCP UNSUPPORTED OPERATION",
-       "MMU CONFIGUATION ERROR"
+       "MMU CONFIGURATION ERROR"
        };
 
-char *space_names[] = {
+static char *space_names[] = {
        "Space 0", "User Data", "User Program", "Space 3",
        "Space 4", "Super Data", "Super Program", "CPU"
        };
 
 
 
-extern void die_if_kernel(char *,struct pt_regs *,int);
+void die_if_kernel(char *,struct pt_regs *,int);
 asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
                              unsigned long error_code);
 
@@ -184,7 +187,7 @@ static inline void access_error060 (struct frame *fp)
        unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
 
 #ifdef DEBUG
-       printk("fslw=%#lx, fa=%#lx\n", ssw, fp->un.fmt4.effaddr);
+       printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
 #endif
 
        if (fslw & MMU060_BPE) {
@@ -194,7 +197,7 @@ static inline void access_error060 (struct frame *fp)
                                      "movec %/d0,%/cacr"
                                      : : : "d0" );
                /* return if there's no other error */
-               if (!(fslw & MMU060_ERR_BITS))
+               if ((!(fslw & MMU060_ERR_BITS)) && !(fslw & MMU060_SEE))
                        return;
        }
        
@@ -209,8 +212,13 @@ static inline void access_error060 (struct frame *fp)
                if (fslw & MMU060_MA)
                        addr = PAGE_ALIGN(addr);
                do_page_fault(&fp->ptregs, addr, errorcode);
-       }
-       else {
+       } else if (fslw & (MMU060_SEE)){
+               /* Software Emulation Error. Probably an instruction
+                * using an unsupported addressing mode
+                */
+               send_sig (SIGSEGV, current, 1);
+       } else {
+               printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
                printk( "68060 access error, fslw=%lx\n", fslw );
                trap_c( fp );
        }
@@ -349,7 +357,7 @@ static inline void access_error040 (struct frame *fp)
 }
 #endif /* CONFIG_M68040 */
 
-#if defined(CONFIG_M68020_OR_M68030)
+#if defined(CPU_M68020_OR_M68030)
 static inline void bus_error030 (struct frame *fp)
 {
        volatile unsigned short temp;
@@ -628,7 +636,7 @@ create_atc_entry:
        asm volatile ("ploadr #2,%0@" : /* no outputs */
                      : "a" (addr));
 }
-#endif /* CONFIG_M68020_OR_M68030 */
+#endif /* CPU_M68020_OR_M68030 */
 
 asmlinkage void buserr_c(struct frame *fp)
 {
@@ -651,7 +659,7 @@ asmlinkage void buserr_c(struct frame *fp)
          access_error040 (fp);
          break;
 #endif
-#if defined (CONFIG_M68020_OR_M68030)
+#if defined (CPU_M68020_OR_M68030)
        case 0xa:
        case 0xb:
          bus_error030 (fp);
@@ -675,6 +683,11 @@ int kstack_depth_to_print = 48;
 
 static void dump_stack(struct frame *fp)
 {
+#ifdef CONFIG_KGDB
+       /* This will never return to here, if kgdb has been initialized. And if
+        * it returns from there, then to where the error happened... */
+       enter_kgdb( &fp->ptregs );
+#else
        unsigned long *stack, *endstack, addr, module_start, module_end;
        extern char _start, _etext;
        int i;
@@ -772,10 +785,15 @@ static void dump_stack(struct frame *fp)
        for (i = 0; i < 10; i++)
                printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);
        printk ("\n");
+#endif
 }
 
 void bad_super_trap (struct frame *fp)
 {
+#ifdef CONFIG_KGDB
+       /* Save the register dump if we'll enter kgdb anyways */
+       if (!kgdb_initialized) {
+#endif
        console_verbose();
        if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
                printk ("*** %s ***   FORMAT=%X\n",
@@ -805,6 +823,9 @@ void bad_super_trap (struct frame *fp)
                                fp->ptregs.pc);
        }
        printk ("Current process id is %d\n", current->pid);
+#ifdef CONFIG_KGDB
+       }
+#endif
        die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
 }
 
@@ -863,7 +884,7 @@ asmlinkage void trap_c(struct frame *fp)
            case VEC_FPOVER:
            case VEC_FPNAN:
                {
-                 unsigned char fstate[216];
+                 unsigned char fstate[FPSTATESIZE];
 
                  __asm__ __volatile__ (".chip 68k/68881\n\t"
                                        "fsave %0@\n\t"
@@ -905,9 +926,13 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
        if (!(fp->sr & PS_S))
                return;
 
+#ifdef CONFIG_KGDB
+       /* Save the register dump if we'll enter kgdb anyways */
+       if (!kgdb_initialized) {
+#endif
        console_verbose();
        printk("%s: %08x\n",str,nr);
-       printk("PC: %08lx\nSR: %04x  SP: %p\n", fp->pc, fp->sr, fp);
+       printk("PC: [<%08lx>]\nSR: %04x  SP: %p\n", fp->pc, fp->sr, fp);
        printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",
               fp->d0, fp->d1, fp->d2, fp->d3);
        printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",
@@ -917,6 +942,18 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
                printk("Corrupted stack page\n");
        printk("Process %s (pid: %d, stackpage=%08lx)\n",
                current->comm, current->pid, current->kernel_stack_page);
+#ifdef CONFIG_KGDB
+       }
+#endif
        dump_stack((struct frame *)fp);
        do_exit(SIGSEGV);
 }
+
+/*
+ * This function is called if an error occur while accessing
+ * user-space from the fpsp040 code.
+ */
+asmlinkage void fpsp040_die(void)
+{
+       do_exit(SIGSEGV);
+}
index 29e59eb5bca510c546d0ac89314ac22968c9fbce..35bf38d1ed73464a76e67f669baed069f33fadcd 100644 (file)
@@ -19,8 +19,8 @@
  *             (%1). Thanks to Roman Hodek for pointing this out.
  *             B: GCC seems to mess up if one uses too many
  *             data-registers to hold input values and one tries to
- *             specify d0 and d1 as scratch registers. Letting gcc choose these
- *      registers itself solves the problem.
+ *             specify d0 and d1 as scratch registers. Letting gcc
+ *             choose these registers itself solves the problem.
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
@@ -124,13 +124,20 @@ csum_partial (const unsigned char *buff, int len, unsigned int sum)
 
 
 /*
- * copy from user space while checksumming, otherwise like csum_partial
+ * copy from user space while checksumming, with exception handling.
  */
 
 unsigned int
-csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
+csum_partial_copy_from_user(const char *src, char *dst, int len,
+                           int sum, int *csum_err)
 {
+       /*
+        * GCC doesn't like more than 10 operands for the asm
+        * statements so we have to use tmp2 for the error
+        * code.
+        */
        unsigned long tmp1, tmp2;
+
        __asm__("movel %2,%4\n\t"
                "btst #1,%4\n\t"        /* Check alignment */
                "jeq 2f\n\t"
@@ -226,28 +233,50 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
             "6:\t"
                "addl %5,%0\n\t"        /* now add rest long to sum */
                "clrl %5\n\t"
-               "addxl %5,%0\n"         /* add X bit */
-            "7:\n"
+               "addxl %5,%0\n\t"       /* add X bit */
+            "7:\t"
+               "clrl %5\n"             /* no error - clear return value */
+            "8:\n"
+               ".section .fixup,\"ax\"\n"
+               ".even\n"
+            "9:\t"
+               "moveq #-14,%5\n\t"     /* -EFAULT, out of inputs to asm ;( */
+               "jra 8b\n"
+               ".previous\n"
                ".section __ex_table,\"a\"\n"
-               ".long 10b,7b\n"
-               ".long 11b,7b\n"
-               ".long 12b,7b\n"
-               ".long 13b,7b\n"
-               ".long 14b,7b\n"
-               ".long 15b,7b\n"
-               ".long 16b,7b\n"
-               ".long 17b,7b\n"
-               ".long 18b,7b\n"
-               ".long 19b,7b\n"
-               ".long 20b,7b\n"
-               ".long 21b,7b\n"
+               ".long 10b,9b\n"
+               ".long 11b,9b\n"
+               ".long 12b,9b\n"
+               ".long 13b,9b\n"
+               ".long 14b,9b\n"
+               ".long 15b,9b\n"
+               ".long 16b,9b\n"
+               ".long 17b,9b\n"
+               ".long 18b,9b\n"
+               ".long 19b,9b\n"
+               ".long 20b,9b\n"
+               ".long 21b,9b\n"
                ".previous"
                : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
-                 "=&d" (tmp1), "=&d" (tmp2)
+                 "=&d" (tmp1), "=d" (tmp2)
                : "0" (sum), "1" (len), "2" (src), "3" (dst)
            );
+
+       *csum_err = tmp2;
+
        return(sum);
 }
+
+/*
+ * This one will go away soon.
+ */
+unsigned int
+csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
+{
+       int dummy;
+
+       return csum_partial_copy_from_user(src, dst, len, sum, &dummy);
+}
 /*
  * copy from kernel space while checksumming, otherwise like csum_partial
  */
index be5501f50ce83587c85fdf10a86dabac426e77a0..76ffc3cc52b264d1742b1bf48fa13928baf59b54 100644 (file)
@@ -9,21 +9,29 @@
 #include <linux/linkage.h>
 
 /*
- * "down_failed" is called with the eventual return address
- * in %a0, and the address of the semaphore in %a1. We need
- * to call "__down()", and then re-try until we succeed..
+ * The semaphore operations have a special calling sequence that
+ * allow us to do a simpler in-line version of them. These routines
+ * need to convert that sequence back into the C sequence when
+ * there is contention on the semaphore.
  */
 ENTRY(__down_failed)
        moveml %a0/%d0/%d1,-(%sp)
-1:     movel %a1,-(%sp)
+       movel %a1,-(%sp)
        jbsr SYMBOL_NAME(__down)
        movel (%sp)+,%a1
-       subql #1,(%a1)
-       jmi 1b
        movel (%sp)+,%d0
        movel (%sp)+,%d1
        rts
 
+ENTRY(__down_failed_interruptible)
+       movel %a0,-(%sp)
+       movel %d1,-(%sp)
+       movel %a1,-(%sp)
+       jbsr SYMBOL_NAME(__down_interruptible)
+       movel (%sp)+,%a1
+       movel (%sp)+,%d1
+       rts
+
 ENTRY(__up_wakeup)
        moveml %a0/%d0/%d1,-(%sp)
        movel %a1,-(%sp)
index c3cdba749b6efa7cae2e5ac1088cc0763893e82e..1f8d9e8c3323997fd02f3a339d835bcd83cdfa37 100644 (file)
@@ -46,7 +46,7 @@ search_exception_table(unsigned long addr)
                if (mp->ex_table_start == NULL)
                        continue;
                ret = search_one_table(mp->ex_table_start,
-                                      mp->ex_table_stop-1, addr);
+                                      mp->ex_table_end-1, addr);
                if (ret) return ret;
        }
 #endif
index 1f4e5466bb04fd57b2275df6185e7a95c2afebf4..71b46e2d97ad099805e3f0e250ffbb3f636459a1 100644 (file)
@@ -108,10 +108,7 @@ bad_area:
        up(&mm->mmap_sem);
 
        /* Are we prepared to handle this fault?  */
-       if (CPU_IS_060 && regs->format == 4)
-               fault_pc = ((struct frame *)regs)->un.fmt4.pc;
-       else
-               fault_pc = regs->pc;
+       fault_pc = regs->pc;
        if ((fixup = search_exception_table(fault_pc)) != 0) {
                struct pt_regs *tregs;
                printk(KERN_DEBUG "Exception at [<%lx>] (%lx)\n", fault_pc, fixup);
index 66a6996dc6bca67db9120177794510381ec769aa..01cd315ddf1fbebfc209b7071a3705a243cfb606 100644 (file)
@@ -109,6 +109,8 @@ pte_t *kernel_page_table (unsigned long *memavailp)
        else
                ptablep = (pte_t *)__get_free_page(GFP_KERNEL);
 
+       flush_page_to_ram((unsigned long) ptablep);
+       flush_tlb_kernel_page((unsigned long) ptablep);
        nocache_page ((unsigned long)ptablep);
 
        return ptablep;
@@ -293,8 +295,6 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
 {
        int chunk;
        unsigned long mem_avail = 0;
-       /* pointer to page table for kernel stacks */
-       extern unsigned long availmem;
 
 #ifdef DEBUG
        {
@@ -324,21 +324,12 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
 
        for (chunk = 0; chunk < m68k_num_memory; chunk++) {
                mem_avail = map_chunk (m68k_memory[chunk].addr,
-                                      m68k_memory[chunk].size, &availmem);
+                                      m68k_memory[chunk].size, &start_mem);
 
        }
        flush_tlb_all();
 #ifdef DEBUG
        printk ("memory available is %ldKB\n", mem_avail >> 10);
-#endif
-
-       /*
-        * virtual address after end of kernel
-        * "availmem" is setup by the code in head.S.
-        */
-       start_mem = availmem;
-
-#ifdef DEBUG
        printk ("start_mem is %#lx\nvirtual_end is %#lx\n",
                start_mem, end_mem);
 #endif
@@ -401,7 +392,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        printk ("before free_area_init\n");
 #endif
 
-       return free_area_init (start_mem, end_mem);
+       return PAGE_ALIGN(free_area_init (start_mem, end_mem));
 }
 
 void mem_init(unsigned long start_mem, unsigned long end_mem)
index 21aeb3b1ef9d361c320cc7da97c660432a9d9e3a..55d5e98f3ec4b436cfd9f5bff3b2f32427ef93a6 100644 (file)
@@ -63,11 +63,12 @@ pmd_t *get_pointer_table (void)
                        return 0;
                }
 
-               if (!(dp->page = __get_free_page (GFP_KERNEL))) {
+               if (!(dp->page = get_free_page (GFP_KERNEL))) {
                        kfree (dp);
                        return 0;
                }
 
+               flush_tlb_kernel_page((unsigned long) dp->page);
                nocache_page (dp->page);
 
                dp->alloced = 0;
@@ -210,10 +211,11 @@ pmd_t *get_kpointer_table (void)
                return NULL;
        }
        if (!(page = kptr_pages.page[i])) {
-               if (!(page = (pmd_tablepage *)__get_free_page(GFP_KERNEL))) {
+               if (!(page = (pmd_tablepage *)get_free_page(GFP_KERNEL))) {
                        printk("No space for kernel pointer table!\n");
                        return NULL;
                }
+               flush_tlb_kernel_page((unsigned long) page);
                nocache_page((u_long)(kptr_pages.page[i] = page));
        }
        asm volatile("bfset %0@{%1,#1}"
@@ -306,21 +308,31 @@ unsigned long mm_vtop (unsigned long vaddr)
        if (CPU_IS_030) {
            unsigned long ttreg;
            
-           asm volatile( "pmove %/tt0,%0@" : : "a" (&ttreg) );
+           asm volatile( ".chip 68030\n\t"
+                         "pmove %/tt0,%0@\n\t"
+                         ".chip 68k"
+                         : : "a" (&ttreg) );
            if (transp_transl_matches( ttreg, vaddr ))
                return vaddr;
-           asm volatile( "pmove %/tt1,%0@" : : "a" (&ttreg) );
+           asm volatile( ".chip 68030\n\t"
+                         "pmove %/tt1,%0@\n\t"
+                         ".chip 68k"
+                         : : "a" (&ttreg) );
            if (transp_transl_matches( ttreg, vaddr ))
                return vaddr;
        }
-       else {
-           register unsigned long ttreg __asm__( "d0" );
+       else if (CPU_IS_040_OR_060) {
+           unsigned long ttreg;
            
-           asm volatile( ".long 0x4e7a0006" /* movec %dtt0,%d0 */
+           asm volatile( ".chip 68040\n\t"
+                         "movec %%dtt0,%0\n\t"
+                         ".chip 68k"
                          : "=d" (ttreg) );
            if (transp_transl_matches( ttreg, vaddr ))
                return vaddr;
-           asm volatile( ".long 0x4e7a0007" /* movec %dtt1,%d0 */
+           asm volatile( ".chip 68040\n\t"
+                         "movec %%dtt1,%0\n\t"
+                         ".chip 68k"
                          : "=d" (ttreg) );
            if (transp_transl_matches( ttreg, vaddr ))
                return vaddr;
index 9ce88d5cf3dc560d4e3a68510983c0393a85af81..ff91819b011034533a013b841c9d4e3897a0fc48 100644 (file)
@@ -145,7 +145,7 @@ CONFIG_CHR_DEV_SG=y
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
-# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 
 #
index 2f57655fe0e709fe94e5a44e6864dd917142839e..59dd627b2e4353426951cc2d6d83e3684c233fb2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.137 1997/04/14 05:38:17 davem Exp $
+/* $Id: entry.S,v 1.138 1997/04/15 09:00:50 davem Exp $
  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -301,15 +301,26 @@ real_irq_continue:
        mov     %l7, %o0                ! irq level
        call    C_LABEL(handler_irq)
         add    %sp, REGWIN_SZ, %o1     ! pt_regs ptr
-
-#if 1 /* ndef __SMP__ */ /* You don't want to know... -DaveM */
        wr      %l0, PSR_ET, %psr
        WRITE_PAUSE
-#endif
 
        RESTORE_ALL
 
 #ifdef __SMP__
+       /* SMP per-cpu ticker interrupts are handled specially. */
+smp_ticker:
+       bne     real_irq_continue
+        or     %l0, PSR_PIL, %g2
+       wr      %g2, 0x0, %psr
+       WRITE_PAUSE
+       wr      %g2, PSR_ET, %psr
+       WRITE_PAUSE
+       call    C_LABEL(smp_percpu_timer_interrupt)
+        add    %sp, REGWIN_SZ, %o0
+       wr      %l0, PSR_ET, %psr
+       WRITE_PAUSE
+       RESTORE_ALL
+
        /* Here is where we check for possible SMP IPI passed to us
         * on some level other than 15 which is the NMI and only used
         * for cross calls.  That has a seperate entry point below.
@@ -322,8 +333,9 @@ maybe_smp_msg:
        sll     %o3, 12, %o3
        ld      [%o5 + %o3], %o1
        andcc   %o1, %o4, %g0
-       be      real_irq_continue
-        cmp    %l7, 13
+       be,a    smp_ticker
+        cmp    %l7, 14
+       cmp     %l7, 13
        add     %o5, %o3, %o5
        bne,a   1f
         sethi  %hi(0x40000000), %o2
index cb153e14e5e2ad643f0435c95d0cc43f412e22d4..eea3528bf236054567cad8a38c3f1eddfc3b4f96 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.79 1997/03/04 16:26:31 jj Exp $
+/* $Id: head.S,v 1.81 1997/04/16 07:15:48 davem Exp $
  * head.S: The initial boot code for the Sparc port of Linux.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
index 799a353d9768302305d27fc1ea45ebe2976b29bb..7206a6e1405db6d8fab04436ce2d6c23527adfc3 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.66 1997/04/14 05:38:21 davem Exp $
+/*  $Id: irq.c,v 1.68 1997/04/16 05:55:58 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 
+#ifdef __SMP_PROF__
+extern volatile unsigned long smp_local_timer_ticks[1+NR_CPUS];
+#endif
+
 /*
  * Dave Redman (djhr@tadpole.co.uk)
  *
@@ -71,11 +75,11 @@ void (*enable_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic;
 void (*disable_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic;
 void (*enable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic;
 void (*disable_pil_irq)(unsigned int) = (void (*)(unsigned int)) irq_panic;
-void (*clear_clock_irq)( void ) = irq_panic;
-void (*clear_profile_irq)( void ) = irq_panic;
-void (*load_profile_irq)( unsigned int ) =  (void (*)(unsigned int)) irq_panic;
-void (*init_timers)( void (*)(int, void *,struct pt_regs *)) =
-    (void (*)( void (*)(int, void *,struct pt_regs *))) irq_panic;
+void (*clear_clock_irq)(void) = irq_panic;
+void (*clear_profile_irq)(int) = (void (*)(int)) irq_panic;
+void (*load_profile_irq)(int, unsigned int) =  (void (*)(int, unsigned int)) irq_panic;
+void (*init_timers)(void (*)(int, void *,struct pt_regs *)) =
+    (void (*)(void (*)(int, void *,struct pt_regs *))) irq_panic;
 
 #ifdef __SMP__
 void (*set_cpu_int)(int, int);
@@ -128,6 +132,109 @@ int get_irq_list(char *buf)
        return len;
 }
 
+#ifdef __SMP_PROF__
+
+static unsigned int int_count[NR_CPUS][NR_IRQS] = {{0},};
+
+extern unsigned int prof_multiplier[NR_CPUS];
+extern unsigned int prof_counter[NR_CPUS];
+
+int get_smp_prof_list(char *buf) {
+       int i,j, len = 0;
+       struct irqaction * action;
+       unsigned long sum_spins = 0;
+       unsigned long sum_spins_syscall = 0;
+       unsigned long sum_spins_sys_idle = 0;
+       unsigned long sum_smp_idle_count = 0;
+       unsigned long sum_local_timer_ticks = 0;
+
+       for (i=0;i<smp_num_cpus;i++) {
+               int cpunum = cpu_logical_map[i];
+               sum_spins+=smp_spins[cpunum];
+               sum_spins_syscall+=smp_spins_syscall[cpunum];
+               sum_spins_sys_idle+=smp_spins_sys_idle[cpunum];
+               sum_smp_idle_count+=smp_idle_count[cpunum];
+               sum_local_timer_ticks+=smp_local_timer_ticks[cpunum];
+       }
+
+       len += sprintf(buf+len,"CPUS: %10i \n", smp_num_cpus);
+       len += sprintf(buf+len,"            SUM ");
+       for (i=0;i<smp_num_cpus;i++)
+               len += sprintf(buf+len,"        P%1d ",cpu_logical_map[i]);
+       len += sprintf(buf+len,"\n");
+       for (i = 0 ; i < NR_IRQS ; i++) {
+               action = *(i + irq_action);
+               if (!action || !action->handler)
+                       continue;
+               len += sprintf(buf+len, "%3d: %10d ",
+                       i, kstat.interrupts[i]);
+               for (j=0;j<smp_num_cpus;j++)
+                       len+=sprintf(buf+len, "%10d ",
+                               int_count[cpu_logical_map[j]][i]);
+               len += sprintf(buf+len, "%c %s",
+                       (action->flags & SA_INTERRUPT) ? '+' : ' ',
+                       action->name);
+               for (action=action->next; action; action = action->next) {
+                       len += sprintf(buf+len, ",%s %s",
+                               (action->flags & SA_INTERRUPT) ? " +" : "",
+                               action->name);
+               }
+               len += sprintf(buf+len, "\n");
+       }
+       len+=sprintf(buf+len, "LCK: %10lu",
+               sum_spins);
+
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10lu",smp_spins[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   spins from int\n");
+
+       len+=sprintf(buf+len, "LCK: %10lu",
+               sum_spins_syscall);
+
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10lu",smp_spins_syscall[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   spins from syscall\n");
+
+       len+=sprintf(buf+len, "LCK: %10lu",
+               sum_spins_sys_idle);
+
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10lu",smp_spins_sys_idle[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   spins from sysidle\n");
+       len+=sprintf(buf+len,"IDLE %10lu",sum_smp_idle_count);
+
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10lu",smp_idle_count[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   idle ticks\n");
+
+       len+=sprintf(buf+len,"TICK %10lu",sum_local_timer_ticks);
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10lu",smp_local_timer_ticks[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   local APIC timer ticks\n");
+
+       len+=sprintf(buf+len,"MULT:          ");
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10u",prof_multiplier[cpu_logical_map[i]]);
+       len +=sprintf(buf+len,"   profiling multiplier\n");
+
+       len+=sprintf(buf+len,"COUNT:         ");
+       for (i=0;i<smp_num_cpus;i++)
+               len+=sprintf(buf+len," %10u",prof_counter[cpu_logical_map[i]]);
+
+       len +=sprintf(buf+len,"   profiling counter\n");
+
+       len+=sprintf(buf+len, "IPI: %10lu   received\n",
+               ipi_count);
+
+       return len;
+}
+#endif 
+
 void free_irq(unsigned int irq, void *dev_id)
 {
        struct irqaction * action;
@@ -185,7 +292,7 @@ void free_irq(unsigned int irq, void *dev_id)
 
 /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */
 unsigned int local_irq_count[NR_CPUS];
-atomic_t __sparc_bh_counter;
+atomic_t __sparc_bh_counter = ATOMIC_INIT(0);
 
 #ifdef __SMP__
 /* SMP interrupt locking on Sparc. */
@@ -200,7 +307,7 @@ spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t global_bh_lock = SPIN_LOCK_UNLOCKED;
 
 /* Global IRQ locking depth. */
-atomic_t global_irq_count = ATOMIC_INIT;
+atomic_t global_irq_count = ATOMIC_INIT(0);
 
 #define irq_active(cpu) \
        (atomic_read(&global_irq_count) != local_irq_count[cpu])
@@ -352,6 +459,10 @@ static void irq_enter(int cpu, int irq)
        extern void smp_irq_rotate(int cpu);
        int stuck = INIT_STUCK;
 
+#ifdef __SMP_PROF__
+       int_count[cpu][irq]++;
+#endif
+
        smp_irq_rotate(cpu);
        hardirq_enter(cpu);
        while(global_irq_lock) {
@@ -408,7 +519,7 @@ void handler_irq(int irq, struct pt_regs * regs)
        int cpu = smp_processor_id();
        
        disable_pil_irq(cpu_irq);
-       irq_enter(cpu, irq);
+       irq_enter(cpu, cpu_irq);
        action = *(cpu_irq + irq_action);
        kstat.interrupts[cpu_irq]++;
        do {
@@ -417,7 +528,7 @@ void handler_irq(int irq, struct pt_regs * regs)
                action->handler(irq, action->dev_id, regs);
                action = action->next;
        } while (action);
-       irq_exit(cpu, irq);
+       irq_exit(cpu, cpu_irq);
        enable_pil_irq(cpu_irq);
 }
 
index 69cb23b049b6158a3515555b776785a8302f51c7..647081edace7fedbda8734f109dd611db6b4ef72 100644 (file)
@@ -889,13 +889,12 @@ out:
 
 asmlinkage void syscall_trace(void)
 {
-       lock_kernel();
 #ifdef DEBUG_PTRACE
        printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
 #endif
        if ((current->flags & (PF_PTRACED|PF_TRACESYS))
                        != (PF_PTRACED|PF_TRACESYS))
-               goto out;
+               return;
        current->exit_code = SIGTRAP;
        current->state = TASK_STOPPED;
        current->tss.flags ^= MAGIC_CONSTANT;
@@ -911,9 +910,9 @@ asmlinkage void syscall_trace(void)
                current->pid, current->exit_code);
 #endif
        if (current->exit_code) {
+               spin_lock_irq(&current->sigmask_lock);
                current->signal |= (1 << (current->exit_code - 1));
+               spin_unlock_irq(&current->sigmask_lock);
        }
        current->exit_code = 0;
-out:
-       unlock_kernel();
 }
index 3eee6df85a4d84bfcc04239bf582e7aa1a0a410d..8a07ae0beea25ae53bb4b179a14c6b8a62fea682 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: signal.c,v 1.72 1997/03/03 16:51:43 jj Exp $
+/*  $Id: signal.c,v 1.73 1997/04/16 05:56:05 davem Exp $
  *  linux/arch/sparc/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -28,7 +28,8 @@
 
 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
-asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options);
+asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+                        int options, unsigned long *ru);
 
 extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
                   void *fpqueue, unsigned long *fpqdepth);
@@ -85,12 +86,15 @@ struct new_signal_frame {
  * atomically swap in the new signal mask, and wait for a signal.
  * This is really tricky on the Sparc, watch out...
  */
-asmlinkage inline void _sigpause_common(unsigned int set, struct pt_regs *regs)
+asmlinkage void _sigpause_common(unsigned int set, struct pt_regs *regs)
 {
        unsigned long mask;
 
+       spin_lock_irq(&current->sigmask_lock);
        mask = current->blocked;
        current->blocked = set & _BLOCKABLE;
+       spin_unlock_irq(&current->sigmask_lock);
+
        regs->pc = regs->npc;
        regs->npc += 4;
 
@@ -115,16 +119,12 @@ asmlinkage inline void _sigpause_common(unsigned int set, struct pt_regs *regs)
 
 asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
 {
-       lock_kernel();
        _sigpause_common(set, regs);
-       unlock_kernel();
 }
 
 asmlinkage void do_sigsuspend (struct pt_regs *regs)
 {
-       lock_kernel();
        _sigpause_common(regs->u_regs[UREG_I0], regs);
-       unlock_kernel();
 }
 
 
@@ -159,26 +159,20 @@ void do_new_sigreturn (struct pt_regs *regs)
        struct new_signal_frame *sf;
        unsigned long up_psr, pc, npc, mask;
        
-       lock_kernel();
        sf = (struct new_signal_frame *) 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);
-               goto out;
-       }
-       if (((uint) sf) & 3){
-               do_exit (SIGSEGV);
-               goto out;
-       }
+       if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
+               goto segv_and_exit;
+
+       if (((uint) sf) & 3)
+               goto segv_and_exit;
 
        __get_user(pc,  &sf->info.si_regs.pc);
        __get_user(npc, &sf->info.si_regs.npc);
 
-       if ((pc | npc) & 3) {
-               do_exit (SIGSEGV);
-               goto out;
-       }
+       if ((pc | npc) & 3)
+               goto segv_and_exit;
        
        /* 2. Restore the state */
        up_psr = regs->psr;
@@ -191,43 +185,55 @@ void do_new_sigreturn (struct pt_regs *regs)
        if (sf->fpu_save)
                restore_fpu_state(regs, sf->fpu_save);
 
+       /* This is pretty much atomic, no amount locking would prevent
+        * the races which exist anyways.
+        */
        __get_user(mask, &sf->info.si_mask);
        current->blocked = (mask & _BLOCKABLE);
-out:
+       return;
+
+segv_and_exit:
+       /* Ugh, we need to grab master lock in these rare cases ;-( */
+       lock_kernel();
+       do_exit(SIGSEGV);
        unlock_kernel();
 }
 
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
        struct sigcontext *scptr;
-       unsigned long pc, npc, psr;
+       unsigned long pc, npc, psr, mask;
 
-       lock_kernel();
        synchronize_user_stack();
-       if (current->tss.new_signal){
-               do_new_sigreturn (regs);
-               goto out;
-       }
+
+       if (current->tss.new_signal)
+               return do_new_sigreturn (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);
-       }
+          (((unsigned long) scptr) & 3))
+               goto segv_and_exit;
+
        __get_user(pc, &scptr->sigc_pc);
        __get_user(npc, &scptr->sigc_npc);
+
        if((pc | npc) & 3)
-               do_exit(SIGSEGV); /* Nice try. */
+               goto segv_and_exit;
+
+       /* This is pretty much atomic, no amount locking would prevent
+        * the races which exist anyways.
+        */
+       __get_user(mask, &scptr->sigc_mask);
+       current->blocked = (mask & _BLOCKABLE);
 
-       __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);
@@ -236,7 +242,12 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
        __get_user(psr, &scptr->sigc_psr);
        regs->psr &= ~(PSR_ICC);
        regs->psr |= (psr & PSR_ICC);
-out:
+       return;
+
+segv_and_exit:
+       /* Ugh, we need to grab master lock in these rare cases ;-( */
+       lock_kernel();
+       do_exit(SIGSEGV);
        unlock_kernel();
 }
 
@@ -252,9 +263,8 @@ int invalid_frame_pointer (void *fp, int fplen)
        return 0;
 }
 
-static inline void
-setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
-           struct pt_regs *regs, int signr, unsigned long oldmask)
+static void setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
+                       struct pt_regs *regs, int signr, unsigned long oldmask)
 {
        struct signal_sframe *sframep;
        struct sigcontext *sc;
@@ -274,8 +284,7 @@ setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
                /* Don't change signal code and address, so that
                 * post mortem debuggers can have a look.
                 */
-               do_exit(SIGILL);
-               return;
+               goto sigill_and_return;
        }
 
        sc = &sframep->sig_context;
@@ -319,6 +328,13 @@ setup_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
        regs->u_regs[UREG_FP] = (unsigned long) sframep;
        regs->pc = (unsigned long) sa->sa_handler;
        regs->npc = (regs->pc + 4);
+       return;
+
+sigill_and_return:
+       /* Ugh, we need to grab master lock in these rare cases ;-( */
+       lock_kernel();
+       do_exit(SIGILL);
+       unlock_kernel();
 }
 
 
@@ -353,9 +369,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
        current->used_math = 0;
 }
 
-
-static inline void
-new_setup_frame(struct sigaction *sa, struct pt_regs *regs, int signo, unsigned long oldmask)
+static void new_setup_frame(struct sigaction *sa, struct pt_regs *regs,
+                           int signo, unsigned long oldmask)
 {
        struct new_signal_frame *sf;
        int sigframe_size;
@@ -369,16 +384,13 @@ new_setup_frame(struct sigaction *sa, struct pt_regs *regs, int signo, unsigned
 
        sf = (struct new_signal_frame *)(regs->u_regs[UREG_FP] - sigframe_size);
 
-       if (invalid_frame_pointer (sf, sigframe_size)){
-               do_exit(SIGILL);
-               return;
-       }
+       if (invalid_frame_pointer (sf, sigframe_size))
+               goto sigill_and_return;
 
-       if (current->tss.w_saved != 0){
+       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;
+               goto sigill_and_return;
        }
 
        /* 2. Save the current process state */
@@ -411,6 +423,12 @@ new_setup_frame(struct sigaction *sa, struct pt_regs *regs, int signo, unsigned
 
        /* Flush instruction space. */
        flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
+       return;
+
+sigill_and_return:
+       lock_kernel();
+       do_exit(SIGILL);
+       unlock_kernel();
 }
 
 
@@ -435,8 +453,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
 #ifdef DEBUG_SIGNALS
                printk ("Invalid stack frame\n");
 #endif
-               do_exit(SIGILL);
-               return;
+               goto sigill_and_return;
        }
 
        /* Start with a clean frame pointer and fill it */
@@ -525,23 +542,26 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
                regs->u_regs[UREG_I1] = (uint) si;
                regs->u_regs[UREG_I2] = (uint) uc;
        }
+       return;
+
+sigill_and_return:
+       lock_kernel();
+       do_exit(SIGILL);
+       unlock_kernel();
 }
 
-asmlinkage int
-svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
+asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
 {
        svr4_gregset_t  *gr;
        svr4_mcontext_t *mc;
-       int ret = -EFAULT;
 
-       lock_kernel();
        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 (current->tss.w_saved)
+               goto sigsegv_and_return;
+
        if(clear_user(uc, sizeof (*uc)))
-               goto out;
+               return -EFAULT;
 
        /* Setup convenience variables */
        mc = &uc->mcontext;
@@ -568,58 +588,53 @@ svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
        /* The register file is not saved
         * we have already stuffed all of it with sync_user_stack
         */
-       ret = 0;
-out:
+       return 0;
+
+sigsegv_and_return:
+       lock_kernel();
+       do_exit(SIGSEGV);
        unlock_kernel();
-       return ret;
+       return -EFAULT;
 }
 
-
 /* Set the context for a svr4 application, this is Solaris way to sigreturn */
 asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
 {
        struct thread_struct *tp = &current->tss;
        svr4_gregset_t  *gr;
-       unsigned long pc, npc, psr;
-       int ret = -EINTR;
+       unsigned long pc, npc, psr, mask;
        
-       lock_kernel();
        /* 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);
-               goto out;
-       }
-       if (((uint) c) & 3){
-               printk ("Unaligned structure passed\n");
-               do_exit (SIGSEGV);
-               goto out;
-       }
+       if (tp->w_saved)
+               goto sigsegv_and_return;
 
-       if(!__access_ok((unsigned long)c, sizeof(*c))) {
-               /* Miguel, add nice debugging msg _here_. ;-) */
-               do_exit(SIGSEGV);
-               goto out;
-       }
+       if (((uint) c) & 3)
+               goto sigsegv_and_return;
+
+       if(!__access_ok((unsigned long)c, sizeof(*c)))
+               goto sigsegv_and_return;
 
        /* 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);
-               goto out;
-       }
+
+       if((pc | npc) & 3)
+               goto sigsegv_and_return;
+
        /* 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;
+       /* 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 */
+
+       /* This is pretty much atomic, no amount locking would prevent
+        * the races which exist anyways.
+        */
+       __get_user(mask, &c->sigmask.sigbits [0]);
+       current->blocked = (mask & _BLOCKABLE);
        regs->pc = pc;
        regs->npc = npc | 1;
        __get_user(regs->y, &((*gr) [SVR4_Y]));
@@ -630,9 +645,13 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
        /* 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);
-out:
+       return 0;
+
+sigsegv_and_return:
+       lock_kernel();
+       do_exit(SIGSEGV);
        unlock_kernel();
-       return ret;
+       return -EFAULT;
 }
 
 static inline void handle_signal(unsigned long signr, struct sigaction *sa,
@@ -649,8 +668,11 @@ static inline void handle_signal(unsigned long signr, struct sigaction *sa,
        }
        if(sa->sa_flags & SA_ONESHOT)
                sa->sa_handler = NULL;
-       if(!(sa->sa_flags & SA_NOMASK))
+       if(!(sa->sa_flags & SA_NOMASK)) {
+               spin_lock_irq(&current->sigmask_lock);
                current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+               spin_unlock_irq(&current->sigmask_lock);
+       }
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
@@ -683,17 +705,23 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
        unsigned long signr, mask = ~current->blocked;
        struct sigaction *sa;
        int svr4_signal = current->personality == PER_SVR4;
-       int ret;
        
-       lock_kernel();
        while ((signr = current->signal & mask) != 0) {
                signr = ffz(~signr);
-               clear_bit(signr, &current->signal);
+
+               spin_lock_irq(&current->sigmask_lock);
+               current->signal &= ~(1 << signr);
+               spin_unlock_irq(&current->sigmask_lock);
+
                sa = current->sig->action + signr;
                signr++;
                if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
                        current->exit_code = signr;
                        current->state = TASK_STOPPED;
+
+                       /* This happens to be SMP safe so no need to
+                        * grab master kernel lock even in this case.
+                        */
                        notify_parent(current);
                        schedule();
                        if (!(signr = current->exit_code))
@@ -702,7 +730,9 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
                        if (signr == SIGSTOP)
                                continue;
                        if (_S(signr) & current->blocked) {
+                               spin_lock_irq(&current->sigmask_lock);
                                current->signal |= _S(signr);
+                               spin_unlock_irq(&current->sigmask_lock);
                                continue;
                        }
                        sa = current->sig->action + signr - 1;
@@ -710,7 +740,14 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
                if(sa->sa_handler == SIG_IGN) {
                        if(signr != SIGCHLD)
                                continue;
-                       while(sys_waitpid(-1,NULL,WNOHANG) > 0);
+
+                       /* sys_wait4() grabs the master kernel lock, so
+                        * we need not do so, that sucker should be
+                        * threaded and would not be that difficult to
+                        * do anyways.
+                        */
+                       while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+                               ;
                        continue;
                }
                if(sa->sa_handler == SIG_DFL) {
@@ -721,6 +758,9 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
                                continue;
 
                        case SIGTSTP: case SIGTTIN: case SIGTTOU:
+                               /* The operations performed by is_orphaned_pgrp()
+                                * are protected by the tasklist_lock.
+                                */
                                if (is_orphaned_pgrp(current->pgrp))
                                        continue;
 
@@ -729,6 +769,8 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
                                        continue;
                                current->state = TASK_STOPPED;
                                current->exit_code = signr;
+
+                               /* notify_parent() is SMP safe */
                                if(!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
                                     SA_NOCLDSTOP))
                                        notify_parent(current);
@@ -748,16 +790,21 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
 #endif
                                /* fall through */
                        default:
+                               spin_lock_irq(&current->sigmask_lock);
                                current->signal |= _S(signr & 0x7f);
+                               spin_unlock_irq(&current->sigmask_lock);
+
                                current->flags |= PF_SIGNALED;
+
+                               lock_kernel(); /* 8-( */
                                do_exit(signr);
+                               unlock_kernel();
                        }
                }
                if(restart_syscall)
                        syscall_restart(orig_i0, regs, sa);
                handle_signal(signr, sa, oldmask, regs, svr4_signal);
-               ret = 1;
-               goto out;
+               return 1;
        }
        if(restart_syscall &&
           (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
@@ -768,10 +815,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs,
                regs->pc -= 4;
                regs->npc -= 4;
        }
-       ret = 0;
-out:
-       unlock_kernel();
-       return ret;
+       return 0;
 }
 
 asmlinkage int
index 8d0d4b5785467dee0d2c42a6b6e8f38474f3aac9..6622f88f0dbf6c695f72bc6f4d7512b490fcb238 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -139,6 +140,8 @@ void smp_commence(void)
        local_flush_tlb_all();
 }
 
+static void smp_setup_percpu_timer(void);
+
 void smp_callin(void)
 {
        int cpuid = smp_processor_id();
@@ -146,6 +149,10 @@ void smp_callin(void)
        local_flush_cache_all();
        local_flush_tlb_all();
        set_irq_udt(mid_xlate[boot_cpu_id]);
+
+       /* Get our local ticker going. */
+       smp_setup_percpu_timer();
+
        calibrate_delay();
        smp_store_cpu_info(cpuid);
        local_flush_cache_all();
@@ -215,6 +222,7 @@ void smp_boot_cpus(void)
        klock_info.akp = boot_cpu_id;
        smp_store_cpu_info(boot_cpu_id);
        set_irq_udt(mid_xlate[boot_cpu_id]);
+       smp_setup_percpu_timer();
        local_flush_cache_all();
        if(linux_num_cpus == 1)
                return;  /* Not an MP box. */
@@ -507,3 +515,101 @@ void smp_stop_cpu_irq(void)
        while(1)
                barrier();
 }
+
+/* Protects counters touched during level14 ticker */
+spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED;
+
+/* 32-bit Sparc specific profiling function. */
+static inline void sparc_do_profile(unsigned long pc)
+{
+       if(prof_buffer && current->pid) {
+               extern int _stext;
+
+               pc -= (unsigned long) &_stext;
+               pc >>= prof_shift;
+
+               spin_lock(&ticker_lock);
+               if(pc < prof_len)
+                       prof_buffer[pc]++;
+               else
+                       prof_buffer[prof_len - 1]++;
+               spin_unlock(&ticker_lock);
+       }
+}
+
+volatile unsigned long smp_local_timer_ticks[1+NR_CPUS]={0,};
+
+unsigned int prof_multiplier[NR_CPUS];
+unsigned int prof_counter[NR_CPUS];
+
+extern void update_one_process(struct task_struct *p, unsigned long ticks,
+                              unsigned long user, unsigned long system);
+
+void smp_percpu_timer_interrupt(struct pt_regs *regs)
+{
+       int cpu = smp_processor_id();
+
+       clear_profile_irq(mid_xlate[cpu]);
+       if(!user_mode(regs))
+               sparc_do_profile(regs->pc);
+       if(!--prof_counter[cpu]) {
+               int user = user_mode(regs);
+               if(current->pid) {
+                       update_one_process(current, 1, user, !user);
+
+                       if(--current->counter < 0) {
+                               current->counter = 0;
+                               need_resched = 1;
+                       }
+
+                       spin_lock(&ticker_lock);
+                       if(user) {
+                               if(current->priority < DEF_PRIORITY)
+                                       kstat.cpu_nice++;
+                               else
+                                       kstat.cpu_user++;
+                       } else {
+                               kstat.cpu_system++;
+                       }
+                       spin_unlock(&ticker_lock);
+               }
+               prof_counter[cpu] = prof_multiplier[cpu];
+       }
+#ifdef __SMP_PROF__
+       smp_local_timer_ticks[cpu]++;
+#endif
+}
+
+extern unsigned int lvl14_resolution;
+
+static void smp_setup_percpu_timer(void)
+{
+       int cpu = smp_processor_id();
+
+       prof_counter[cpu] = prof_multiplier[cpu] = 1;
+       load_profile_irq(mid_xlate[cpu], lvl14_resolution);
+
+       if(cpu == boot_cpu_id)
+               enable_pil_irq(14);
+}
+
+int setup_profiling_timer(unsigned int multiplier)
+{
+       int i;
+       unsigned long flags;
+
+       /* Prevent level14 ticker IRQ flooding. */
+       if((!multiplier) || (lvl14_resolution / multiplier) < 500)
+               return -EINVAL;
+
+       save_and_cli(flags);
+       for(i = 0; i < NR_CPUS; i++) {
+               if(cpu_present_map & (1 << i)) {
+                       load_profile_irq(mid_xlate[i], lvl14_resolution / multiplier);
+                       prof_multiplier[i] = multiplier;
+               }
+       }
+       restore_flags(flags);
+
+       return 0;
+}
index 05d9746be88f24ef763b34337f707fcabf3d9ea1..9a6ea3d6cced16a4a40f7b77fd6152ac8f395ecb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.54 1997/04/14 05:38:25 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.55 1997/04/17 03:28:56 davem Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -87,6 +87,9 @@ EXPORT_SYMBOL(klock_info);
 EXPORT_SYMBOL_PRIVATE(_lock_kernel);
 EXPORT_SYMBOL_PRIVATE(_unlock_kernel);
 EXPORT_SYMBOL_PRIVATE(_spinlock_waitfor);
+EXPORT_SYMBOL_PRIVATE(_rw_read_enter);
+EXPORT_SYMBOL_PRIVATE(_rw_read_exit);
+EXPORT_SYMBOL_PRIVATE(_rw_write_enter);
 EXPORT_SYMBOL(__sparc_bh_counter);
 EXPORT_SYMBOL(page_offset);
 EXPORT_SYMBOL(stack_top);
index e9db016ad6362e7eeebd2e761ee321543d0a5691..bc95696883366e92935ffd64411d0f6f8d399b79 100644 (file)
@@ -111,12 +111,12 @@ static void sun4c_clear_clock_irq(void)
        clear_intr = sun4c_timers->timer_limit10;
 }
 
-static void sun4c_clear_profile_irq(void)
+static void sun4c_clear_profile_irq(int cpu)
 {
        /* Errm.. not sure how to do this.. */
 }
 
-static void sun4c_load_profile_irq(unsigned int limit)
+static void sun4c_load_profile_irq(int cpu, unsigned int limit)
 {
        /* Errm.. not sure how to do this.. */
 }
index 72e89988a69795e54f92b8aa9ce77a003c4b550b..d6420ec68b2a078541d90886b66ad1951a1ff871 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/traps.h>
+#include <asm/pgtable.h>
 #include <asm/smp.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -145,7 +146,7 @@ static unsigned long cpu_pil_to_imask[16] = {
 /*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
 /*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS,
 /*13*/ SUN4M_INT_AUDIO,
-/*14*/ 0x00000000,
+/*14*/ SUN4M_INT_E14,
 /*15*/ 0x00000000
 };
 
@@ -196,37 +197,18 @@ static void sun4m_clear_clock_irq(void)
        clear_intr = sun4m_timers->l10_timer_limit;
 }
 
-static void sun4m_clear_profile_irq(void)
+static void sun4m_clear_profile_irq(int cpu)
 {
        volatile unsigned int clear;
     
-       clear = sun4m_timers->cpu_timers[0].l14_timer_limit;
+       clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit;
 }
 
-static void sun4m_load_profile_irq(unsigned int limit)
+static void sun4m_load_profile_irq(int cpu, unsigned int limit)
 {
-       sun4m_timers->cpu_timers[0].l14_timer_limit = limit;
+       sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit;
 }
 
-#if HANDLE_LVL14_IRQ
-static void sun4m_lvl14_handler(int irq, void *dev_id, struct pt_regs * regs)
-{
-       volatile unsigned int clear;
-    
-       printk("CPU[%d]: TOOK A LEVEL14!\n", smp_processor_id());
-       /* we do nothing with this at present
-        * this is purely to prevent OBP getting its mucky paws
-        * in linux.
-        */
-       clear = sun4m_timers->cpu_timers[0].l14_timer_limit; /* clear interrupt */
-    
-       /* reload with value, this allows on the fly retuning of the level14
-        * timer
-        */
-       sun4m_timers->cpu_timers[0].l14_timer_limit = lvl14_resolution;
-}
-#endif /* HANDLE_LVL14_IRQ */
-
 __initfunc(static void sun4m_init_timers(void (*counter_fn)(int, void *, struct pt_regs *)))
 {
        int reg_count, irq, cpu;
@@ -282,13 +264,6 @@ __initfunc(static void sun4m_init_timers(void (*counter_fn)(int, void *, struct
                prom_halt();
        }
     
-       /* Can't cope with multiple CPUS yet so no level14 tick events */
-#if HANDLE_LVL14_IRQ
-       if (linux_num_cpus > 1)
-               claim_ticker14(NULL, PROFILE_IRQ, 0);
-       else
-               claim_ticker14(sun4m_lvl14_handler, PROFILE_IRQ, lvl14_resolution);
-#endif /* HANDLE_LVL14_IRQ */
        if(linux_num_cpus > 1) {
                for(cpu = 0; cpu < 4; cpu++)
                        sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0;
@@ -296,6 +271,25 @@ __initfunc(static void sun4m_init_timers(void (*counter_fn)(int, void *, struct
        } else {
                sun4m_timers->cpu_timers[0].l14_timer_limit = 0;
        }
+#ifdef __SMP__
+       {
+               unsigned long flags;
+               extern unsigned long lvl14_save[4];
+               struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
+
+               /* For SMP we use the level 14 ticker, however the bootup code
+                * has copied the firmwares level 14 vector into boot cpu's
+                * trap table, we must fix this now or we get squashed.
+                */
+               __save_and_cli(flags);
+               trap_table->inst_one = lvl14_save[0];
+               trap_table->inst_two = lvl14_save[1];
+               trap_table->inst_three = lvl14_save[2];
+               trap_table->inst_four = lvl14_save[3];
+               local_flush_cache_all();
+               __restore_flags(flags);
+       }
+#endif
 }
 
 __initfunc(void sun4m_init_IRQ(void))
@@ -349,10 +343,6 @@ __initfunc(void sun4m_init_IRQ(void))
                 * Not sure, but writing here on SLAVIO systems may puke
                 * so I don't do it unless there is more than 1 cpu.
                 */
-#if 0
-               printk("Warning:"
-                      "sun4m multiple CPU interrupt code requires work\n");
-#endif
                irq_rcvreg = (unsigned long *)
                                &sun4m_interrupts->undirected_target;
                sun4m_interrupts->undirected_target = 0;
index 736b9e63421b97c3cf8bb05ab1cbe8592ae85a3a..d4044f88f818ca6e6c74e03db4bcadd8ab66ad7f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.34 1997/01/06 06:52:35 davem Exp $
+/* $Id: sys_sparc.c,v 1.35 1997/04/16 05:56:09 davem Exp $
  * linux/arch/sparc/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
@@ -254,49 +254,45 @@ asmlinkage int
 sparc_sigaction (int signum, const struct sigaction *action, struct sigaction *oldaction)
 {
        struct sigaction new_sa, *p;
-       int err = -EINVAL;
 
-       lock_kernel();
        if(signum < 0) {
                current->tss.new_signal = 1;
                signum = -signum;
        }
+       if(signum<1 || signum>32)
+               return -EINVAL;
 
-       if (signum<1 || signum>32)
-               goto out;
        p = signum - 1 + current->sig->action;
-       if (action) {
-               err = verify_area(VERIFY_READ,action,sizeof(struct sigaction));
-               if (err)
-                       goto out;
-               err = -EINVAL;
+       if(action) {
+               if(verify_area(VERIFY_READ,action,sizeof(struct sigaction)))
+                       return -EFAULT;
                if (signum==SIGKILL || signum==SIGSTOP)
-                       goto out;
-               err = -EFAULT;
+                       return -EINVAL;
                if(copy_from_user(&new_sa, action, sizeof(struct sigaction)))
-                       goto out;       
+                       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)
-                               goto out;
+                       if(verify_area(VERIFY_READ, new_sa.sa_handler, 1))
+                               return -EFAULT;
                }
        }
 
        if (oldaction) {
-               err = -EFAULT;
+               /* In the clone() case we could copy half consistant
+                * state to the user, however this could sleep and
+                * deadlock us if we held the signal lock on SMP.  So for
+                * now I take the easy way out and do no locking.
+                */
                if (copy_to_user(oldaction, p, sizeof(struct sigaction)))
-                       goto out;       
+                       return -EFAULT; 
        }
 
        if (action) {
+               spin_lock_irq(&current->sig->siglock);
                *p = new_sa;
                check_pending(signum);
+               spin_unlock_irq(&current->sig->siglock);
        }
-
-       err = 0;
-out:
-       unlock_kernel();
-       return err;
+       return 0;
 }
 
 #ifndef CONFIG_AP1000
index d58c43d5358356e078da6a8c3bf3fc06742c3d24..5f5b195045b705d9021d8a18f79309e778db47da 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.77 1997/02/15 01:17:04 davem Exp $
+/* $Id: sys_sunos.c,v 1.78 1997/04/16 05:56:12 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1184,39 +1184,39 @@ asmlinkage int sunos_sigaction(int signum, const struct sigaction *action,
        struct sigaction *oldaction)
 {
        struct sigaction new_sa, *p;
-       const  int sigaction_size = sizeof (struct sigaction) - sizeof (void *);
-       int err = -EINVAL;
+       const int sigaction_size = sizeof (struct sigaction) - sizeof (void *);
 
-       lock_kernel();
        current->personality |= PER_BSD;
-
-       if (signum<1 || signum>32)
-               goto out;
+       if(signum < 1 || signum > 32)
+               return -EINVAL;
 
        p = signum - 1 + current->sig->action;
-       if (action) {
-               err = -EFAULT;
+
+       if(action) {
                if(copy_from_user(&new_sa, action, sigaction_size))
-                       goto out;
-               err = -EINVAL;
+                       return -EFAULT;
                if (signum==SIGKILL || signum==SIGSTOP)
-                       goto out;
+                       return -EINVAL;
                memset(&new_sa, 0, sizeof(struct sigaction));
-               err = -EFAULT;
                if(copy_from_user(&new_sa, action, sigaction_size))
-                       goto out;
+                       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)
-                               goto out;
+                       if(verify_area(VERIFY_READ, new_sa.sa_handler, 1))
+                               return -EFAULT;
                }
                new_sa.sa_flags ^= SUNOS_SV_INTERRUPT;
        }
 
        if (oldaction) {
-               err = -EFAULT;
+               /* In the clone() case we could copy half consistant
+                * state to the user, however this could sleep and
+                * deadlock us if we held the signal lock on SMP.  So for
+                * now I take the easy way out and do no locking.
+                * But then again we don't support SunOS lwp's anyways ;-)
+                */
                if (copy_to_user(oldaction, p, sigaction_size))
-                       goto out;       
+                        return -EFAULT;
+
                if (oldaction->sa_flags & SA_RESTART)
                        oldaction->sa_flags &= ~SA_RESTART;
                else
@@ -1224,13 +1224,12 @@ asmlinkage int sunos_sigaction(int signum, const struct sigaction *action,
        }
 
        if (action) {
+               spin_lock_irq(&current->sig->siglock);
                *p = new_sa;
                check_pending(signum);
+               spin_unlock_irq(&current->sig->siglock);
        }
-       err = 0;
-out:
-       unlock_kernel();
-       return err;
+       return 0;
 }
 
 
index f00c8f18370ebf65de8481fa8492a3a2f78ad4c0..8023443f737c5fd83be29cc18684435163c88c75 100644 (file)
@@ -60,6 +60,8 @@ void install_obp_ticker(void)
 void claim_ticker14(void (*handler)(int, void *, struct pt_regs *),
                    int irq_nr, unsigned int timeout )
 {
+       int cpu = smp_processor_id();
+
        /* first we copy the obp handler instructions
         */
        disable_irq(irq_nr);
@@ -78,7 +80,7 @@ void claim_ticker14(void (*handler)(int, void *, struct pt_regs *),
                         "counter14",
                         NULL)) {
                install_linux_ticker();
-               load_profile_irq(timeout);
+               load_profile_irq(cpu, timeout);
                enable_irq(irq_nr);
        }
 }
index 1a1cea0c050cd56104432c4c8903362022704420..526dd0f28a09c6a162b19175597749486450241b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.27 1997/04/14 05:38:31 davem Exp $
+/* $Id: time.c,v 1.28 1997/04/15 09:01:10 davem Exp $
  * linux/arch/sparc/kernel/time.c
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -54,11 +54,6 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
            last_rtc_update = xtime.tv_sec;
          else
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-
-#ifdef __SMP__
-       /* I really think it should not be done this way... -DaveM */
-       smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0);
-#endif
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
index 07fc786bc26b4ae01d7fc82dd0605299065973db..79667533f3d7ac343ba5227a8126214785b14e37 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: locks.S,v 1.9 1997/04/14 05:38:41 davem Exp $
+/* $Id: locks.S,v 1.11 1997/04/17 03:29:03 davem Exp $
  * locks.S: SMP low-level lock primitives on Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -7,6 +7,7 @@
 #include <asm/cprefix.h>
 #include <asm/ptrace.h>
 #include <asm/psr.h>
+#include <asm/smp.h>
 #include <asm/spinlock.h>
 
        .text
@@ -19,8 +20,8 @@
         * itself in %g1, %g4 must be restored into %o7 when we return,
         * and the caller wants us to return to him at three instructions
         * previous to the call instruction which got us here.  See how
-        * this is used in asm-sparc/smp_lock.h if what I just said
-        * confuses you to no end.
+        * this is used in asm/smp_lock.h and asm/spinlock.h if what I
+        * just said confuses you to no end.
         */
        .globl  ___spinlock_waitfor
 ___spinlock_waitfor:
@@ -59,8 +60,8 @@ ___lock_kernel:
 9:     jmpl    %o7 + 0x8, %g0
         mov    %g4, %o7
 
-       .globl  ___lock_reaquire_kernel
-___lock_reaquire_kernel:
+       .globl  ___lock_reacquire_kernel
+___lock_reacquire_kernel:
        rd      %psr, %g3
        or      %g3, PSR_PIL, %g7
        wr      %g7, 0x0, %psr
@@ -81,9 +82,6 @@ ___lock_reaquire_kernel:
        jmpl    %o7 + 0x8, %g0
         mov    %g4, %o7
 
-#undef NO_PROC_ID
-#define NO_PROC_ID     0xff
-
        .globl  ___unlock_kernel
 ___unlock_kernel:
        addcc   %g2, 1, %g2
@@ -101,3 +99,64 @@ ___unlock_kernel:
        nop; nop; nop;
 1:     jmpl    %o7 + 0x8, %g0
         mov    %g4, %o7
+
+       /* Read/writer locks, as usual this is overly clever to make it
+        * as fast as possible.
+        */
+
+       /* caches... */
+___rw_read_enter_spin_on_wlock:
+       orcc    %g2, 0x0, %g0
+       be,a    ___rw_read_enter
+        ldstub [%g1 + 3], %g2
+       b       ___rw_read_enter_spin_on_wlock
+        ldub   [%g1 + 3], %g2
+___rw_write_enter_spin_on_wlock:
+       orcc    %g2, 0x0, %g0
+       be,a    ___rw_write_enter
+        ldstub [%g1 + 3], %g2
+       b       ___rw_write_enter_spin_on_wlock
+        ldub   [%g1 + 3], %g2
+
+       .globl  ___rw_read_enter
+___rw_read_enter:
+       orcc    %g2, 0x0, %g0
+       bne,a   ___rw_read_enter_spin_on_wlock
+        ldub   [%g1 + 3], %g2
+1:
+       ldstub  [%g1 + 2], %g7
+       orcc    %g7, 0x0, %g0
+       bne     1b
+        ldsh   [%g1], %g2
+       add     %g2, 1, %g2
+       sth     %g2, [%g1]
+       sth     %g0, [%g1 + 2]
+       retl
+        mov    %g4, %o7
+
+       /* We must be careful here to not blow away wlock. */
+       .globl  ___rw_read_exit
+___rw_read_exit_spin:
+       ldstub  [%g1 + 2], %g2
+___rw_read_exit:
+       orcc    %g2, 0x0, %g0
+       bne     ___rw_read_exit_spin
+        ldsh   [%g1], %g7
+       sub     %g7, 1, %g7
+       sth     %g7, [%g1]
+       stb     %g0, [%g1 + 2]
+       retl
+        mov    %g4, %o7
+
+       .globl  ___rw_write_enter
+___rw_write_enter:
+       orcc    %g2, 0x0, %g0
+       bne,a   ___rw_write_enter_spin_on_wlock
+        ldub   [%g1 + 3], %g2
+       ld      [%g1], %g2
+1:
+       andncc  %g2, 0xff, %g0
+       bne,a   1b
+        ld     [%g1], %g2
+       retl
+        mov    %g4, %o7
index 120c797b0b7c305555db56087940bf21c27e83da..bacf9b095f6bd5aecdaaee88ad93fe80b760b648 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.14 1997/04/10 23:32:33 davem Exp $
+# $Id: Makefile,v 1.15 1997/04/14 17:04:49 jj Exp $
 # sparc64/Makefile
 #
 # Makefile for the architecture dependent flags and dependencies on the
@@ -24,7 +24,7 @@ ELF2AOUT64    = elf2aout64
 # debugging of the kernel to get the proper debugging information.
 
 #CFLAGS := $(CFLAGS) -g -pipe -fcall-used-g5 -fcall-used-g7 
-CFLAGS := $(CFLAGS) -pipe -fno-sibling-call \
+CFLAGS := $(CFLAGS) -pipe \
           -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
 
 LINKFLAGS = -T arch/sparc64/vmlinux.lds
index 4fcfb9113463cce0cf9d67b45aa2143c8c720dab..87592dcbf21fa4fe74f60700d40cf399f61c341e 100644 (file)
@@ -107,7 +107,7 @@ CONFIG_BLK_DEV_SR_VENDOR=y
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
-# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 
 #
index 597033696db8d39eb1563e3c9f344141d9a1b994..7d293a88b01f77524484c3eacb4a13da8133b05a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: etrap.S,v 1.10 1997/04/03 13:03:49 davem Exp $
+/* $Id: etrap.S,v 1.11 1997/04/14 17:04:45 jj Exp $
  * etrap.S: Preparing for entry into the kernel on Sparc V9.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -19,9 +19,8 @@
 etrap:
        rdpr            %pil, %g4
 etrap_irq:
-       rdpr            %wstate, %g5
-       sllx            %g4, 20, %g4
        rdpr            %tstate, %g1
+       sllx            %g4, 20, %g4
        rdpr            %tpc, %g2
        or              %g1, %g4, %g1
        rdpr            %tnpc, %g3
@@ -39,6 +38,7 @@ etrap_irq:
         * trap level until PRIMARY_CONTEXT is set to zero, else
         * we fall out of NUCLEUS too soon and crash hard.
         */
+       rdpr            %wstate, %g5
        mov             PRIMARY_CONTEXT, %g7
        ldxa            [%g7] ASI_DMMU, %g4
        mov             SECONDARY_CONTEXT, %g6
index fc84bfaf934ade6fc15a78ea760ae7df277f0293..08a4a6b6ac7ff7d0e243d6b2270c28b26cb647ba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: idprom.c,v 1.1 1996/12/28 18:39:38 davem Exp $
+/* $Id: idprom.c,v 1.2 1997/04/17 02:28:10 miguel Exp $
  * idprom.c: Routines to load the idprom into kernel addresses and
  *           interpret the data contained within.
  *
@@ -34,14 +34,12 @@ __initfunc(void idprom_init(void))
        idprom = &idprom_buffer;
 
        if (idprom->id_format != 0x01)  {
-               prom_printf("IDPROM: Unknown format type!\n");
-               prom_halt();
+               prom_printf("IDPROM: Warning, unknown format type!\n");
        }
 
        if (idprom->id_cksum != calc_idprom_cksum(idprom)) {
-               prom_printf("IDPROM: Checksum failure (nvram=%x, calc=%x)!\n",
+               prom_printf("IDPROM: Warning, 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",
index 66c7cd877415490613a378a8cabbed0b6568edc0..bc9a8053e360ab5a3558fdf9f7f170827f1d7ee3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.11 1997/04/14 05:38:59 davem Exp $
+/* $Id: irq.c,v 1.12 1997/04/16 05:56:20 davem Exp $
  * irq.c: UltraSparc IRQ handling/init/registry.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -382,7 +382,7 @@ void free_irq(unsigned int irq, void *dev_cookie)
 
 /* Per-processor IRQ locking depth, both SMP and non-SMP code use this. */
 unsigned int local_irq_count[NR_CPUS];
-atomic_t __sparc64_bh_counter;
+atomic_t __sparc64_bh_counter = ATOMIC_INIT(0);
 
 #ifdef __SMP__
 #error SMP not supported on sparc64 just yet
index 1d40d0a6a60bc131b91319a6ee9fa9a7643f4dee..e1129dfd669f7c91659320c0d4d8742de1be286e 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: signal32.c,v 1.5 1997/04/07 18:57:09 jj Exp $
+/*  $Id: signal32.c,v 1.6 1997/04/16 10:27:17 jj Exp $
  *  arch/sparc64/kernel/signal32.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -32,7 +32,8 @@
 
 #define synchronize_user_stack() do { } while (0)
 
-asmlinkage int sys_waitpid(pid_t pid, unsigned long *stat_addr, int options);
+asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+                        int options, unsigned long *ru);
 
 asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
                         unsigned long orig_o0, int ret_from_syscall);
@@ -85,12 +86,15 @@ struct new_signal_frame32 {
  * 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)
+asmlinkage void _sigpause32_common(unsigned int set, struct pt_regs *regs)
 {
        unsigned int mask;
 
+       spin_lock_irq(&current->sigmask_lock);
        mask = current->blocked;
        current->blocked = set & _BLOCKABLE;
+       spin_unlock_irq(&current->sigmask_lock);
+       
        regs->tpc = regs->tnpc;
        regs->tnpc += 4;
 
@@ -115,16 +119,12 @@ asmlinkage inline void _sigpause32_common(unsigned int set, struct pt_regs *regs
 
 asmlinkage void do_sigpause32(unsigned int set, struct pt_regs *regs)
 {
-       lock_kernel ();
        _sigpause32_common(set, regs);
-       unlock_kernel ();
 }
 
 asmlinkage void do_sigsuspend32(struct pt_regs *regs)
 {
-       lock_kernel ();
        _sigpause32_common(regs->u_regs[UREG_I0], regs);
-       unlock_kernel ();
 }
 
 
@@ -158,15 +158,15 @@ void do_new_sigreturn32(struct pt_regs *regs)
        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);
+               goto segv;
        }
        if (((unsigned long) sf) & 3){
-               do_exit (SIGSEGV);
+               goto segv;
        }
        get_user(pc, &sf->info.si_regs.pc);
        __get_user(npc, &sf->info.si_regs.npc);
        if ((pc | npc) & 3){
-               do_exit (SIGSEGV);
+               goto segv;
        }
        regs->tpc = pc;
        regs->tnpc = npc;
@@ -187,15 +187,18 @@ void do_new_sigreturn32(struct pt_regs *regs)
                restore_fpu_state32(regs, &sf->fpu_state);
        __get_user(mask, &sf->info.si_mask);
        current->blocked = mask & _BLOCKABLE;
-       unlock_kernel();
+       return;
+segv:
+       lock_kernel();
+       do_exit(SIGSEGV);
 }
 
 asmlinkage void do_sigreturn32(struct pt_regs *regs)
 {
        struct sigcontext32 *scptr;
        unsigned pc, npc, psr;
+       unsigned long mask;
 
-       lock_kernel ();
        synchronize_user_stack();
        if (current->tss.new_signal)
                return do_new_sigreturn32(regs);
@@ -204,18 +207,15 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
        /* Check sanity of the user arg. */
        if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
           (((unsigned long) scptr) & 3)) {
-               printk("%s [%d]: do_sigreturn, scptr is invalid at "
-                      "pc<%016lx> scptr<%p>\n",
-                      current->comm, current->pid, regs->tpc, scptr);
-               do_exit(SIGSEGV);
+               goto segv;
        }
        __get_user(pc, &scptr->sigc_pc);
        __get_user(npc, &scptr->sigc_npc);
        if((pc | npc) & 3)
-               do_exit(SIGSEGV); /* Nice try. */
+               goto segv; /* Nice try. */
 
-       __get_user(current->blocked, &scptr->sigc_mask);
-       current->blocked &= _BLOCKABLE;
+       __get_user(mask, &scptr->sigc_mask);
+       current->blocked = (mask & _BLOCKABLE);
        __get_user(current->tss.sstk_info.cur_status, &scptr->sigc_onstack);
        current->tss.sstk_info.cur_status &= 1;
        regs->tpc = pc;
@@ -228,7 +228,10 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
        __get_user(psr, &scptr->sigc_psr);
        regs->tstate &= ~(TSTATE_ICC);
        regs->tstate |= psr_to_tstate_icc(psr);
-       unlock_kernel ();
+       return;
+segv:
+       lock_kernel ();
+       do_exit (SIGSEGV);
 }
 
 /* Checks if the fp is valid */
@@ -239,7 +242,7 @@ static int invalid_frame_pointer(void *fp, int fplen)
        return 0;
 }
 
-static inline void
+static void
 setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
              struct pt_regs *regs, int signr, unsigned long oldmask)
 {
@@ -264,8 +267,8 @@ setup_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
                /* Don't change signal code and address, so that
                 * post mortem debuggers can have a look.
                 */
+               lock_kernel ();
                do_exit(SIGILL);
-               return;
        }
 
        sc = &sframep->sig_context;
@@ -358,15 +361,15 @@ new_setup_frame32(struct sigaction *sa, struct pt_regs *regs,
        sf = (struct new_signal_frame32 *)(regs->u_regs[UREG_FP] - sigframe_size);
        
        if (invalid_frame_pointer (sf, sigframe_size)){
+               lock_kernel ();
                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);
+               lock_kernel ();
                do_exit (SIGILL);
-               return;
        }
 
        /* 2. Save the current process state */
@@ -433,8 +436,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
 #ifdef DEBUG_SIGNALS
                printk ("Invalid stack frame\n");
 #endif
+               lock_kernel ();
                do_exit(SIGILL);
-               return;
        }
 
        /* Start with a clean frame pointer and fill it */
@@ -705,7 +708,14 @@ asmlinkage int do_signal32(unsigned long oldmask, struct pt_regs * regs,
                if(sa->sa_handler == SIG_IGN) {
                        if(signr != SIGCHLD)
                                continue;
-                       while(sys_waitpid(-1,NULL,WNOHANG) > 0);
+
+                        /* sys_wait4() grabs the master kernel lock, so
+                         * we need not do so, that sucker should be
+                         * threaded and would not be that difficult to
+                         * do anyways.
+                         */
+                        while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+                                ;
                        continue;
                }
                if(sa->sa_handler == SIG_DFL) {
index 4b791e86eb874ef22a8d39b2f64ab845d4a8740e..91426c814f2164992311d3a0b65dfc5eba8bb3db 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.3 1997/03/18 17:59:10 jj Exp $
+/* $Id: sparc64_ksyms.c,v 1.4 1997/04/14 17:04:43 jj Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -162,7 +162,8 @@ EXPORT_SYMBOL(__memmove);
 EXPORT_SYMBOL(__csum_partial_copy_sparc_generic);
 
 /* Moving data to/from userspace. */
-EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(__copy_to_user);
+EXPORT_SYMBOL(__copy_from_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 
 /* No version information on this, heavily used in inline asm,
index 88c24131a2982c39389a158b60a02a6e63f86cf3..855c636e45bb91d600cf023e2d386e0d344d6083 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/shm.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -156,20 +157,20 @@ __u32 *create_elf32_tables(char *p, int argc, int envc,
        sp -= argc+1;
        argv = (__u32 *) sp;
        if (!ibcs) {
-               __put_user(((__u32) envp),--sp);
-               __put_user(((__u32) argv),--sp);
+               __put_user(((__u32)(long) envp),--sp);
+               __put_user(((__u32)(long) argv),--sp);
        }
 
        __put_user((__u32)argc,--sp);
        current->mm->arg_start = (unsigned long) p;
        while (argc-->0) {
-               __put_user(((__u32)p),argv++);
+               __put_user(((__u32)(long)p),argv++);
                p += strlen_user(p);
        }
        __put_user(NULL, argv);
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
        while (envc-->0) {
-               __put_user(((__u32)p),envp++);
+               __put_user(((__u32)(long)p),envp++);
                p += strlen_user(p);
        }
        __put_user(NULL, envp);
@@ -1108,7 +1109,7 @@ static int elf32_core_dump(long signr, struct pt_regs * regs)
 #else
        if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
        {
-               printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n",
+               printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
                        sizeof(elf_gregset_t), sizeof(struct pt_regs));
        }
        else
@@ -1255,7 +1256,7 @@ static int elf32_core_dump(long signr, struct pt_regs * regs)
 }
 #endif         /* USE_ELF_CORE_DUMP */
 
-int init_elf32_binfmt(void)
+__initfunc(int init_elf32_binfmt(void))
 {
        return register_binfmt(&elf32_format);
 }
index 543fbcecdb3d2e75d0545c3fdf86537fd236412c..07d8717241949a249fa91cb1657350e9d81f5135 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.3 1997/04/09 08:25:17 jj Exp $
+/* $Id: sys_sparc32.c,v 1.6 1997/04/16 14:52:29 jj Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -14,6 +14,7 @@
 #include <linux/resource.h>
 #include <linux/sched.h>
 #include <linux/times.h>
+#include <linux/utime.h>
 #include <linux/utsname.h>
 #include <linux/timex.h>
 #include <linux/smp.h>
@@ -21,6 +22,8 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
+#include <linux/malloc.h>
+#include <linux/uio.h>
 
 #include <asm/types.h>
 #include <asm/poll.h>
@@ -32,9 +35,6 @@
  * produce warnings */
 #define A(x) ((unsigned long)x)
  
-/* FIXME: All struct * etc. stuff should be examined and proper structure conversions
- * added ASAP -JJ */
-
 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
 extern asmlinkage unsigned long sys_brk(unsigned long brk);
 extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off);
@@ -69,7 +69,6 @@ extern asmlinkage long sys_read(unsigned int fd, char * buf, unsigned long count
 extern asmlinkage long sys_write(unsigned int fd, const char * buf, unsigned long count);
 extern asmlinkage long sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count);
 extern asmlinkage long sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count);
-extern asmlinkage int sys_getdents(unsigned int fd, void * dirent, unsigned int count);
 extern asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp);
 extern asmlinkage int sys_poll(struct pollfd * ufds, unsigned int nfds, int timeout);
 extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
@@ -142,6 +141,50 @@ asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
        return sys_ioperm((unsigned long)from, (unsigned long)num, on);
 }
 
+struct msgbuf32 { s32 mtype; char mtext[1]; };
+
+struct ipc_perm32
+{
+       key_t             key;
+        __kernel_uid_t32  uid;
+        __kernel_gid_t32  gid;
+        __kernel_uid_t32  cuid;
+        __kernel_gid_t32  cgid;
+        __kernel_mode_t32 mode;
+        unsigned short  seq;
+};
+
+struct msqid_ds32
+{
+        struct ipc_perm32 msg_perm;
+        u32 msg_first;
+        u32 msg_last;
+        __kernel_time_t32 msg_stime;
+        __kernel_time_t32 msg_rtime;
+        __kernel_time_t32 msg_ctime;
+        u32 wwait;
+        u32 rwait;
+        unsigned short msg_cbytes;
+        unsigned short msg_qnum;  
+        unsigned short msg_qbytes;
+        __kernel_ipc_pid_t32 msg_lspid;
+        __kernel_ipc_pid_t32 msg_lrpid;
+};
+
+struct shmid_ds32 {
+        struct ipc_perm32       shm_perm;
+        int                     shm_segsz;
+        __kernel_time_t32       shm_atime;
+        __kernel_time_t32       shm_dtime;
+        __kernel_time_t32       shm_ctime;
+        __kernel_ipc_pid_t32    shm_cpid; 
+        __kernel_ipc_pid_t32    shm_lpid; 
+        unsigned short          shm_nattch;
+        unsigned short          shm_npages;
+        u32                    shm_pages;
+        u32                    attaches; 
+};
+                                                        
 /*
  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
  *
@@ -184,32 +227,111 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
        if (call <= MSGCTL) 
                switch (call) {
                case MSGSND:
-                       /* XXX struct msgbuf has a long first :(( */
-                       err = sys_msgsnd (first, (struct msgbuf *) A(ptr), 
-                                         second, third);
+                       {
+                               struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL);
+                               
+                               if (!p) err = -ENOMEM;
+                               else {
+                                       if (get_user(p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) ||
+                                           __copy_from_user(p->mtext, &(((struct msgbuf32 *)A(ptr))->mtext), second))
+                                               err = -EFAULT;
+                                       else {
+                                               unsigned long old_fs = get_fs();
+                                               set_fs (KERNEL_DS);
+                                               err = sys_msgsnd (first, p, second, third);
+                                               set_fs (old_fs);
+                                       }
+                                       kfree (p);
+                               }
+                       }
                        goto out;
                case MSGRCV:
-                       switch (version) {
-                       case 0: {
-                               struct ipc_kludge tmp;
-                               err = -EINVAL;
-                               if (!ptr)
-                                       goto out;
-                               err = -EFAULT;
-                               if(copy_from_user(&tmp,(struct ipc_kludge *) ptr, sizeof (tmp)))
+                       {
+                               struct msgbuf *p;
+                               unsigned long old_fs;
+                               
+                               if (!version) {
+                                       struct ipc_kludge tmp;
+                                       err = -EINVAL;
+                                       if (!ptr)
+                                               goto out;
+                                       err = -EFAULT;
+                                       if(copy_from_user(&tmp,(struct ipc_kludge *)A(ptr), sizeof (tmp)))
+                                               goto out;
+                                       ptr = tmp.msgp;
+                                       fifth = tmp.msgtyp;
+                               }
+                               p = kmalloc (second + sizeof (struct msgbuf), GFP_KERNEL);
+                               if (!p) {
+                                       err = -EFAULT;
                                        goto out;
-                               err = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
-                               goto out;
                                }
-                       case 1: default:
-                               err = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
+                               old_fs = get_fs();
+                               set_fs (KERNEL_DS);
+                               err = sys_msgrcv (first, p, second, fifth, third);
+                               set_fs (old_fs);
+                               if (put_user (p->mtype, &(((struct msgbuf32 *)A(ptr))->mtype)) ||
+                                   __copy_to_user(&(((struct msgbuf32 *)A(ptr))->mtext), p->mtext, second))
+                                       err = -EFAULT;
+                               kfree (p);
                                goto out;
                        }
                case MSGGET:
                        err = sys_msgget ((key_t) first, second);
                        goto out;
                case MSGCTL:
-                       err = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+                       {
+                               struct msqid_ds m;
+                               unsigned long old_fs;
+                               
+                               switch (second) {
+                                       case IPC_INFO:
+                                       case MSG_INFO:
+                                               /* struct msginfo is the same */
+                                       case IPC_RMID:
+                                               /* and this doesn't care about ptr */
+                                               err = sys_msgctl (first, second, (struct msqid_ds *)A(ptr));
+                                               goto out;
+                                               
+                                       case IPC_SET:
+                                               if (get_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) ||
+                                                   __get_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) ||
+                                                   __get_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) ||
+                                                   __get_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes))) {
+                                                       err = -EFAULT;  
+                                                       goto out;
+                                               }
+                                       default:
+                                               break;
+                               }
+                               old_fs = get_fs();
+                               set_fs (KERNEL_DS);
+                               err = sys_msgctl (first, second, &m);
+                               set_fs (old_fs);
+                               switch (second) {
+                                       case MSG_STAT:
+                                       case IPC_STAT:
+                                               if (put_user (m.msg_perm.key, &(((struct msqid_ds32 *)A(ptr))->msg_perm.key)) ||
+                                                   __put_user (m.msg_perm.uid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.uid)) ||
+                                                   __put_user (m.msg_perm.gid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.gid)) ||
+                                                   __put_user (m.msg_perm.cuid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cuid)) ||
+                                                   __put_user (m.msg_perm.cgid, &(((struct msqid_ds32 *)A(ptr))->msg_perm.cgid)) ||
+                                                   __put_user (m.msg_perm.mode, &(((struct msqid_ds32 *)A(ptr))->msg_perm.mode)) ||
+                                                   __put_user (m.msg_perm.seq, &(((struct msqid_ds32 *)A(ptr))->msg_perm.seq)) ||
+                                                   __put_user (m.msg_stime, &(((struct msqid_ds32 *)A(ptr))->msg_stime)) ||
+                                                   __put_user (m.msg_rtime, &(((struct msqid_ds32 *)A(ptr))->msg_rtime)) ||
+                                                   __put_user (m.msg_ctime, &(((struct msqid_ds32 *)A(ptr))->msg_ctime)) ||
+                                                   __put_user (m.msg_cbytes, &(((struct msqid_ds32 *)A(ptr))->msg_cbytes)) ||
+                                                   __put_user (m.msg_qnum, &(((struct msqid_ds32 *)A(ptr))->msg_qnum)) ||
+                                                   __put_user (m.msg_qbytes, &(((struct msqid_ds32 *)A(ptr))->msg_qbytes)) ||
+                                                   __put_user (m.msg_lspid, &(((struct msqid_ds32 *)A(ptr))->msg_lspid)) ||
+                                                   __put_user (m.msg_lrpid, &(((struct msqid_ds32 *)A(ptr))->msg_lrpid)))
+                                                       err = -EFAULT;
+                                               break;
+                                       default:
+                                               break;
+                               }
+                       }
                        goto out;
                default:
                        err = -EINVAL;
@@ -220,28 +342,92 @@ asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u
                case SHMAT:
                        switch (version) {
                        case 0: default: {
-                               ulong raddr;
-                               err = sys_shmat (first, (char *) ptr, second, &raddr);
+                               unsigned long raddr;
+                               err = sys_shmat (first, (char *)A(ptr), second, &raddr);
                                if (err)
                                        goto out;
                                err = -EFAULT;
-                               if(put_user (raddr, (ulong *) third))
+                               if(put_user (raddr, ((u32 *)A(third))))
                                        goto out;
                                err = 0;
                                goto out;
                                }
-                       case 1: /* iBCS2 emulator entry point */
-                               err = sys_shmat (first, (char *) ptr, second, (ulong *) third);
+                       case 1: /* If iBCS2 should ever run, then for sure in 64bit mode, not 32bit... */
+                               err = -EINVAL;
                                goto out;
                        }
                case SHMDT: 
-                       err = sys_shmdt ((char *)ptr);
+                       err = sys_shmdt ((char *)A(ptr));
                        goto out;
                case SHMGET:
                        err = sys_shmget (first, second, third);
                        goto out;
                case SHMCTL:
-                       err = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+                       {
+                               struct shmid_ds s;
+                               unsigned long old_fs;
+                               
+                               switch (second) {
+                                       case IPC_INFO:
+                                               /* struct shminfo is the same */
+                                       case SHM_LOCK:
+                                       case SHM_UNLOCK:
+                                       case IPC_RMID:
+                                               /* and these three aren't using ptr at all */
+                                               err = sys_shmctl (first, second, (struct shmid_ds *)A(ptr));
+                                               goto out;
+                                               
+                                       case IPC_SET:
+                                               if (get_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) ||
+                                                   __get_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) ||
+                                                   __get_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode))) {
+                                                       err = -EFAULT; 
+                                                       goto out;
+                                               }
+                                       default:
+                                               break;
+                               }
+                               old_fs = get_fs();
+                               set_fs (KERNEL_DS);
+                               err = sys_shmctl (first, second, &s);
+                               set_fs (old_fs);
+                               switch (second) {
+                                       case SHM_INFO:
+                                               {
+                                                       struct shm_info32 { int used_ids; u32 shm_tot; u32 shm_rss; u32 shm_swp; u32 swap_attempts; u32 swap_successes; };
+                                                       struct shm_info *si = (struct shm_info *)&s;
+
+                                                       if (put_user (si->used_ids, &(((struct shm_info32 *)A(ptr))->used_ids)) ||
+                                                           __put_user (si->shm_tot, &(((struct shm_info32 *)A(ptr))->shm_tot)) ||
+                                                           __put_user (si->shm_rss, &(((struct shm_info32 *)A(ptr))->shm_rss)) ||
+                                                           __put_user (si->shm_swp, &(((struct shm_info32 *)A(ptr))->shm_swp)) ||
+                                                           __put_user (si->swap_attempts, &(((struct shm_info32 *)A(ptr))->swap_attempts)) ||
+                                                           __put_user (si->swap_successes, &(((struct shm_info32 *)A(ptr))->swap_successes)))
+                                                               err = -EFAULT;
+                                               }
+                                               break;
+                                       case SHM_STAT:
+                                       case IPC_STAT:
+                                               if (put_user (s.shm_perm.key, &(((struct shmid_ds32 *)A(ptr))->shm_perm.key)) ||
+                                                   __put_user (s.shm_perm.uid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.uid)) ||
+                                                   __put_user (s.shm_perm.gid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.gid)) ||
+                                                   __put_user (s.shm_perm.cuid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cuid)) ||
+                                                   __put_user (s.shm_perm.cgid, &(((struct shmid_ds32 *)A(ptr))->shm_perm.cgid)) ||
+                                                   __put_user (s.shm_perm.mode, &(((struct shmid_ds32 *)A(ptr))->shm_perm.mode)) ||
+                                                   __put_user (s.shm_perm.seq, &(((struct shmid_ds32 *)A(ptr))->shm_perm.seq)) ||
+                                                   __put_user (s.shm_atime, &(((struct shmid_ds32 *)A(ptr))->shm_atime)) ||
+                                                   __put_user (s.shm_dtime, &(((struct shmid_ds32 *)A(ptr))->shm_dtime)) ||
+                                                   __put_user (s.shm_ctime, &(((struct shmid_ds32 *)A(ptr))->shm_ctime)) ||
+                                                   __put_user (s.shm_segsz, &(((struct shmid_ds32 *)A(ptr))->shm_segsz)) ||
+                                                   __put_user (s.shm_nattch, &(((struct shmid_ds32 *)A(ptr))->shm_nattch)) ||
+                                                   __put_user (s.shm_lpid, &(((struct shmid_ds32 *)A(ptr))->shm_cpid)) ||
+                                                   __put_user (s.shm_cpid, &(((struct shmid_ds32 *)A(ptr))->shm_lpid)))
+                                                       err = -EFAULT;
+                                               break;
+                                       default:
+                                               break;
+                               }
+                       }
                        goto out;
                default:
                        err = -EINVAL;
@@ -272,15 +458,45 @@ asmlinkage int sys32_uselib(u32 library)
 
 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, u32 arg)
 {
-       return sys_fcntl(fd, cmd, (unsigned long)arg);
+       switch (cmd) {
+       case F_GETLK:
+       case F_SETLK:
+       case F_SETLKW:
+               {
+                       struct flock f;
+                       unsigned long old_fs;
+                       long ret;
+                       
+                       if (get_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) ||
+                           __get_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) ||
+                           __get_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) ||
+                           __get_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) ||
+                           __get_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid)))
+                               return -EFAULT;
+                       old_fs = get_fs(); set_fs (KERNEL_DS);
+                       ret = sys_fcntl(fd, cmd, (unsigned long)&f);
+                       set_fs (old_fs);
+                       if (__put_user (f.l_type, &(((struct flock32 *)A(arg))->l_type)) ||
+                           __put_user (f.l_whence, &(((struct flock32 *)A(arg))->l_whence)) ||
+                           __put_user (f.l_start, &(((struct flock32 *)A(arg))->l_start)) ||
+                           __put_user (f.l_len, &(((struct flock32 *)A(arg))->l_len)) ||
+                           __put_user (f.l_pid, &(((struct flock32 *)A(arg))->l_pid)))
+                               return -EFAULT;
+                       return ret;
+               }
+       default:
+               return sys_fcntl(fd, cmd, (unsigned long)arg);
+       }
 }
 
+/* Conversion of args should be probably done in all the locations where it is handled,
+   using if (current->tss.flags & SPARC_FLAG_32BIT */
 asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, u32 arg)
 {
        return sys_ioctl(fd, cmd, (unsigned long)arg);
 }
 
-asmlinkage int sys32_mknod(u32 filename, int mode, dev_t dev)
+asmlinkage int sys32_mknod(u32 filename, int mode, __kernel_dev_t32 dev)
 {
        return sys_mknod((const char *)A(filename), mode, dev);
 }
@@ -315,19 +531,52 @@ asmlinkage int sys32_rename(u32 oldname, u32 newname)
        return sys_rename((const char *)A(oldname), (const char *)A(newname));
 }
 
+/* XXX: Play with the addr, it will be ugly :(( */
 asmlinkage int sys32_quotactl(int cmd, u32 special, int id, u32 addr)
 {
        return sys_quotactl(cmd, (const char *)A(special), id, (caddr_t)A(addr));
 }
 
+static int put_statfs (u32 buf, struct statfs *s)
+{
+       if (put_user (s->f_type, &(((struct statfs32 *)A(buf))->f_type)) ||
+           __put_user (s->f_bsize, &(((struct statfs32 *)A(buf))->f_bsize)) ||
+           __put_user (s->f_blocks, &(((struct statfs32 *)A(buf))->f_blocks)) ||
+           __put_user (s->f_bfree, &(((struct statfs32 *)A(buf))->f_bfree)) ||
+           __put_user (s->f_bavail, &(((struct statfs32 *)A(buf))->f_bavail)) ||
+           __put_user (s->f_files, &(((struct statfs32 *)A(buf))->f_files)) ||
+           __put_user (s->f_ffree, &(((struct statfs32 *)A(buf))->f_ffree)) ||
+           __put_user (s->f_namelen, &(((struct statfs32 *)A(buf))->f_namelen)) ||
+           __put_user (s->f_fsid.val[0], &(((struct statfs32 *)A(buf))->f_fsid.val[0])) ||
+           __put_user (s->f_fsid.val[1], &(((struct statfs32 *)A(buf))->f_fsid.val[1])))
+               return -EFAULT;
+       return 0;
+}
+
 asmlinkage int sys32_statfs(u32 path, u32 buf)
 {
-       return sys_statfs((const char *)A(path), (struct statfs *)A(buf));
+       int ret;
+       struct statfs s;
+       unsigned long old_fs = get_fs();
+       
+       set_fs (KERNEL_DS);
+       ret = sys_statfs((const char *)A(path), &s);
+       set_fs (old_fs);
+       if (put_statfs(buf, &s)) return -EFAULT;
+       return ret;
 }
 
 asmlinkage int sys32_fstatfs(unsigned int fd, u32 buf)
 {
-       return sys_fstatfs(fd, (struct statfs *)A(buf));
+       int ret;
+       struct statfs s;
+       unsigned long old_fs = get_fs();
+       
+       set_fs (KERNEL_DS);
+       ret = sys_fstatfs(fd, &s);
+       set_fs (old_fs);
+       if (put_statfs(buf, &s)) return -EFAULT;
+       return ret;
 }
 
 asmlinkage int sys32_truncate(u32 path, u32 length)
@@ -342,11 +591,24 @@ asmlinkage int sys32_ftruncate(unsigned int fd, u32 length)
 
 asmlinkage int sys32_utime(u32 filename, u32 times)
 {
-       return sys_utime((char *)A(filename), (struct utimbuf *)A(times));
+       struct utimbuf32 { __kernel_time_t32 actime, modtime; };
+       struct utimbuf t;
+       unsigned long old_fs;
+       int ret;
+       
+       if (get_user (t.actime, &(((struct utimbuf32 *)A(times))->actime)) ||
+           __get_user (t.modtime, &(((struct utimbuf32 *)A(times))->modtime)))
+               return -EFAULT;
+       old_fs = get_fs();
+       set_fs (KERNEL_DS); 
+       ret = sys_utime((char *)A(filename), &t);
+       set_fs (old_fs);
+       return ret;
 }
 
 asmlinkage int sys32_utimes(u32 filename, u32 utimes)
 {
+       /* struct timeval is the same :)) */
        return sys_utimes((char *)A(filename), (struct timeval *)A(utimes));
 }
 
@@ -365,12 +627,12 @@ asmlinkage int sys32_chroot(u32 filename)
        return sys_chroot((const char *)A(filename));
 }
 
-asmlinkage int sys32_chmod(u32 filename, mode_t mode)
+asmlinkage int sys32_chmod(u32 filename, __kernel_mode_t32 mode)
 {
        return sys_chmod((const char *)A(filename), mode);
 }
 
-asmlinkage int sys32_chown(u32 filename, uid_t user, gid_t group)
+asmlinkage int sys32_chown(u32 filename, __kernel_uid_t32 user, __kernel_gid_t32 group)
 {
        return sys_chown((const char *)A(filename), user, group);
 }
@@ -392,6 +654,7 @@ asmlinkage long sys32_lseek(unsigned int fd, s32 offset, unsigned int origin)
 
 asmlinkage int sys32_llseek(unsigned int fd, u32 offset_high, u32 offset_low, u32 result, unsigned int origin)
 {
+       /* loff_t is the same :)) */
        return sys_llseek(fd, (unsigned long)offset_high, (unsigned long)offset_low, (loff_t *)A(result), origin);
 }
 
@@ -407,22 +670,234 @@ asmlinkage long sys32_write(unsigned int fd, u32 buf, u32 count)
 
 asmlinkage long sys32_readv(u32 fd, u32 vector, u32 count)
 {
-       return sys_readv((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count);
+       struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
+       struct iovec *v;
+       u32 i;
+       long ret;
+       unsigned long old_fs;
+       
+       if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL;
+       v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM;
+       for (i = 0; i < count; i++) {
+               if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) ||
+                   __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) {
+                       kfree (v);
+                       return -EFAULT;
+               }
+       }
+       old_fs = get_fs();
+       set_fs (KERNEL_DS);
+       ret = sys_readv((unsigned long)fd, v, (unsigned long)count);
+       set_fs (old_fs);
+       kfree (v);
+       return ret;
 }
 
 asmlinkage long sys32_writev(u32 fd, u32 vector, u32 count)
 {
-       return sys_writev((unsigned long)fd, (const struct iovec *)A(vector), (unsigned long)count);
+       struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
+       struct iovec *v;
+       u32 i;
+       long ret;
+       unsigned long old_fs;
+       
+       if (!count) return 0; if (count > UIO_MAXIOV) return -EINVAL;
+       v = kmalloc (count * sizeof (struct iovec), GFP_KERNEL); if (!v) return -ENOMEM;
+       for (i = 0; i < count; i++) {
+               if (__get_user ((unsigned long)(v[i].iov_base), &((((struct iovec32 *)A(vector))+i)->iov_base)) ||
+                   __get_user (v[i].iov_len, &((((struct iovec32 *)A(vector))+i)->iov_len))) {
+                       kfree (v);
+                       return -EFAULT;
+               }
+       }
+       old_fs = get_fs();
+       set_fs (KERNEL_DS);
+       ret = sys_writev((unsigned long)fd, v, (unsigned long)count);
+       set_fs (old_fs);
+       kfree (v);
+       return ret;
+}
+
+/* readdir & getdents */
+
+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
+#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
+
+struct old_linux_dirent32 {
+       u32             d_ino;
+       u32             d_offset;
+       unsigned short  d_namlen;
+       char            d_name[1];
+};
+
+struct readdir_callback32 {
+       struct old_linux_dirent32 * dirent;
+       int count;
+};
+
+static int fillonedir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+{
+       struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
+       struct old_linux_dirent32 * dirent;
+
+       if (buf->count)
+               return -EINVAL;
+       buf->count++;
+       dirent = buf->dirent;
+       put_user(ino, &dirent->d_ino);
+       put_user(offset, &dirent->d_offset);
+       put_user(namlen, &dirent->d_namlen);
+       copy_to_user(dirent->d_name, name, namlen);
+       put_user(0, dirent->d_name + namlen);
+       return 0;
+}
+
+asmlinkage int old32_readdir(unsigned int fd, u32 dirent, unsigned int count)
+{
+       int error = -EBADF;
+       struct file * file;
+       struct readdir_callback32 buf;
+
+       lock_kernel();
+       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+               goto out;
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out;
+       error = verify_area(VERIFY_WRITE, (void *)A(dirent), sizeof(struct old_linux_dirent32));
+       if (error)
+               goto out;
+       buf.count = 0;
+       buf.dirent = (struct old_linux_dirent32 *)A(dirent);
+       error = file->f_op->readdir(file->f_inode, file, &buf, fillonedir);
+       if (error < 0)
+               goto out;
+       error = buf.count;
+out:
+       unlock_kernel();
+       return error;
+}
+
+struct linux_dirent32 {
+       u32             d_ino;
+       u32             d_off;
+       unsigned short  d_reclen;
+       char            d_name[1];
+};
+
+struct getdents_callback32 {
+       struct linux_dirent32 * current_dir;
+       struct linux_dirent32 * previous;
+       int count;
+       int error;
+};
+
+static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
+{
+       struct linux_dirent32 * dirent;
+       struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
+       int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+
+       buf->error = -EINVAL;   /* only used if we fail.. */
+       if (reclen > buf->count)
+               return -EINVAL;
+       dirent = buf->previous;
+       if (dirent)
+               put_user(offset, &dirent->d_off);
+       dirent = buf->current_dir;
+       buf->previous = dirent;
+       put_user(ino, &dirent->d_ino);
+       put_user(reclen, &dirent->d_reclen);
+       copy_to_user(dirent->d_name, name, namlen);
+       put_user(0, dirent->d_name + namlen);
+       ((char *) dirent) += reclen;
+       buf->current_dir = dirent;
+       buf->count -= reclen;
+       return 0;
 }
 
 asmlinkage int sys32_getdents(unsigned int fd, u32 dirent, unsigned int count)
 {
-       return sys_getdents(fd, (void *)A(dirent), count);
+       struct file * file;
+       struct linux_dirent32 * lastdirent;
+       struct getdents_callback32 buf;
+       int error = -EBADF;
+
+       lock_kernel();
+       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+               goto out;
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out;
+       error = verify_area(VERIFY_WRITE, (void *)A(dirent), count);
+       if (error)
+               goto out;
+       buf.current_dir = (struct linux_dirent32 *) A(dirent);
+       buf.previous = NULL;
+       buf.count = count;
+       buf.error = 0;
+       error = file->f_op->readdir(file->f_inode, file, &buf, filldir);
+       if (error < 0)
+               goto out;
+       lastdirent = buf.previous;
+       if (!lastdirent) {
+               error = buf.error;
+       } else {
+               put_user(file->f_pos, &lastdirent->d_off);
+               error = count - buf.count;
+       }
+out:
+       unlock_kernel();
+       return error;
 }
 
+/* end of readdir & getdents */
+
 asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp)
 {
-       return sys_select(n, (fd_set *)A(inp), (fd_set *)A(outp), (fd_set *)A(exp), (struct timeval *)A(tvp));
+       unsigned long old_fs;
+       char *p;
+       u32 *q;
+       int i, ret = -EINVAL, nn;
+       u32 *Inp, *Outp, *Exp;
+       
+       if (n < 0 || n > PAGE_SIZE*2) return -EINVAL;
+       lock_kernel ();
+       p = (char *)__get_free_page (GFP_KERNEL);
+       if (!p) goto out;
+       q = (u32 *)p;
+       nn = (n + 8 * sizeof(unsigned long) - 1) / (8 * sizeof (unsigned long));
+       Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp);
+       ret = -EFAULT;
+       for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) {
+               if (__get_user (q[1], Inp) ||
+                   __get_user (q[0], Inp+1) ||
+                   __get_user (q[1+PAGE_SIZE/4], Outp) ||
+                   __get_user (q[PAGE_SIZE/4], Outp+1) ||
+                   __get_user (q[1+PAGE_SIZE/2], Exp) ||
+                   __get_user (q[PAGE_SIZE/2], Exp+1))
+                       goto out;
+       }
+       old_fs = get_fs ();
+       set_fs (KERNEL_DS);
+       ret = sys_select(n, (fd_set *)p, (fd_set *)(p + PAGE_SIZE/4), (fd_set *)(p + PAGE_SIZE/2), (struct timeval *)A(tvp));
+       set_fs (old_fs);
+       q = (u32 *)p;
+       Inp = (u32 *)A(inp); Outp = (u32 *)A(outp); Exp = (u32 *)A(exp);
+       for (i = 0; i < ret; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) {
+               if (__put_user (q[1], Inp) ||
+                   __put_user (q[0], Inp+1) ||
+                   __put_user (q[1+PAGE_SIZE/4], Outp) ||
+                   __put_user (q[PAGE_SIZE/4], Outp+1) ||
+                   __put_user (q[1+PAGE_SIZE/2], Exp) ||
+                   __put_user (q[PAGE_SIZE/2], Exp+1)) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+       }
+out:
+       free_page ((unsigned long)p);
+       return ret;
 }
 
 asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout)
@@ -430,19 +905,62 @@ asmlinkage int sys32_poll(u32 ufds, unsigned int nfds, int timeout)
        return sys_poll((struct pollfd *)A(ufds), nfds, timeout);
 }
 
+static inline int putstat(u32 statbuf, struct stat *s)
+{
+       if (put_user (s->st_dev, &(((struct stat32 *)A(statbuf))->st_dev)) ||
+           __put_user (s->st_ino, &(((struct stat32 *)A(statbuf))->st_ino)) ||
+           __put_user (s->st_mode, &(((struct stat32 *)A(statbuf))->st_mode)) ||
+           __put_user (s->st_nlink, &(((struct stat32 *)A(statbuf))->st_nlink)) ||
+           __put_user (s->st_uid, &(((struct stat32 *)A(statbuf))->st_uid)) ||
+           __put_user (s->st_gid, &(((struct stat32 *)A(statbuf))->st_gid)) ||
+           __put_user (s->st_rdev, &(((struct stat32 *)A(statbuf))->st_rdev)) ||
+           __put_user (s->st_size, &(((struct stat32 *)A(statbuf))->st_size)) ||
+           __put_user (s->st_atime, &(((struct stat32 *)A(statbuf))->st_atime)) ||
+           __put_user (s->st_mtime, &(((struct stat32 *)A(statbuf))->st_mtime)) ||
+           __put_user (s->st_ctime, &(((struct stat32 *)A(statbuf))->st_ctime)) ||
+           __put_user (s->st_blksize, &(((struct stat32 *)A(statbuf))->st_blksize)) ||
+           __put_user (s->st_blocks, &(((struct stat32 *)A(statbuf))->st_blocks)))
+               return -EFAULT;
+       return 0;
+}
+
 asmlinkage int sys32_newstat(u32 filename, u32 statbuf)
 {
-       return sys_newstat((char *)A(filename), (struct stat *)A(statbuf));
+       int ret;
+       struct stat s;
+       unsigned long old_fs = get_fs();
+       
+       set_fs (KERNEL_DS);
+       ret = sys_newstat((char *)A(filename), &s);
+       set_fs (old_fs);
+       if (putstat (statbuf, &s)) return -EFAULT;
+       return ret;
 }
 
 asmlinkage int sys32_newlstat(u32 filename, u32 statbuf)
 {
-       return sys_newlstat((char *)A(filename), (struct stat *)A(statbuf));
+       int ret;
+       struct stat s;
+       unsigned long old_fs = get_fs();
+       
+       set_fs (KERNEL_DS);
+       ret = sys_newlstat((char *)A(filename), &s);
+       set_fs (old_fs);
+       if (putstat (statbuf, &s)) return -EFAULT;
+       return ret;
 }
 
 asmlinkage int sys32_newfstat(unsigned int fd, u32 statbuf)
 {
-       return sys_newfstat(fd, (struct stat *)A(statbuf));
+       int ret;
+       struct stat s;
+       unsigned long old_fs = get_fs();
+       
+       set_fs (KERNEL_DS);
+       ret = sys_newfstat(fd, &s);
+       set_fs (old_fs);
+       if (putstat (statbuf, &s)) return -EFAULT;
+       return ret;
 }
 
 asmlinkage int sys32_readlink(u32 path, u32 buf, int bufsiz)
@@ -454,7 +972,7 @@ asmlinkage int sys32_sysfs(int option, ...)
 {
         va_list args;
        unsigned int x;
-       int ret;
+       int ret = -EINVAL;
 
         va_start(args, option);
         switch (option) {
@@ -473,6 +991,7 @@ asmlinkage int sys32_sysfs(int option, ...)
        return ret;
 }
 
+/* Continue here */
 asmlinkage int sys32_ustat(dev_t dev, u32 ubuf)
 {
        return sys_ustat(dev, (struct ustat *)A(ubuf));
index d7e80cc140e9d42a09de493606a70b9a564aeed6..3afd28cc90765f613b53833794a4e9cbc989543c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.5 1997/04/09 08:25:16 jj Exp $
+/* $Id: systbls.S,v 1.6 1997/04/16 10:27:15 jj Exp $
  * systbls.S: System call entry point tables for OS compatibility.
  *            The native Linux system call table lives here also.
  *
@@ -56,7 +56,7 @@ sys_call_table32:
        .xword sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_newuname
 /*190*/        .xword sys_nis_syscall, sys32_personality, sys_prof, sys_break, sys_lock
        .xword sys_mpx, sys_ulimit, sys_getppid, sparc32_sigaction, sys_sgetmask
-/*200*/        .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old_readdir
+/*200*/        .xword sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys32_uselib, old32_readdir
        .xword sys_nis_syscall, sys32_socketcall, sys32_syslog, sys32_olduname, sys_nis_syscall
 /*210*/        .xword sys_idle, sys_nis_syscall, sys32_waitpid, sys32_swapoff, sys32_sysinfo
        .xword sys32_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
index 4c7725f37d02226c36be19946233dc31bf81022c..72d2774b5f9e4a3481dac01c645a3c4d68368f6a 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.22 1997/04/12 04:28:48 davem Exp $
+/*  $Id: init.c,v 1.23 1997/04/16 10:27:18 jj Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -32,6 +32,9 @@ extern unsigned long empty_null_pte_table;
 
 unsigned long tlb_context_cache = CTX_FIRST_VERSION;
 
+/* References to section boundaries */
+extern char __init_begin, __init_end, etext, __p1275_loc, __bss_start;
+
 /*
  * BAD_PAGE is the page that is used for page faults when linux
  * is out-of-memory. Older versions of linux just did a
@@ -268,6 +271,7 @@ void mmu_get_scsi_sgl(struct mmu_sglist *sg, int sz, struct linux_sbus *sbus)
 
 char *mmu_info(void)
 {
+       /* XXX */
        return "MMU Type: Spitfire\n\tFIXME: Write this\n";
 }
 
@@ -436,15 +440,6 @@ void sparc_ultra_mapioaddr(unsigned long physaddr, unsigned long virt_addr,
        else
                pte = mk_pte_phys(physaddr, __pgprot(pg_iobits | __DIRTY_BITS));
 
-#if 0
-       prom_printf("IOMAP: vaddr[%016lx]paddr[%016lx]ptep[%016lx]pte[%016lx])\n",
-                   virt_addr, physaddr, (unsigned long) ptep, pte_val(pte));
-       prom_printf("IOMAP: pgd[%016lx,%016lx]\n",
-                   (unsigned long) pgdp, pgd_val(*pgdp));
-       prom_printf("IOMAP: pmd[%016lx,%016lx]\n",
-                   (unsigned long) pmdp, pmd_val(*pmdp));
-#endif
-
        set_pte(ptep, pte);
 }
 
@@ -462,6 +457,7 @@ void sparc_ultra_unmapioaddr(unsigned long virt_addr)
        pte_clear(ptep);
 }
 
+#ifdef DEBUG_MMU
 void sparc_ultra_dump_itlb(void)
 {
         int slot;
@@ -485,6 +481,7 @@ void sparc_ultra_dump_dtlb(void)
                        slot+1, spitfire_get_dtlb_tag(slot+1), spitfire_get_dtlb_data(slot+1));
         }
 }
+#endif
 
 /* paging_init() sets up the page tables */
 
@@ -493,7 +490,6 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
 __initfunc(unsigned long 
 paging_init(unsigned long start_mem, unsigned long end_mem))
 {
-       extern unsigned long __p1275_loc;
        extern unsigned long phys_base;
        extern void setup_tba(unsigned long kpgdir);
        extern void __bfill64(void *, unsigned long);
@@ -637,9 +633,10 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
 {
        int codepages = 0;
        int datapages = 0;
+       int initpages = 0;
+       int prompages = 0;
        unsigned long tmp2, addr;
        unsigned long data_end;
-       extern char etext;
 
        end_mem &= PAGE_MASK;
        max_mapnr = MAP_NR(end_mem);
@@ -665,6 +662,10 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
                if(PageReserved(mem_map + MAP_NR(addr))) {
                        if ((addr < (unsigned long) &etext) && (addr >= PAGE_OFFSET))
                                codepages++;
+                       else if((addr >= (unsigned long)&__init_begin && addr < (unsigned long)&__init_end))
+                               initpages++;
+                       else if((addr >= (unsigned long)&__p1275_loc && addr < (unsigned long)&__bss_start))
+                               prompages++;
                        else if((addr < data_end) && (addr >= PAGE_OFFSET))
                                datapages++;
                        continue;
@@ -680,26 +681,23 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
 
        tmp2 = nr_free_pages << PAGE_SHIFT;
 
-       printk("Memory: %luk available (%dk kernel code, %dk data) [%016lx,%016lx]\n",
+       printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %dk prom) [%016lx,%016lx]\n",
               tmp2 >> 10,
               codepages << (PAGE_SHIFT-10),
-              datapages << (PAGE_SHIFT-10), PAGE_OFFSET, end_mem);
+              datapages << (PAGE_SHIFT-10), 
+              initpages << (PAGE_SHIFT-10), 
+              prompages << (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;
-
-#if 0
-       printk("Done in mem_init() halting\n");
-       prom_cmdline();
-#endif
 }
 
 void free_initmem (void)
 {
-       extern char __init_begin, __init_end;
        unsigned long addr;
        
        addr = (unsigned long)(&__init_begin);
index ef047d0406da86d8f431de7190a609e46b9c6fb1..69299d7cde20d884ccf86c7835a8780491fbe177 100644 (file)
@@ -7,7 +7,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-SUB_DIRS     := block char net #streams
+SUB_DIRS     := block char net pnp #streams
 MOD_SUB_DIRS := $(SUB_DIRS) sbus
 ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus sound cdrom isdn pnp
 
@@ -15,11 +15,6 @@ ifdef CONFIG_PCI
 SUB_DIRS += pci
 endif
 
-ifdef CONFIG_PNP
-SUB_DIRS += pnp
-MOD_SUB_DIRS += pnp
-endif
-
 ifdef CONFIG_SBUS
 SUB_DIRS += sbus
 endif
index 78ca9a1dc3ca9627c6b43f923b61a7323adb2b58..740a3780a66bcb0ee412b6934718eb28ea67d7eb 100644 (file)
@@ -43,8 +43,6 @@
  *
  */
 
-#include <linux/module.h>
-
 #define MAJOR_NR ACSI_MAJOR
 
 #include <linux/config.h>
@@ -1127,9 +1125,8 @@ static int acsi_ioctl( struct inode *inode, struct file *file,
                 * ACSI disks...
                 */
          case BLKGETSIZE:   /* Return device size */
-               if (put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects,
-                            (long *)arg))
-                    return -EFAULT;                                     
+               return put_user(acsi_part[MINOR(inode->i_rdev)].nr_sects,
+                               (long *) arg);
          case BLKFLSBUF:
                if(!suser())  return -EACCES;
                if(!inode->i_rdev) return -EINVAL;
@@ -1629,33 +1626,23 @@ static int acsi_devinit(struct acsi_info_struct *aip)
        return DEV_SUPPORTED;
 }
 
-#ifdef CONFIG_ATARI_SLM_MODULE
-void acsi_attach_SLMs( int (*attach_func)( int, int ) );
-#endif
+EXPORT_SYMBOL(acsi_delay_start);
+EXPORT_SYMBOL(acsi_delay_end);
+EXPORT_SYMBOL(acsi_wait_for_IRQ);
+EXPORT_SYMBOL(acsi_wait_for_noIRQ);
+EXPORT_SYMBOL(acsicmd_nodma);
+EXPORT_SYMBOL(acsi_getstatus);
+EXPORT_SYMBOL(acsi_buffer);
+EXPORT_SYMBOL(phys_acsi_buffer);
 
-static struct symbol_table acsi_symbol_table =
-{
-#include <linux/symtab_begin.h>
-
-       X(acsi_delay_start),
-       X(acsi_delay_end),
-       X(acsi_wait_for_IRQ),
-       X(acsi_wait_for_noIRQ),
-       X(acsicmd_nodma),
-       X(acsi_getstatus),
-       X(acsi_buffer),
-       X(phys_acsi_buffer),
 #ifdef CONFIG_ATARI_SLM_MODULE
-       X(acsi_extstatus),
-       X(acsi_end_extstatus),
-       X(acsi_extcmd),
-       X(acsi_attach_SLMs),
-#endif
+void acsi_attach_SLMs( int (*attach_func)( int, int ) );
 
-#include <linux/symtab_end.h>
-};
+EXPORT_SYMBOL(acsi_extstatus);
+EXPORT_SYMBOL(acsi_end_extstatus);
+EXPORT_SYMBOL(acsi_extcmd);
+EXPORT_SYMBOL(acsi_attach_SLMs);
 
-#ifdef CONFIG_ATARI_SLM_MODULE
 /* to remember IDs of SLM devices, SLM module is loaded later
  * (index is target#, contents is lun#, -1 means "no SLM") */
 int SLM_devices[8];
@@ -1751,7 +1738,6 @@ static void acsi_geninit( struct gendisk *gd )
        for( i = 0; i < (MAX_DEV << 4); i++ )
                acsi_blocksizes[i] = 1024;
        blksize_size[MAJOR_NR] = acsi_blocksizes;
-       register_symtab (&acsi_symbol_table);
 }
 
 #ifdef CONFIG_ATARI_SLM_MODULE
index 38a78e313816b97a10a3c0301886e88bb9f37caf..12c0fcd529440d26fc3deb3d07eb72f6c4ae656b 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/fd.h>
+#include <linux/hdreg.h>
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/delay.h>
@@ -401,6 +402,7 @@ static int motor_on(int nr)
        restore_flags(flags);
 
        if (on_attempts == 0) {
+               on_attempts = -1;
 #if 0
                printk (KERN_ERR "motor_on failed, turning motor off\n");
                fd_motor_off (nr);
@@ -1511,93 +1513,103 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
        int error;
        unsigned long flags;
 
-       switch(cmd)
-        {
-         case FDFMTBEG:
-         get_hw(drive);
-           if (fd_ref[drive] > 1) {
-             rel_hw();
-             return -EBUSY;
-           }
-           fsync_dev(inode->i_rdev);
-           if (motor_on(drive) == 0) {
-             rel_hw();
-             return -ENODEV;
-           }
-           if (fd_calibrate(drive) == 0) {
-             rel_hw();
-             return -ENXIO;
-           }
-           floppy_off(drive);
-           rel_hw();
-           break;
-         case FDFMTTRK:
-           if (param < unit[drive].type->tracks * unit[drive].type->heads)
-            {
-             get_fdc(drive);
-             get_hw(drive);
-             fd_select(drive);
-             if (fd_seek(drive,param)!=0)
-              {
-               savedtrack=param;
-               memset(trackdata,FD_FILL_BYTE,unit[drive].sects*512);
-               non_int_flush_track(drive);
-              }
-             floppy_off(drive);
-             rel_hw();
-             rel_fdc();
-            }
-           else
-             return -EINVAL;
-           break;
-         case FDFMTEND:
-           floppy_off(drive);
-           invalidate_inodes(inode->i_rdev);
-           invalidate_buffers(inode->i_rdev);
-           break;
-         case FDGETPRM:
-           error = verify_area(VERIFY_WRITE, (void *)param,
-                               sizeof(struct floppy_struct));
-           if (error)
-             return error;
-           memset((void *)&getprm, 0, sizeof (getprm));
-           getprm.track=unit[drive].type->tracks;
-           getprm.head=unit[drive].type->heads;
-           getprm.sect=unit[drive].sects;
-           getprm.size=unit[drive].blocks;
-           copy_to_user((void *)param,(void *)&getprm,sizeof(struct floppy_struct));
+       switch(cmd){
+       case HDIO_GETGEO:
+       {
+               struct hd_geometry loc;
+               loc.heads = unit[drive].type->heads;
+               loc.sectors = unit[drive].sects;
+               loc.cylinders = unit[drive].type->tracks;
+               loc.start = 0;
+               if ((error = copy_to_user((void *)param, (void *)&loc,
+                                         sizeof(struct hd_geometry))))
+                       return error;
+               break;
+       }
+       case FDFMTBEG:
+               get_hw(drive);
+               if (fd_ref[drive] > 1) {
+                       rel_hw();
+                       return -EBUSY;
+               }
+               fsync_dev(inode->i_rdev);
+               if (motor_on(drive) == 0) {
+                       rel_hw();
+                       return -ENODEV;
+               }
+               if (fd_calibrate(drive) == 0) {
+                       rel_hw();
+                       return -ENXIO;
+               }
+               floppy_off(drive);
+               rel_hw();
+               break;
+       case FDFMTTRK:
+               if (param < unit[drive].type->tracks * unit[drive].type->heads)
+               {
+                       get_fdc(drive);
+                       get_hw(drive);
+                       fd_select(drive);
+                       if (fd_seek(drive,param)!=0){
+                               savedtrack=param;
+                               memset(trackdata, FD_FILL_BYTE,
+                                      unit[drive].sects*512);
+                               non_int_flush_track(drive);
+                       }
+                       floppy_off(drive);
+                       rel_hw();
+                       rel_fdc();
+               }
+               else
+                       return -EINVAL;
+               break;
+       case FDFMTEND:
+               floppy_off(drive);
+               invalidate_inodes(inode->i_rdev);
+               invalidate_buffers(inode->i_rdev);
+               break;
+       case FDGETPRM:
+               memset((void *)&getprm, 0, sizeof (getprm));
+               getprm.track=unit[drive].type->tracks;
+               getprm.head=unit[drive].type->heads;
+               getprm.sect=unit[drive].sects;
+               getprm.size=unit[drive].blocks;
+               if ((error = copy_to_user((void *)param,
+                                         (void *)&getprm,
+                                         sizeof(struct floppy_struct))))
+                       return error;
            break;
-         case BLKGETSIZE:
-           if (put_user(unit[drive].blocks,(long *)param))
-                   return -EFAULT;
-            break;
-          case FDSETPRM:
-          case FDDEFPRM:
-            return -EINVAL;
-          case FDFLUSH:
-           save_flags(flags);
-           cli();
-            if ((drive == selected) && (writepending)) {
-              del_timer (&flush_track_timer);
-              restore_flags(flags);
-              non_int_flush_track(selected);
-            }
-            else
-              restore_flags(flags);
-            break;
+       case BLKGETSIZE:
+               if (put_user(unit[drive].blocks,(long *)param))
+                       return -EFAULT;
+               break;
+       case FDSETPRM:
+       case FDDEFPRM:
+               return -EINVAL;
+       case FDFLUSH:
+               save_flags(flags);
+               cli();
+               if ((drive == selected) && (writepending)) {
+                       del_timer (&flush_track_timer);
+                       restore_flags(flags);
+                       non_int_flush_track(selected);
+               }
+               else
+                       restore_flags(flags);
+               break;
 #ifdef RAW_IOCTL
-         case IOCTL_RAW_TRACK:
-           error = verify_area(VERIFY_WRITE, (void *)param,
-             unit[drive].type->read_size);
-           if (error)
-             return error;
-           copy_to_user((void *)param, raw_buf, unit[drive].type->read_size);
-           return unit[drive].type->read_size;
+       case IOCTL_RAW_TRACK:
+               error = copy_to_user((void *)param, raw_buf,
+                                    unit[drive].type->read_size);
+               if (error)
+                       return error;
+               else
+                       return unit[drive].type->read_size;
 #endif
-         default:
-           printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive);
-           return -ENOSYS;
-         }
+       default:
+               printk(KERN_DEBUG "fd_ioctl: unknown cmd %d for drive %d.",cmd,drive);
+               return -ENOSYS;
+       }
        return 0;
 }
 
index b9a28b55ac0737265f7bdc461c513301f5d925a2..3cf489712061b0403b91e3b911dec1defe9eff27 100644 (file)
@@ -52,6 +52,9 @@
  * Michael (MSch) 11/07/96:
  *  - implemented FDSETPRM and FDDEFPRM ioctl
  *
+ * Andreas (97/03/19):
+ *  - implemented missing BLK* ioctls
+ *
  *  Things left to do:
  *   - Formatting
  *   - Maybe a better strategy for disk change detection (does anyone
@@ -281,6 +284,7 @@ unsigned char *DMABuffer;                     /* buffer for writes */
 static unsigned long PhysDMABuffer;   /* physical address */
 
 static int UseTrackbuffer = -1;                  /* Do track buffering? */
+MODULE_PARM(UseTrackbuffer, "i");
 
 unsigned char *TrackBuffer;                      /* buffer for reads */
 static unsigned long PhysTrackBuffer; /* physical address */
@@ -305,6 +309,7 @@ static int MotorOn = 0, MotorOffTrys;
 static int IsFormatting = 0, FormatError;
 
 static int UserSteprate[FD_MAX_UNITS] = { -1, -1 };
+MODULE_PARM(UserSteprate, "1-" __MODULE_STRING(FD_MAX_UNITS) "i");
 
 /* Synchronization of FDC access. */
 static volatile int fdc_busy = 0;
@@ -405,7 +410,7 @@ static void fd_probe( int drive );
 static int fd_test_drive_present( int drive );
 static void config_types( void );
 static int floppy_open( struct inode *inode, struct file *filp );
-static void floppy_release( struct inode * inode, struct file * filp );
+static int floppy_release( struct inode * inode, struct file * filp );
 
 /************************* End of Prototypes **************************/
 
@@ -1582,6 +1587,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
        drive &= 3;
        switch (cmd) {
        case FDGETPRM:
+       case BLKGETSIZE:
                if (type) {
                        if (--type >= NUM_DISK_MINORS)
                                return -ENODEV;
@@ -1599,6 +1605,9 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                        else
                                dtp = UDT;
                }
+               if (cmd == BLKGETSIZE)
+                       return put_user(dtp->blocks, (long *)param);
+
                memset((void *)&getprm, 0, sizeof(getprm));
                getprm.size = dtp->blocks;
                getprm.sect = dtp->spt;
@@ -1608,6 +1617,22 @@ static int fd_ioctl(struct inode *inode, struct file *filp,
                if (copy_to_user((void *)param, &getprm, sizeof(getprm)))
                        return -EFAULT;
                return 0;
+       case BLKRASET:
+               if (!suser())
+                       return -EACCES;
+               if (param > 0xff)
+                       return -EINVAL;
+               read_ahead[MAJOR(inode->i_rdev)] = param;
+               return 0;
+       case BLKRAGET:
+               return put_user(read_ahead[MAJOR(inode->i_rdev)],
+                               (int *) param);
+       case BLKFLSBUF:
+               if (!suser())
+                       return -EACCES;
+               fsync_dev(inode->i_rdev);
+               invalidate_buffers(inode->i_rdev);
+               return 0;
        }
        if (!IOCTL_ALLOWED)
                return -EPERM;
index d168cbe4b6baa4387b7c4c6e0384bfc250d6c59a..0fd999e186fa44eda807221ac8db9e40e9cd6bd0 100644 (file)
@@ -1676,10 +1676,13 @@ void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
        }
        if (handler) {
-               if (in_interrupt())
-                       schedule_bh( (void *)(void *) handler);
-               else
+               if(softirq_trylock()) {
+                       /* got the lock, call the handler immediately */
                        handler();
+                       softirq_endlock();
+               } else
+                       /* we interrupted a bottom half. Defer handler */
+                       schedule_bh( (void *)(void *) handler);
        } else
                FDCS->reset = 1;
        is_alive("normal interrupt end");
index 4c21bc9473924d6e933a10b9f433da19ece7eaeb..96d2aea70998a0c0902330804ab47d20878098b4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/blk.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 
@@ -739,7 +740,7 @@ void resetup_one_dev(struct gendisk *dev, int drive)
        }
 }
 
-static void setup_dev(struct gendisk *dev)
+static inline void setup_dev(struct gendisk *dev)
 {
        int i, drive;
        int end_minor   = dev->max_nr * dev->max_p;
@@ -762,7 +763,7 @@ static void setup_dev(struct gendisk *dev)
        }
 }
 
-void device_setup(void)
+__initfunc(void device_setup(void))
 {
        extern void console_map_init(void);
 #ifdef CONFIG_PNP_PARPORT
index faad205adddc988485e3c7bc673323914a3201f8..988450ce9a9177fc23ec5cea7c0d55f5483fff35 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/config.h>
 #include <linux/locks.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -631,7 +632,7 @@ extern void ez_init( void );
 extern void bpcd_init( void );
 #endif
 
-int blk_dev_init(void)
+__initfunc(int blk_dev_init(void))
 {
        struct request * req;
        struct blk_dev_struct *dev;
index ff1356a72b960087387da345c1bd55661f889f37..102b19963e86b2fb7f358d208283f58443a6231e 100644 (file)
@@ -200,7 +200,7 @@ static int initrd_release(struct inode *inode,struct file *file)
 {
        unsigned long i;
 
-       if (--initrd_users) return;
+       if (--initrd_users) return 0;
        for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
                free_page(i);
        initrd_start = 0;
@@ -405,11 +405,11 @@ identify_ramdisk_image(kdev_t device, struct file *fp, int start_block)
        }
 
        /* Try ext2 */
-       if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
+       if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
                printk(KERN_NOTICE
                       "RAMDISK: Ext2 filesystem found at block %d\n",
                       start_block);
-               nblocks = ext2sb->s_blocks_count;
+               nblocks = le32_to_cpu(ext2sb->s_blocks_count);
                goto done;
        }
 
index 9e1dca8db197a5a93b5de7d1f1dedf960eb7fe25..0f556752d768fb710c2360d2c5f0d9cdfdb4bb6a 100644 (file)
@@ -36,7 +36,7 @@
 #include <asm/setup.h>
 #include <asm/bitops.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 #define TRUE                  (1)
 #define FALSE                 (0)
index c601d6a700b0b8fd6f48ca3e684a6ceeab479f2b..cf50335d48ad72547e9f29003e5d013d269c83a9 100644 (file)
@@ -43,6 +43,16 @@ L_OBJS += keyboard.o defkeymap.o
 endif
 endif
 
+ifeq ($(CONFIG_ATARI_DSP56K),y)
+L_OBJS += dsp56k.o
+S = y
+else
+  ifeq ($(CONFIG_ATARI_DSP56K),m)
+  M_OBJS += dsp56k.o
+  SM = y
+  endif
+endif
+
 ifeq ($(CONFIG_DIGI),y)
 L_OBJS += pcxx.o
 else
index ea17b418ae255d85051ca71fb1e2178dcd1b585c..5f2d88a251547fa07a3313364c09e060d5171e38 100644 (file)
@@ -172,11 +172,11 @@ static int fasync_mouse(struct inode *inode, struct file *filp, int on)
  * close access to the mouse
  */
 
-static int close_mouse(struct inode * inode, struct file * file)
+static int release_mouse(struct inode * inode, struct file * file)
 {
        fasync_mouse(inode, file, 0);
        if (--mouse.active)
-         return;
+               return 0;
        free_irq(IRQ_AMIGA_VERTB, mouse_interrupt);
        MSE_INT_OFF();
        MOD_DEC_USE_COUNT;
@@ -299,7 +299,7 @@ struct file_operations amiga_mouse_fops = {
        NULL,           /* mouse_ioctl */
        NULL,           /* mouse_mmap */
        open_mouse,
-       close_mouse,
+       release_mouse,
        NULL,
        fasync_mouse,
 };
index 108175fe8fe0e1cb84335e2b8d7371edf890fab6..9c7405effe4ae1c124f79f4206abc04df1c17e0c 100644 (file)
@@ -27,7 +27,8 @@
 #include <asm/uaccess.h>
 
 static struct mouse_status mouse;
-static int atari_mouse_x_threshold = 2, atari_mouse_y_threshold = 2;
+static int mouse_threshold[2] = {2,2};
+MODULE_PARM(mouse_threshold, "2i");
 extern int atari_mouse_buttons;
 
 static void atari_mouse_interrupt(char *buf)
@@ -82,7 +83,7 @@ static int open_mouse(struct inode *inode, struct file *file)
     mouse.dx = mouse.dy = 0;
     atari_mouse_buttons = 0;
     ikbd_mouse_y0_top ();
-    ikbd_mouse_thresh (atari_mouse_x_threshold, atari_mouse_y_threshold);
+    ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]);
     ikbd_mouse_rel_pos();
     MOD_INC_USE_COUNT;
     atari_mouse_interrupt_hook = atari_mouse_interrupt;
@@ -99,12 +100,9 @@ static long read_mouse(struct inode *inode, struct file *file,
                       char *buffer, unsigned long count)
 {
     int dx, dy, buttons;
-    int r;
 
     if (count < 3)
        return -EINVAL;
-    if ((r = verify_area(VERIFY_WRITE, buffer, count)))
-       return r;
     if (!mouse.ready)
        return -EAGAIN;
     /* ikbd_mouse_disable */
@@ -124,12 +122,14 @@ static long read_mouse(struct inode *inode, struct file *file,
     if (mouse.dx == 0 && mouse.dy == 0)
       mouse.ready = 0;
     /* ikbd_mouse_rel_pos(); */
-    put_user(buttons | 0x80, buffer);
-    put_user((char) dx, buffer + 1);
-    put_user((char) dy, buffer + 2);
-    for (r = 3; r < count; r++)
-      put_user (0, buffer + r);
-    return r;
+    if (put_user(buttons | 0x80, buffer++) ||
+       put_user((char) dx, buffer++) ||
+       put_user((char) dy, buffer++))
+       return -EFAULT;
+    if (count > 3)
+       if (clear_user(buffer, count - 3))
+           return -EFAULT;
+    return count;
 }
 
 static unsigned int mouse_poll(struct file *file, poll_table *wait)
@@ -188,13 +188,13 @@ void atari_mouse_setup( char *str, int *ints )
     if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD)
        printk( "atari_mouse_setup: bad threshold value (ignored)\n" );
     else {
-       atari_mouse_x_threshold = ints[1];
-       atari_mouse_y_threshold = ints[1];
+       mouse_threshold[0] = ints[1];
+       mouse_threshold[1] = ints[1];
        if (ints[0] > 1) {
            if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD)
                printk("atari_mouse_setup: bad threshold value (ignored)\n" );
            else
-               atari_mouse_y_threshold = ints[2];
+               mouse_threshold[1] = ints[2];
        }
     }
        
index f1e4d72802458ef09509e1e4e3eb78df6b9de41b..dd8999244a47e014de14a00e62707a1fdf6715dd 100644 (file)
@@ -693,24 +693,27 @@ int lp_init(void)
        pb = parport_enumerate();
 
        while (pb) {
-               if (parport[0] == -1 || lp_searchfor(parport, count) ||
-                   (parport[0] == -3 &&
-                    pb->probe_info.class == PARPORT_CLASS_PRINTER)) {
-                       lp_table[count].dev =
-                           parport_register_device(pb, dev_name, NULL, 
-                                           lp_wakeup,
-                                           lp_interrupt, PARPORT_DEV_TRAN,
-                                           (void *) &lp_table[count]);
-                       lp_table[count].flags |= LP_EXIST;
-                       printk(KERN_INFO "lp%d: using %s at 0x%x, ", count,
-                              pb->name, pb->base);
-                       if (pb->irq == -1)
-                               printk("polling.\n");
-                       else
-                               printk("irq %d.\n", pb->irq);
+               /* We only understand PC-style ports. */
+               if (pb->modes & PARPORT_MODE_SPP) {
+                       if (parport[0] == -1 || lp_searchfor(parport, count) ||
+                           (parport[0] == -3 &&
+                            pb->probe_info.class == PARPORT_CLASS_PRINTER)) {
+                               lp_table[count].dev =
+                                 parport_register_device(pb, dev_name, NULL, 
+                                               lp_wakeup,
+                                               lp_interrupt, PARPORT_DEV_TRAN,
+                                               (void *) &lp_table[count]);
+                               lp_table[count].flags |= LP_EXIST;
+                               printk(KERN_INFO "lp%d: using %s at 0x%x, ", 
+                                      count, pb->name, pb->base);
+                               if (pb->irq == -1)
+                                       printk("polling.\n");
+                               else
+                                       printk("irq %d.\n", pb->irq);
+                       }
+                       if (++count == LP_NO)
+                               break;
                }
-               if (++count == LP_NO)
-                       break;
                pb = pb->next;
        }
 
index a79047749a63ebcd6ef316d0f3a7e895d3af01f7..3cc9458bddd64c04b029079d81a98afeb5755a4c 100644 (file)
@@ -34,8 +34,8 @@
  *
  */
 
-#include <linux/module.h>
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
@@ -139,40 +139,35 @@ static __inline__ int lp_char_interrupt(char lpchar, int dev)
 
 static int lp_error;
 
-void lp_interrupt(int irq, void *dummy, struct pt_regs *fp)
+void lp_interrupt(int dev)
 {
-    unsigned long flags;
-    int dev;
-
-    for (dev = 0; dev < MAX_LP; dev++) {
-       if ((lp_table[dev] != NULL) && (lp_table[dev]->lp_my_interrupt(dev) != 0))
-         if (lp_table[dev]->do_print)
-         {
-                 if (lp_table[dev]->copy_size)
-                 {
-                         save_flags(flags);
-                         cli();
-                         if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) {
-                                 --lp_table[dev]->copy_size;
-                                 ++lp_table[dev]->bytes_written;
-                                 restore_flags(flags);
-                         }
-                         else
-                         {
-                                 lp_table[dev]->do_print = 0;
-                                 restore_flags(flags);
-                                 lp_error = 1;
-                                 wake_up_interruptible(&lp_table[dev]->lp_wait_q);
-                         }
-                 }
-                 else
-                 {
-                         lp_table[dev]->do_print = 0;
-                         lp_error = 0;
-                         wake_up_interruptible(&lp_table[dev]->lp_wait_q);
-                 }
-
-         }
+    if (dev >= 0 && dev < MAX_LP && lp_table[dev]->do_print)
+    {
+       if (lp_table[dev]->copy_size)
+       {
+               unsigned long flags;
+               save_flags(flags);
+               cli();
+               if (lp_char_interrupt(lp_table[dev]->lp_buffer[lp_table[dev]->bytes_written], dev)) {
+                       --lp_table[dev]->copy_size;
+                       ++lp_table[dev]->bytes_written;
+                       restore_flags(flags);
+               }
+               else
+               {
+                       lp_table[dev]->do_print = 0;
+                       restore_flags(flags);
+                       lp_error = 1;
+                       wake_up_interruptible(&lp_table[dev]->lp_wait_q);
+               }
+       }
+       else
+       {
+               lp_table[dev]->do_print = 0;
+               lp_error = 0;
+               wake_up_interruptible(&lp_table[dev]->lp_wait_q);
+       }
+
     }
 }
 
@@ -366,6 +361,7 @@ static long long lp_lseek(struct inode * inode, struct file * file,
 static int lp_open(struct inode *inode, struct file *file)
 {
        int dev = MINOR(inode->i_rdev);
+       int ret;
 
        if (dev >= MAX_LP)
                return -ENODEV;
@@ -386,10 +382,14 @@ static int lp_open(struct inode *inode, struct file *file)
 
        lp_table[dev]->flags |= LP_BUSY;
 
-       MOD_INC_USE_COUNT;
-       lp_table[dev]->lp_open();
-
-       return 0;
+       ret = lp_table[dev]->lp_open(dev);
+       if (ret != 0) {
+               lp_table[dev]->flags &= ~LP_BUSY;
+       }
+       else {
+               MOD_INC_USE_COUNT;
+       }
+       return ret;
 }
 
 static int lp_release(struct inode *inode, struct file *file)
@@ -397,7 +397,7 @@ static int lp_release(struct inode *inode, struct file *file)
        int dev =MINOR(inode->i_rdev);
 
        lp_table[dev]->flags &= ~LP_BUSY;
-       lp_table[dev]->lp_release();
+       lp_table[dev]->lp_release(dev);
        MOD_DEC_USE_COUNT;
        return 0;
 }
@@ -458,18 +458,12 @@ static struct file_operations lp_fops = {
        lp_release
 };
 
-#ifdef CONFIG_MODULES
-static struct symbol_table parallel_syms = {
-#include <linux/symtab_begin.h>
-       X(lp_table),
-       X(lp_irq),
-       X(lp_interrupt),
-       X(lp_init),
-       X(register_parallel),
-       X(unregister_parallel),
-#include <linux/symtab_end.h>
-};
-#endif
+EXPORT_SYMBOL(lp_table);
+EXPORT_SYMBOL(lp_irq);
+EXPORT_SYMBOL(lp_interrupt);
+EXPORT_SYMBOL(lp_init);
+EXPORT_SYMBOL(register_parallel);
+EXPORT_SYMBOL(unregister_parallel);
 
 int lp_init(void)
 {
@@ -483,14 +477,6 @@ int lp_init(void)
                return -ENXIO;
        }
 
-#ifdef CONFIG_MODULES
-       if (register_symtab(&parallel_syms)) {
-               unregister_chrdev(LP_MAJOR, "lp");
-               printk(KERN_CRIT "unable to register parallel symtab\n");
-               return -ENXIO;
-       }
-#endif
-
 #if WHICH_DRIVER == FORCE_POLLING
        lp_irq = 0;
        printk(KERN_INFO "lp_init: lp using polling driver\n");
index 3b347efb776c501681f198681d45c471ba9ca05e..3d973d2a8af94cba7976a2038d7401e063c75620 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/random.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -491,7 +492,7 @@ static struct file_operations memory_fops = {
        NULL            /* fsync */
 };
 
-int chr_dev_init(void)
+__initfunc(int chr_dev_init(void))
 {
        if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
                printk("unable to get major %d for memory devs\n", MEM_MAJOR);
index 55bc89efe0e0bf445a55ba3da9bc0e15066b0f6c..ab81344eb91b1cab4ffb3a2abb0867846cf2a2f1 100644 (file)
@@ -311,7 +311,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
        int sz;
        int delta;
        char *first_free, *fj, *fnw;
-       int j, k, i = 0;
+       int i, j, k;
 
        /* we mostly copy too much here (512bytes), but who cares ;) */
        if (copy_from_user(&tmp, user_kdgkb, sizeof(struct kbsentry)))
@@ -319,6 +319,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry *user_kdgkb, int perm)
        tmp.kb_string[sizeof(tmp.kb_string)-1] = '\0';
        if (tmp.kb_func >= MAX_NR_FUNC)
                return -EINVAL;
+       i = tmp.kb_func;
 
        switch (cmd) {
        case KDGKBSENT:
index eeaecdd8ffdf4725653557acb99855e8de573641..3a181b9980353c4cb8cc40fead7d7b756cb054cc 100644 (file)
@@ -305,7 +305,7 @@ int init_sc(void)
                        /*
                         * No interrupt could be used
                         */
-                       pr_debug("Failed to aquire an IRQ line\n");
+                       pr_debug("Failed to acquire an IRQ line\n");
                        continue;
                }
 
index 812aec76a32aa3e83b065cd76c665b45708c11a5..acaa2c972e4e4bbe6da76e756b699323b7f2dfa9 100644 (file)
@@ -73,7 +73,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
       tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
     fi
-    
+
     tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT
     tristate 'CS89x0 support' CONFIG_CS89x0
     tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
index 6bbd69cb9f3a6f58e11c15bf9a5f6e11034c57a0..aacec03fb870ed7c7c34e0401bc6509dfb339439 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/config.h>
 #include <linux/netdevice.h>
 #include <linux/errno.h>
+#include <linux/init.h>
 
 #define        NEXT_DEV        NULL
 
@@ -93,7 +94,7 @@ extern int atp_init(struct device *);
 extern int de600_probe(struct device *);
 extern int de620_probe(struct device *);
 
-static int ethif_probe(struct device *dev)
+__initfunc(static int ethif_probe(struct device *dev))
 {
     u_long base_addr = dev->base_addr;
 
index 8112587ef536fb61dd094ba498a1b530bbda403b..414afff85b1b1e16c082983b962509e1c2266647 100644 (file)
@@ -55,7 +55,7 @@
 
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -302,14 +302,16 @@ static int lance_rx (struct device *dev)
                        lp->stats.rx_errors++;
                        continue;
                } else if (bits & LE_R1_ERR) {
-                       /* Count only the end frame as a tx error, not the beginning */
+                       /* Count only the end frame as a rx error,
+                        * not the beginning
+                        */
                        if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++;
                        if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++;
                        if (bits & LE_R1_OFL) lp->stats.rx_over_errors++;
                        if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++;
                        if (bits & LE_R1_EOP) lp->stats.rx_errors++;
                } else {
-                       len = rd->mblength;
+                       len = (rd->mblength & 0xfff) - 4;
                        skb = dev_alloc_skb (len+2);
 
                        if (skb == 0) {
@@ -582,6 +584,16 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev)
                return status;
        }
 
+       if (skb == NULL) {
+               dev_tint (dev);
+               printk ("skb is NULL\n");
+               return 0;
+       }
+
+       if (skb->len <= 0) {
+               printk ("skb len is %d\n", skb->len);
+               return 0;
+       }
        /* Block a timer-based transmit from overlapping. */
 #ifdef OLD_METHOD
        dev->tbusy = 1;
@@ -698,18 +710,13 @@ static void lance_set_multicast (struct device *dev)
        struct lance_private *lp = (struct lance_private *) dev->priv;
        volatile struct lance_init_block *ib = lp->init_block;
        volatile struct lance_regs *ll = lp->ll;
-       char shown;
 
-       shown = 0;
        while (dev->tbusy)
-               if (!shown++)
-                       printk ("Waiting for tbusy to go down\n");
+               schedule();
        set_bit (0, (void *) &dev->tbusy);
 
-       shown = 0;
        while (lp->tx_old != lp->tx_new)
-               if (!shown)
-                       printk ("Waiting for buffer to empty\n");
+               schedule();
 
        ll->rap = LE_CSR0;
        ll->rdp = LE_C0_STOP;
index 629bd2d535516f6bc12d4bd496b74cb76945a34f..5dbd2985a76a6cc7da5889e6aaeee9a4c006c463 100644 (file)
@@ -53,7 +53,7 @@
 #include <asm/bitops.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 
@@ -365,7 +365,7 @@ static int ariadne_close(struct device *dev)
     if (ariadne_debug > 1) {
        printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name,
               board->Lance.RDP);
-       printk("%s: %d packets missed\n", dev->name,
+       printk("%s: %lu packets missed\n", dev->name,
               priv->stats.rx_missed_errors);
     }
 
index 5e8ec01eca569426f93de3c6bc812360afe2c837..f0b781bcf4875b463bbea150112f49147b76c7e1 100644 (file)
 static char *version =
        "bionet.c:v1.0 06-feb-96 (c) Hartmut Laue.\n";
 
-#ifdef MODULE
 #include <linux/module.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -596,22 +591,13 @@ static struct net_device_stats *net_get_stats(struct device *dev)
 
 #ifdef MODULE
 
-#include <linux/version.h>
-
-/* We should include the kernel identification string in the module.
- */
-static char kernel_version[] = UTS_RELEASE;
-
-#undef NEXT_DEV
-#define NEXT_DEV       (&bio_dev)
-
 static char bio_name[16];
 static struct device bio_dev =
        {
                bio_name,       /* filled in by register_netdev() */
                0, 0, 0, 0,     /* memory */
                0, 0,           /* base, irq */
-               0, 0, 0, NEXT_DEV, bionet_probe,
+               0, 0, 0, NULL, bionet_probe,
        };
 
 int
index f1b2ea24b6a789404a6c61d8d1dc5cfd297735a6..72056f1b3197232f4bb7e91cafbac1cf019c39f2 100644 (file)
 static char *version =
        "pamsnet.c:v0.2beta 30-mar-96 (c) Torsten Lang.\n";
 
-#ifdef MODULE
 #include <linux/module.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -868,21 +863,12 @@ static struct net_device_stats *net_get_stats(struct device *dev)
 
 #ifdef MODULE
 
-#include <linux/version.h>
-
-/* We should include the kernel identification string in the module.
- */
-static char kernel_version[] = UTS_RELEASE;
-
-#undef NEXT_DEV
-#define NEXT_DEV       (&pam_dev)
-
 static struct device pam_dev =
        {
                "        ",     /* filled in by register_netdev() */
                0, 0, 0, 0,     /* memory */
                0, 0,           /* base, irq */
-               0, 0, 0, NEXT_DEV, pamsnet_probe,
+               0, 0, 0, NULL, pamsnet_probe,
        };
 
 int
index 0a400a417d4880a501a332a982ff58ce02d00def..f5b75bb9f8c894ee1bd98727eea845f58956c08f 100644 (file)
@@ -4,6 +4,8 @@
  *  based on original code by Donald Becker, with changes by
  *  Alan Cox and Pauline Middelink.
  *
+ * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
+ *
  * Many modifications, and currently maintained, by
  *  Philip Blundell <Philip.Blundell@pobox.com>
  */
  * things seem to be getting better slowly.
  */
 
-/* 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.
- */
-
 /* If your card is confused about what sort of interface it has (eg it
  * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART'
  * or 'SOFTSET /LISA' from DOS seems to help.
 
 /* Known bugs:
  *
- * - 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.
- * - The statistics may not be getting reported properly.
  */
 
+/*
+ *
+ * Note by Zoltan Szilagyi 10-12-96:
+ *
+ * I've succeeded in eliminating the "CU wedged" messages, and hence the
+ * lockups, which were only occuring with cards running in 8-bit mode ("force
+ * 8-bit operation" in Intel's SoftSet utility). This version of the driver
+ * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the
+ * CU before submitting a packet for transmission, and then restarts it as soon
+ * as the process of handing the packet is complete. This is definitely an
+ * unnecessary slowdown if the card is running in 16-bit mode; therefore one
+ * should detect 16-bit vs 8-bit mode from the EEPROM settings and act 
+ * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for
+ * ftp's, which is significantly better than I get in DOS, so the overhead of
+ * stopping and restarting the CU with each transmit is not prohibitive in
+ * practice.
+ */
+  
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 struct net_local
 {
        struct net_device_stats stats;
+       unsigned long last_tx;       /* jiffies when last transmit started */
        unsigned long init_time;     /* jiffies when eexp_hw_init586 called */
        unsigned short rx_first;     /* first rx buf, same as RX_BUF_START */
        unsigned short rx_last;      /* last rx buf */
+       unsigned short rx_ptr;       /* first rx buf to look at */
        unsigned short tx_head;      /* next free tx buf */
        unsigned short tx_reap;      /* first in-use tx buf */
        unsigned short tx_tail;      /* previous tx buf to tx_head */
@@ -114,11 +127,13 @@ struct net_local
        unsigned short last_tx_restart;   /* set to tx_link when we
                                             restart the CU */
        unsigned char started;
-       unsigned char promisc;
        unsigned short rx_buf_start;
        unsigned short rx_buf_end;
        unsigned short num_tx_bufs;
        unsigned short num_rx_bufs;
+       unsigned char width;         /* 0 for 16bit, 1 for 8bit */
+       unsigned char was_promisc;
+       unsigned char old_mc_count;
 };
 
 /* This is the code and data that is downloaded to the EtherExpress card's
@@ -126,11 +141,6 @@ struct net_local
  */
 
 static unsigned short start_code[] = {
-/* 0xfff6 */
-       0x0000,                 /* set bus to 16 bits */
-       0x0000,0x0000,
-       0x0000,0x0000,          /* address of ISCP (lo,hi) */
-
 /* 0x0000 */
        0x0001,                 /* ISCP: busy - cleared after reset */
        0x0008,0x0000,0x0000,   /* offset,address (lo,hi) of SCB */
@@ -144,9 +154,9 @@ static unsigned short start_code[] = {
        0x0000,0x0000,          /* pad */
        0x0000,0x0000,
 
-/* 0x0020 -- start of 82586 CU program */
-#define CONF_LINK 0x0020
-       0x0000,Cmd_Config,
+/* 0x20 -- start of 82586 CU program */
+#define CONF_LINK 0x20
+       0x0000,Cmd_Config,      
        0x0032,                 /* link to next command */
        0x080c,                 /* 12 bytes follow : fifo threshold=8 */
        0x2e40,                 /* don't rx bad frames
@@ -156,27 +166,43 @@ 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
+#define CONF_PROMISC  0x2e
+       0x0000,                 /* no HDLC : normal CRC : enable broadcast 
                                 * disable promiscuous/multicast modes */
        0x003c,                 /* minimum frame length = 60 octets) */
 
-       0x0000,Cmd_INT|Cmd_SetAddr,
+       0x0000,Cmd_SetAddr,
        0x003e,                 /* link to next command */
+#define CONF_HWADDR  0x38
        0x0000,0x0000,0x0000,   /* hardware address placed here */
 
-       0x0000,Cmd_TDR,0x0048,
-/* 0x0044 -- TDR result placed here */
-       0x0000, 0x0000,
-
-/* Eventually, a set-multicast will go in here */
+       0x0000,Cmd_MCast,
+       0x0076,                 /* link to next command */
+#define CONF_NR_MULTICAST 0x44
+       0x0000,                 /* number of multicast addresses */
+#define CONF_MULTICAST 0x46
+       0x0000, 0x0000, 0x0000, /* some addresses */
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+       0x0000, 0x0000, 0x0000,
+
+#define CONF_DIAG_RESULT  0x76
+       0x0000, Cmd_Diag,
+       0x007c,                 /* link to next command */
+
+       0x0000,Cmd_TDR|Cmd_INT,
+       0x0084,
+#define CONF_TDR_RESULT  0x82
+       0x0000,
 
        0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
-       0x0048,
-
-       0x0000
-
+       0x0084                  /* dummy link */
 };
 
 /* maps irq number to EtherExpress magic value */
@@ -213,6 +239,13 @@ static void eexp_hw_txinit    (struct device *dev);
 static void eexp_hw_rxinit    (struct device *dev);
 
 static void eexp_hw_init586   (struct device *dev);
+static void eexp_setup_filter (struct device *dev);
+
+static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
+enum eexp_iftype {AUI=0, BNC=1, TPE=2};
+
+#define STARTED_RU      2
+#define STARTED_CU      1
 
 /*
  * Primitive hardware access functions.
@@ -270,7 +303,8 @@ static inline short int SHADOW(short int addr)
 
 int express_probe(struct device *dev)
 {
-       unsigned short *port,ports[] = { 0x0300,0x0270,0x0320,0x0340,0 };
+       unsigned short *port;
+       static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 };
        unsigned short ioaddr = dev->base_addr;
 
        if (ioaddr&0xfe00)
@@ -302,6 +336,7 @@ static int eexp_open(struct device *dev)
 {
        int irq = dev->irq;
        unsigned short ioaddr = dev->base_addr;
+       struct net_local *lp = (struct net_local *)dev->priv;
 
 #if NET_DEBUG > 6
        printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
@@ -316,8 +351,16 @@ static int eexp_open(struct device *dev)
                return -EAGAIN;
 
        request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
+       request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
+       request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
+       request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
        dev->tbusy = 0;
        dev->interrupt = 0;
+       
+       if (lp->width) {
+               printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
+               outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
+       }
 
        eexp_hw_init586(dev);
        dev->start = 1;
@@ -331,6 +374,7 @@ static int eexp_open(struct device *dev)
 /*
  * close and disable the interface, leaving the 586 in reset.
  */
+
 static int eexp_close(struct device *dev)
 {
        unsigned short ioaddr = dev->base_addr;
@@ -464,9 +508,23 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
        /* 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)
-               unstick_cu(dev);
-
+       if (dev->tbusy) {
+               int status = scb_status(dev);
+               unstick_cu(dev);
+               if ((jiffies - lp->last_tx) < HZ)
+                       return 1;
+               printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
+                      (SCB_complete(status)?"lost interrupt":
+                       "board on fire"));
+               lp->stats.tx_errors++;
+               dev->tbusy = 0;
+               lp->last_tx = jiffies;
+               if (!SCB_complete(status)) {
+                       scb_command(dev, SCB_CUabort);
+                       outb(0,dev->base_addr+SIGNAL_CA);
+               }
+       }
+  
        if (set_bit(0,(void *)&dev->tbusy))
        {
                lp->stats.tx_dropped++;
@@ -477,6 +535,8 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
                        ETH_ZLEN;
                unsigned short *data = (unsigned short *)buf->data;
 
+               lp->stats.tx_bytes += length;
+
                eexp_hw_tx_pio(dev,data,length);
        }
        dev_kfree_skb(buf, FREE_WRITE);
@@ -491,11 +551,86 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev)
  * check to make sure we've not become wedged.
  */
 
+/*
+ * Handle an EtherExpress interrupt
+ * If we've finished initializing, start the RU and CU up.
+ * If we've already started, reap tx buffers, handle any received packets,
+ * check to make sure we've not become wedged.
+ */
+
+static unsigned short eexp_start_irq(struct device *dev,
+                                    unsigned short status)
+{
+       unsigned short ack_cmd = SCB_ack(status);
+       struct net_local *lp = (struct net_local *)dev->priv;
+       unsigned short ioaddr = dev->base_addr;
+       if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
+               short diag_status, tdr_status;
+               while (SCB_CUstat(status)==2)
+                       status = scb_status(dev);
+#if NET_DEBUG > 4
+               printk("%s: CU went non-active (status %04x)\n",
+                      dev->name, status);
+#endif
+
+               outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
+               diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
+               if (diag_status & 1<<11) {
+                       printk(KERN_WARNING "%s: 82586 failed self-test\n", 
+                              dev->name);
+               } else if (!(diag_status & 1<<13)) {
+                       printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
+               }
+
+               outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
+               tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
+               if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
+                       printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
+               } 
+               else if (tdr_status & TDR_XCVRPROBLEM) {
+                       printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
+               }
+               else if (tdr_status & TDR_LINKOK) {
+#if NET_DEBUG > 4
+                       printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
+#endif
+               } else {
+                       printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
+                              tdr_status);
+               }
+                       
+               lp->started |= STARTED_CU;
+               scb_wrcbl(dev, lp->tx_link);
+               /* if the RU isn't running, start it now */
+               if (!(lp->started & STARTED_RU)) {
+                       ack_cmd |= SCB_RUstart;
+                       scb_wrrfa(dev, lp->rx_buf_start);
+                       lp->rx_ptr = lp->rx_buf_start;
+               }
+               ack_cmd |= SCB_CUstart | 0x2000;
+       }
+
+       if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4) 
+               lp->started|=STARTED_RU;
+
+       return ack_cmd;
+}
+
+static void eexp_cmd_clear(struct device *dev)
+{
+       unsigned long int oldtime = jiffies;
+       while (scb_rdcmd(dev) && ((jiffies-oldtime)<10));
+       if (scb_rdcmd(dev)) {
+               printk("%s: command didn't clear\n", dev->name);
+       }
+}
+       
 static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
 {
        struct device *dev = irq2dev_map[irq];
        struct net_local *lp;
        unsigned short ioaddr,status,ack_cmd;
+       unsigned short old_read_ptr, old_write_ptr;
 
        if (dev==NULL)
        {
@@ -507,6 +642,9 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
        lp = (struct net_local *)dev->priv;
        ioaddr = dev->base_addr;
 
+       old_read_ptr = inw(ioaddr+READ_PTR);
+       old_write_ptr = inw(ioaddr+WRITE_PTR);
+
        outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
 
        dev->interrupt = 1;
@@ -517,75 +655,73 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
        printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
 #endif
 
-       ack_cmd = SCB_ack(status);
+       if (lp->started == (STARTED_CU | STARTED_RU)) {
 
-       if (lp->started==0 && SCB_complete(status))
-       {
-               while (SCB_CUstat(status)==2)
-                               status = scb_status(dev);
-#if NET_DEBUG > 4
-               printk(KERN_DEBUG "%s: CU went non-active (status = %08x)\n",
-                      dev->name, status);
-#endif
+               do {
+                       eexp_cmd_clear(dev);
 
-               /* now get the TDR status */
-               {
-                       short tdr_status;
-                       outw(0x40, dev->base_addr + SM_PTR);
-                       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" : "");
-                       }
-                       else if (tdr_status & TDR_XCVRPROBLEM) {
-                                       printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
-                       }
-#if NET_DEBUG > 4
-                       else if (tdr_status & TDR_LINKOK) {
-                                       printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
-                       }
-#endif
-               }
+                       ack_cmd = SCB_ack(status);
+                       scb_command(dev, ack_cmd);
+                       outb(0,ioaddr+SIGNAL_CA);
 
-               lp->started=1;
-               scb_wrcbl(dev, lp->tx_link);
-               scb_wrrfa(dev, lp->rx_buf_start);
-               ack_cmd |= SCB_CUstart | SCB_RUstart | 0x2000;
-       }
-       else if (lp->started)
-       {
-               unsigned short txstatus;
-               txstatus = eexp_hw_lasttxstat(dev);
-       }
+                       eexp_cmd_clear(dev);
 
-       if (SCB_rxdframe(status))
-       {
-               eexp_hw_rx_pio(dev);
-       }
+                       if (SCB_complete(status)) {
+                               if (!eexp_hw_lasttxstat(dev)) {
+                                       printk("%s: tx interrupt but no status\n", dev->name);
+                               }
+                       }
+                       
+                       if (SCB_rxdframe(status)) 
+                               eexp_hw_rx_pio(dev);
 
-       if ((lp->started&2)!=0 && SCB_RUstat(status)!=4)
-       {
-               printk(KERN_WARNING "%s: RU stopped: status %04x\n",
-                       dev->name,status);
-               lp->stats.rx_errors++;
-               eexp_hw_rxinit(dev);
-               scb_wrrfa(dev, lp->rx_buf_start);
-               ack_cmd |= SCB_RUstart;
+                       status = scb_status(dev);
+               } while (status & 0xc000);
+
+               if (SCB_RUdead(status)) 
+               {
+                       printk(KERN_WARNING "%s: RU stopped: status %04x\n",
+                              dev->name,status);
+#if 0
+                       printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
+                       outw(lp->cur_rfd, ioaddr+READ_PTR);
+                       printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
+                       outw(lp->cur_rfd+6, ioaddr+READ_PTR);
+                       printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
+                       outw(rbd, ioaddr+READ_PTR);
+                       printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
+                       outw(rbd+8, ioaddr+READ_PTR);
+                       printk("[%04x]\n", inw(ioaddr+DATAPORT));
+#endif
+                       lp->stats.rx_errors++;
+#if 1
+                       eexp_hw_rxinit(dev);
+#else
+                       lp->cur_rfd = lp->first_rfd;
+#endif
+                       scb_wrrfa(dev, lp->rx_buf_start);
+                       scb_command(dev, SCB_RUstart);
+                       outb(0,ioaddr+SIGNAL_CA);
+               } 
+       } else {
+               if (status & 0x8000) 
+                       ack_cmd = eexp_start_irq(dev, status);
+               else
+                       ack_cmd = SCB_ack(status);
+               scb_command(dev, ack_cmd);
+               outb(0,ioaddr+SIGNAL_CA);
        }
-       else if (lp->started==1 && SCB_RUstat(status)==4)
-               lp->started|=2;
 
-       scb_command(dev, ack_cmd);
-       outb(0,ioaddr+SIGNAL_CA);
+       eexp_cmd_clear(dev);
 
-       outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
+       outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); 
 
        dev->interrupt = 0;
-#if NET_DEBUG > 6
-        printk(KERN_DEBUG "%s: leaving eexp_irq()\n", dev->name);
+#if NET_DEBUG > 6 
+       printk("%s: leaving eexp_irq()\n", dev->name);
 #endif
+       outw(old_read_ptr, ioaddr+READ_PTR);
+       outw(old_write_ptr, ioaddr+WRITE_PTR);
        return;
 }
 
@@ -593,6 +729,25 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
  * Hardware access functions
  */
 
+/*
+ * Set the cable type to use.
+ */
+
+static void eexp_hw_set_interface(struct device *dev)
+{
+       unsigned char oldval = inb(dev->base_addr + 0x300e);
+       oldval &= ~0x82;
+       switch (dev->if_port) {
+       case TPE:
+               oldval |= 0x2;
+       case BNC:
+               oldval |= 0x80;
+               break;
+       }
+       outb(oldval, dev->base_addr+0x300e);
+       udelay(20000);
+}
+
 /*
  * Check all the receive buffers, and hand any received packets
  * to the upper levels. Basic sanity check on each frame
@@ -602,41 +757,49 @@ static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
 static void eexp_hw_rx_pio(struct device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
-       unsigned short rx_block = lp->rx_first;
+       unsigned short rx_block = lp->rx_ptr;
        unsigned short boguscount = lp->num_rx_bufs;
        unsigned short ioaddr = dev->base_addr;
+       unsigned short status;
 
 #if NET_DEBUG > 6
        printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
 #endif
 
-       while (boguscount--)
-       {
-               unsigned short status, rfd_cmd, rx_next, pbuf, pkt_len;
-
+       do {
+               unsigned short rfd_cmd, rx_next, pbuf, pkt_len;
+  
                outw(rx_block, ioaddr + READ_PTR);
                status = inw(ioaddr + DATAPORT);
-               rfd_cmd = inw(ioaddr + DATAPORT);
-               rx_next = inw(ioaddr + DATAPORT);
-               pbuf = inw(ioaddr + DATAPORT);
 
                if (FD_Done(status))
                {
+                       rfd_cmd = inw(ioaddr + DATAPORT);
+                       rx_next = inw(ioaddr + DATAPORT);
+                       pbuf = inw(ioaddr + DATAPORT);
                        outw(pbuf, ioaddr + READ_PTR);
                        pkt_len = inw(ioaddr + DATAPORT);
 
-                       if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16
-                               || (pkt_len & 0xc000)!=0xc000)
+                       if (rfd_cmd!=0x0000)
+                       {
+                               printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
+                                      dev->name, rfd_cmd);
+                               continue;
+                       }
+                       else if (pbuf!=rx_block+0x16)
                        {
-                               /* This should never happen.  If it does,
-                                * we almost certainly have a driver bug.
-                                */
-                               printk(KERN_WARNING "%s: Rx frame at %04x corrupted, status %04x, cmd %04x, "
-                                       "next %04x, pbuf %04x, len %04x\n",dev->name,rx_block,
-                                       status,rfd_cmd,rx_next,pbuf,pkt_len);
+                               printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n", 
+                                      dev->name, rx_block+0x16, pbuf);
                                continue;
                        }
-                       else if (!FD_OK(status))
+                       else if ((pkt_len & 0xc000)!=0xc000) 
+                       {
+                               printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
+                                      dev->name, pkt_len & 0xc000);
+                               continue;
+                       }
+                       else if (!FD_OK(status)) 
                        {
                                lp->stats.rx_errors++;
                                if (FD_CRC(status))
@@ -668,13 +831,15 @@ static void eexp_hw_rx_pio(struct device *dev)
                                skb->protocol = eth_type_trans(skb,dev);
                                netif_rx(skb);
                                lp->stats.rx_packets++;
+                               lp->stats.rx_bytes += pkt_len;
                        }
                        outw(rx_block, ioaddr+WRITE_PTR);
                        outw(0, ioaddr+DATAPORT);
                        outw(0, ioaddr+DATAPORT);
+                       rx_block = rx_next;
                }
-               rx_block = rx_next;
-       }
+       } while (FD_Done(status) && boguscount--);
+       lp->rx_ptr = rx_block;
 }
 
 /*
@@ -690,7 +855,17 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
        struct net_local *lp = (struct net_local *)dev->priv;
        unsigned short ioaddr = dev->base_addr;
 
-       outw(lp->tx_head, ioaddr + WRITE_PTR);
+       if (lp->width) {
+               /* Stop the CU so that there is no chance that it
+                  jumps off to a bogus address while we are writing the
+                  pointer to the next transmit packet in 8-bit mode -- 
+                  this eliminates the "CU wedged" errors in 8-bit mode.
+                  (Zoltan Szilagyi 10-12-96) */ 
+               scb_command(dev, SCB_CUsuspend);
+               outw(0xFFFF, ioaddr+SIGNAL_CA);
+       }
+
+       outw(lp->tx_head, ioaddr + WRITE_PTR);
 
        outw(0x0000, ioaddr + DATAPORT);
         outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
@@ -719,6 +894,16 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
                lp->tx_head += TX_BUF_SIZE;
        if (lp->tx_head != lp->tx_reap)
                dev->tbusy = 0;
+
+       if (lp->width) {
+               /* Restart the CU so that the packet can actually
+                  be transmitted. (Zoltan Szilagyi 10-12-96) */
+               scb_command(dev, SCB_CUresume);
+               outw(0xFFFF, ioaddr+SIGNAL_CA);
+       }
+
+       lp->stats.tx_packets++;
+       lp->last_tx = jiffies;
 }
 
 /*
@@ -731,14 +916,13 @@ static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
 static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
 {
        unsigned short hw_addr[3];
+       unsigned char buswidth;
        unsigned int memory_size;
-       static char *ifmap[]={"AUI", "BNC", "RJ45"};
-       enum iftype {AUI=0, BNC=1, TP=2};
        int i;
        unsigned short xsum = 0;
        struct net_local *lp;
 
-       printk("%s: EtherExpress 16 at %#x",dev->name,ioaddr);
+       printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
 
        outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
        outb(0, ioaddr+EEPROM_Ctrl);
@@ -769,7 +953,7 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
                dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
 
        {
-               char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
+               static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
                unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
 
                /* Use the IRQ from EEPROM if none was given */
@@ -777,7 +961,9 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
                        dev->irq = irqmap[setupval>>13];
 
                dev->if_port = !(setupval & 0x1000) ? AUI :
-                       eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TP : BNC;
+                       eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
+
+               buswidth = !((setupval & 0x400) >> 10);
        }
 
        dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
@@ -786,8 +972,11 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
 
        memset(dev->priv, 0, sizeof(struct net_local));
 
-       printk("; using IRQ %d, %s connector", dev->irq,ifmap[dev->if_port]);
-
+       printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, 
+              eexp_ifmap[dev->if_port], buswidth?8:16);
+       eexp_hw_set_interface(dev);
+  
        /* Find out how much RAM we have on the card */
        outw(0, dev->base_addr + WRITE_PTR);
        for (i = 0; i < 32768; i++)
@@ -795,10 +984,10 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
 
         for (memory_size = 0; memory_size < 64; memory_size++)
        {
-               outw(memory_size<<10, dev->base_addr + WRITE_PTR);
                outw(memory_size<<10, dev->base_addr + READ_PTR);
                if (inw(dev->base_addr+DATAPORT))
                        break;
+               outw(memory_size<<10, dev->base_addr + WRITE_PTR);
                outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
                outw(memory_size<<10, dev->base_addr + READ_PTR);
                if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
@@ -820,16 +1009,17 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
        case 32:
                lp->rx_buf_end += 0x4000;
        case 16:
-               printk(", %dk RAM.\n", memory_size);
+               printk(", %dk RAM)\n", memory_size);
                break;
        default:
-               printk("; bad memory size (%dk).\n", memory_size);
+               printk(") bad memory size (%dk).\n", memory_size);
                kfree(dev->priv);
                return ENODEV;
                break;
        }
 
        lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
+       lp->width = buswidth;
 
        dev->open = eexp_open;
        dev->stop = eexp_close;
@@ -905,8 +1095,8 @@ static unsigned short eexp_hw_lasttxstat(struct device *dev)
 
        do
        {
-               outw(tx_block, dev->base_addr + SM_PTR);
-               status = inw(SHADOW(tx_block));
+               outw(tx_block & ~31, dev->base_addr + SM_PTR);
+               status = inw(dev->base_addr + SHADOW(tx_block));
                if (!Stat_Done(status))
                {
                        lp->tx_link = tx_block;
@@ -918,12 +1108,29 @@ static unsigned short eexp_hw_lasttxstat(struct device *dev)
                        lp->stats.collisions += Stat_NoColl(status);
                        if (!Stat_OK(status))
                        {
-                               if (Stat_Abort(status))
-                                       lp->stats.tx_aborted_errors++;
-                               if (Stat_TNoCar(status) || Stat_TNoCTS(status))
+                               char *whatsup = NULL;
+                               lp->stats.tx_errors++;
+                               if (Stat_Abort(status)) 
+                                       lp->stats.tx_aborted_errors++;
+                               if (Stat_TNoCar(status)) {
+                                       whatsup = "aborted, no carrier";
                                        lp->stats.tx_carrier_errors++;
-                               if (Stat_TNoDMA(status))
-                                       lp->stats.tx_fifo_errors++;
+                               }
+                               if (Stat_TNoCTS(status)) {
+                                       whatsup = "aborted, lost CTS";
+                                       lp->stats.tx_carrier_errors++;
+                               }
+                               if (Stat_TNoDMA(status)) {
+                                       whatsup = "FIFO underran";
+                                       lp->stats.tx_fifo_errors++;
+                               }
+                               if (Stat_TXColl(status)) {
+                                       whatsup = "aborted, too many collisions";
+                                       lp->stats.tx_aborted_errors++;
+                               }
+                               if (whatsup)
+                                       printk(KERN_INFO "%s: transmit %s\n",
+                                              dev->name, whatsup);
                        }
                        else
                                lp->stats.tx_packets++;
@@ -1043,7 +1250,7 @@ static void eexp_hw_rxinit(struct device *dev)
        unsigned short ioaddr = dev->base_addr;
 
        lp->num_rx_bufs = 0;
-       lp->rx_first = rx_block;
+       lp->rx_first = lp->rx_ptr = rx_block;
        do
        {
                lp->num_rx_bufs++;
@@ -1052,9 +1259,9 @@ static void eexp_hw_rxinit(struct device *dev)
 
                outw(0, ioaddr + DATAPORT);  outw(0, ioaddr+DATAPORT);
                outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
-               outw(rx_block + 0x16, ioaddr+DATAPORT);
+               outw(0xffff, ioaddr+DATAPORT);
 
-               outw(0xdead, ioaddr+DATAPORT);
+               outw(0x0000, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
@@ -1062,19 +1269,30 @@ static void eexp_hw_rxinit(struct device *dev)
                outw(0xdead, ioaddr+DATAPORT);
                outw(0xdead, ioaddr+DATAPORT);
 
-               outw(0x8000, ioaddr+DATAPORT);
-               outw(0xffff, ioaddr+DATAPORT);
+               outw(0x0000, ioaddr+DATAPORT);
+               outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT);
                outw(rx_block + 0x20, ioaddr+DATAPORT);
                outw(0, ioaddr+DATAPORT);
-               outw(0x8000 | (RX_BUF_SIZE-0x20), ioaddr+DATAPORT);
+               outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT);
 
                lp->rx_last = rx_block;
                rx_block += RX_BUF_SIZE;
        } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE);
 
-       outw(lp->rx_last + 4, ioaddr+WRITE_PTR);
-       outw(lp->rx_first, ioaddr+DATAPORT);
 
+       /* Make first Rx frame descriptor point to first Rx buffer
+           descriptor */
+       outw(lp->rx_first + 6, ioaddr+WRITE_PTR);
+       outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
+
+       /* Close Rx frame descriptor ring */
+       outw(lp->rx_last + 4, ioaddr+WRITE_PTR);
+       outw(lp->rx_first, ioaddr+DATAPORT);
+  
+       /* Close Rx buffer descriptor ring */
+       outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR);
+       outw(lp->rx_first + 0x16, ioaddr+DATAPORT);
+       
 }
 
 /*
@@ -1083,6 +1301,7 @@ static void eexp_hw_rxinit(struct device *dev)
  * us.  We can't start the receive/transmission system up before we know that
  * the hardware is configured correctly.
  */
+
 static void eexp_hw_init586(struct device *dev)
 {
        struct net_local *lp = (struct net_local *)dev->priv;
@@ -1097,24 +1316,19 @@ static void eexp_hw_init586(struct device *dev)
 
        set_loopback(dev);
 
-       /* Bash the startup code a bit */
-       start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):
-               (start_code[28] & ~1);
-       lp->promisc = dev->flags & IFF_PROMISC;
-       memcpy(&start_code[33], &dev->dev_addr[0], 6);
-
        outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
 
        /* Download the startup code */
        outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
-       outw(start_code[0], ioaddr + 0x8006);
-       outw(start_code[1], ioaddr + 0x8008);
-       outw(start_code[2], ioaddr + 0x800a);
-       outw(start_code[3], ioaddr + 0x800c);
-       outw(start_code[4], ioaddr + 0x800e);
-       for (i = 10; i < (sizeof(start_code)); i+=32) {
+       outw(lp->width?0x0001:0x0000, ioaddr + 0x8006);
+       outw(0x0000, ioaddr + 0x8008);
+       outw(0x0000, ioaddr + 0x800a);
+       outw(0x0000, ioaddr + 0x800c);
+       outw(0x0000, ioaddr + 0x800e);
+
+       for (i = 0; i < (sizeof(start_code)); i+=32) {
                int j;
-               outw(i-10, ioaddr + SM_PTR);
+               outw(i, ioaddr + SM_PTR);
                for (j = 0; j < 16; j+=2)
                        outw(start_code[(i+j)/2],
                             ioaddr+0x4000+j);
@@ -1123,6 +1337,24 @@ static void eexp_hw_init586(struct device *dev)
                             ioaddr+0x8000+j);
        }
 
+       /* Do we want promiscuous mode or multicast? */
+       outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
+       i = inw(ioaddr+SHADOW(CONF_PROMISC));
+       outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1), 
+            ioaddr+SHADOW(CONF_PROMISC));
+       lp->was_promisc = dev->flags & IFF_PROMISC;
+#if 0
+       eexp_setup_filter(dev);
+#endif
+
+       /* Write our hardware address */
+       outw(CONF_HWADDR & ~31, ioaddr+SM_PTR);
+       outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR));
+       outw(((unsigned short *)dev->dev_addr)[1], 
+            ioaddr+SHADOW(CONF_HWADDR+2));
+       outw(((unsigned short *)dev->dev_addr)[2],
+            ioaddr+SHADOW(CONF_HWADDR+4));
+
        eexp_hw_txinit(dev);
        eexp_hw_rxinit(dev);
 
@@ -1193,6 +1425,38 @@ static void eexp_hw_init586(struct device *dev)
        return;
 }
 
+static void eexp_setup_filter(struct device *dev)
+{
+       struct dev_mc_list *dmi = dev->mc_list;
+       unsigned short ioaddr = dev->base_addr;
+       int count = dev->mc_count;
+       int i;
+       if (count > 8) {
+               printk(KERN_INFO "%s: too many multicast addresses (%d)\n",
+                      dev->name, count);
+               count = 8;
+       }
+       
+       outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
+       outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST));
+       for (i = 0; i < count; i++) {
+               unsigned short *data = (unsigned short *)dmi->dmi_addr;
+               if (!dmi) {
+                       printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
+                       break;
+               }
+               if (dmi->dmi_addrlen != ETH_ALEN) {
+                       printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
+                       continue;
+               }
+               outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
+               outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
+               outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
+               outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2));
+               outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR);
+               outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4));
+       }
+}
 
 /*
  * Set or clear the multicast filter for this adaptor.
@@ -1200,12 +1464,49 @@ static void eexp_hw_init586(struct device *dev)
 static void
 eexp_set_multicast(struct device *dev)
 {
+        unsigned short ioaddr = dev->base_addr;
+        struct net_local *lp = (struct net_local *)dev->priv;
+        int kick = 0, i;
+        if ((dev->flags & IFF_PROMISC) != lp->was_promisc) {
+                outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
+                i = inw(ioaddr+SHADOW(CONF_PROMISC));
+                outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
+                     ioaddr+SHADOW(CONF_PROMISC));
+                lp->was_promisc = dev->flags & IFF_PROMISC;
+                kick = 1;
+        }
+        if (!(dev->flags & IFF_PROMISC)) {
+                eexp_setup_filter(dev);
+                if (lp->old_mc_count != dev->mc_count) {
+                        kick = 1;
+                        lp->old_mc_count = dev->mc_count;
+                }
+        }
+        if (kick) {
+                unsigned long oj;
+                scb_command(dev, SCB_CUsuspend);
+                outb(0, ioaddr+SIGNAL_CA);
+                outb(0, ioaddr+SIGNAL_CA);
+#if 0
+                printk("%s: waiting for CU to go suspended\n", dev->name);
+#endif
+                oj = jiffies;
+                while ((SCB_CUstat(scb_status(dev)) == 2) &&
+                       ((jiffies-oj) < 100));
+               if (SCB_CUstat(scb_status(dev)) == 2)
+                       printk("%s: warning, CU didn't stop\n", dev->name);
+                lp->started &= ~(STARTED_CU);
+                scb_wrcbl(dev, CONF_LINK);
+                scb_command(dev, SCB_CUstart);
+                outb(0, ioaddr+SIGNAL_CA);
+        }
 }
 
 
 /*
  * MODULE stuff
  */
+
 #ifdef MODULE
 
 #define EEXP_MAX_CARDS     4    /* max number of cards to support */
index daff3ecf6b842b532bffaba59879cf25504b76e7..20d82d2c2bbe9a321dc7f72cf358c944c5788974 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 #include "hydra.h"
 
@@ -193,7 +193,9 @@ int hydra_probe(struct device *dev)
                        dev->stop = &hydra_close;
                        dev->hard_start_xmit = &hydra_start_xmit;
                        dev->get_stats = &hydra_get_stats;
-                       dev->set_multicast_list = &hydra_set_multicast_list;
+#ifdef HAVE_MULTICAST
+                       dev->set_multicast_list = &set_multicast_list;
+#endif
                        
                        /*
                         *      Cannot yet do multicast
@@ -643,6 +645,7 @@ static struct net_device_stats *hydra_get_stats(struct device *dev)
        return(&priv->stats);
 }
 
+#ifdef HAVE_MULTICAST
 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
 {
        struct hydra_private *priv = (struct hydra_private *)dev->priv;
@@ -652,6 +655,7 @@ static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
        /* (personally i don't care about multicasts at all :) */
        return;
 }
+#endif
 
 
 #ifdef MODULE
index 2e6278412c3f1a8538e4e4e63294c685660f5212..18e2642afea86d7cd80871b430b52c4fee07daf2 100644 (file)
@@ -2,7 +2,7 @@
 /* Generated by  cat $MYRI_HOME/lib/lanai/mcp4.dat > myri_code4.h */
 
 static unsigned int lanai4_code_off = 0x0000; /* half-word offset */ 
-static unsigned char lanai4_code[76256] = {
+static unsigned char lanai4_code[76256] __initdata = {
 0xF2,0x0E, 
 0xFE,0x00, 0xC2,0x90, 0x00,0x00, 0x07,0x88, 0x00,0x08, 0xE0,0x01, 0x01,0x4C, 0x97,0x93, 
 0xFF,0xFC, 0xE0,0x00, 0x00,0x14, 0x00,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x92,0x93, 
@@ -4775,7 +4775,7 @@ static unsigned char lanai4_code[76256] = {
 /* This is the LANai data */ 
 
 static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */
-static unsigned char lanai4_data[20472] = {
+static unsigned char lanai4_data[20472] __initdata = {
 0x00,0x00, 
 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
index 3654806183f6bd430ca14f87985d9434f46cccb1..3d7a2587ab55cc47dc817a345ad7c7b145cfd157 100644 (file)
@@ -19,6 +19,7 @@ static char *version =
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -171,7 +172,7 @@ static inline int myri_do_handshake(struct myri_eth *mp)
        return 0;
 }
 
-static int myri_load_lanai(struct myri_eth *mp)
+static inline int myri_load_lanai(struct myri_eth *mp)
 {
        struct device           *dev = mp->dev;
        struct myri_shmem       *shmem = mp->shmem;
@@ -893,7 +894,7 @@ static void dump_eeprom(struct myri_eth *mp)
 }
 #endif
 
-static int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num)
+static inline int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, int num)
 {
        static unsigned version_printed = 0;
        struct myri_eth *mp;
@@ -1105,7 +1106,7 @@ static int myri_ether_init(struct device *dev, struct linux_sbus_device *sdev, i
        return 0;
 }
 
-int myri_sbus_probe(struct device *dev)
+__initfunc(int myri_sbus_probe(struct device *dev))
 {
        struct linux_sbus *bus;
        struct linux_sbus_device *sdev = 0;
index fee809b1ea1c4dd8c0723c5fdec718878252e92e..37484d1632db541529e937f2172aeab6fc07c1e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: plip.c,v 1.1.1.1.2.6 1997/03/26 17:52:20 phil Exp $ */
+/* $Id: plip.c,v 1.3.6.2 1997/04/16 15:07:56 phil Exp $ */
 /* PLIP: A parallel port "network" driver for Linux. */
 /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */
 /*
@@ -1190,6 +1190,36 @@ plip_searchfor(int list[], int a)
        return 0;
 }
 
+static int
+plip_init_one(int i, struct parport *pb)
+{
+       if (i == PLIP_MAX) {
+               printk(KERN_ERR "plip: too many devices\n");
+               return 1;
+       }
+       dev_plip[i] = kmalloc(sizeof(struct device),
+                             GFP_KERNEL);
+       if (!dev_plip[i]) {
+               printk(KERN_ERR "plip: memory squeeze\n");
+               return 1;
+       }
+       memset(dev_plip[i], 0, sizeof(struct device));
+       dev_plip[i]->name = kmalloc(strlen("plipXXX"), GFP_KERNEL);
+       if (!dev_plip[i]->name) {
+               printk(KERN_ERR "plip: memory squeeze.\n");
+               kfree(dev_plip[i]);
+               return 1;
+       }
+       sprintf(dev_plip[i]->name, "plip%d", i);
+       dev_plip[i]->priv = pb;
+       if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) {
+               kfree(dev_plip[i]->name);
+               kfree(dev_plip[i]);
+               return 1; 
+       }
+       return 0;
+}
+
 int
 plip_init(void)
 {
@@ -1207,38 +1237,17 @@ plip_init(void)
 
        /* When user feeds parameters, use them */
        while (pb) {
-               if ((parport[0] == -1 && (!timid || !pb->devices)) || 
-                   plip_searchfor(parport, i)) {
-                       if (i == PLIP_MAX) {
-                               printk(KERN_ERR "plip: too many devices\n");
-                               break;
-                       }
-                       dev_plip[i] = kmalloc(sizeof(struct device),
-                                             GFP_KERNEL);
-                       if (!dev_plip[i]) {
-                               printk(KERN_ERR "plip: memory squeeze\n");
-                               break;
-                       }
-                       memset(dev_plip[i], 0, sizeof(struct device));
-                       dev_plip[i]->name = 
-                               kmalloc(strlen("plipXXX"), GFP_KERNEL);
-                       if (!dev_plip[i]->name) {
-                               printk(KERN_ERR "plip: memory squeeze.\n");
-                               kfree(dev_plip[i]);
-                               break;
-                       }
-                       sprintf(dev_plip[i]->name, "plip%d", i);
-                       dev_plip[i]->priv = pb;
-                       if (plip_init_dev(dev_plip[i],pb) || register_netdev(dev_plip[i])) {
-                               kfree(dev_plip[i]->name);
-                               kfree(dev_plip[i]);
-                       } else {
+               if (pb->modes & PARPORT_MODE_SPP) {
+                       if ((parport[0] == -1 && (!timid || !pb->devices)) || 
+                           plip_searchfor(parport, i)) {
+                               if (plip_init_one(i, pb))
+                                       continue;
                                devices++;
                        }
+                       i++;
                }
-               i++;
                pb = pb->next;
-       }
+       }
 
        if (devices == 0) {
                printk(KERN_INFO "plip: no devices registered\n");
index a22cb1bb03cc562fee017ac34bec5cd4968bf787..66e3b0b68ca3a0f126674b98208b432c89a97657 100644 (file)
@@ -20,6 +20,7 @@ static char *version =
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -2058,7 +2059,7 @@ static void happy_meal_set_multicast(struct device *dev)
        dev->tbusy = 0;
 }
 
-static int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev)
+static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *sdev)
 {
        static unsigned version_printed = 0;
        struct happy_meal *hp;
@@ -2201,7 +2202,7 @@ static int happy_meal_ether_init(struct device *dev, struct linux_sbus_device *s
        return 0;
 }
 
-int happy_meal_probe(struct device *dev)
+__initfunc(int happy_meal_probe(struct device *dev))
 {
        struct linux_sbus *bus;
        struct linux_sbus_device *sdev = 0;
index 46820b2063dfc4f3f3c38646e1a05a3b66c74597..0485aa2d198fdc8eaa93e79affc303fd89bb7e9a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sunlance.c,v 1.61 1997/04/10 06:40:54 davem Exp $
+/* $Id: sunlance.c,v 1.62 1997/04/16 10:27:25 jj Exp $
  * lance.c: Linux/Sparc/Lance driver
  *
  *     Written 1995, 1996 by Miguel de Icaza
@@ -75,6 +75,7 @@ static char *lancedma = "LANCE DMA";
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -934,9 +935,10 @@ static void lance_set_multicast (struct device *dev)
        dev->tbusy = 0;
 }
 
-int sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev,
-                     struct Linux_SBus_DMA *ledma,
-                     struct linux_sbus_device *lebuffer)
+__initfunc(static int 
+sparc_lance_init (struct device *dev, struct linux_sbus_device *sdev,
+                 struct Linux_SBus_DMA *ledma,
+                 struct linux_sbus_device *lebuffer))
 {
        static unsigned version_printed = 0;
        int    i;
@@ -1097,7 +1099,7 @@ no_link_test:
 }
 
 /* On 4m, find the associated dma for the lance chip */
-static struct Linux_SBus_DMA *
+static inline struct Linux_SBus_DMA *
 find_ledma (struct linux_sbus_device *dev)
 {
        struct Linux_SBus_DMA *p;
@@ -1109,7 +1111,7 @@ find_ledma (struct linux_sbus_device *dev)
 }
 
 /* Find all the lance cards on the system and initialize them */
-int sparc_lance_probe (struct device *dev)
+__initfunc(int sparc_lance_probe (struct device *dev))
 {
        struct linux_sbus *bus;
        struct linux_sbus_device *sdev = 0;
index b0085181ec6ef4d661a36c2108a39313daf7fb69..c987c5e9fae86cfbdbb07b628aa480b2aecb1a41 100644 (file)
@@ -21,6 +21,7 @@ static char *version =
 #include <linux/in.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -902,7 +903,7 @@ static inline void qec_init_once(struct sunqec *qecp, struct linux_sbus_device *
 }
 
 /* Four QE's per QEC card. */
-static int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev)
+static inline int qec_ether_init(struct device *dev, struct linux_sbus_device *sdev)
 {
        static unsigned version_printed = 0;
        struct device *qe_devs[4];
@@ -1149,7 +1150,7 @@ qec_free_devs:
        return res;
 }
 
-int qec_probe(struct device *dev)
+__initfunc(int qec_probe(struct device *dev))
 {
        struct linux_sbus *bus;
        struct linux_sbus_device *sdev = 0;
index 43d792ba59850cf8a2f0d9a5bc1a78919c6113cc..0b18de7d9948f553e00f3eadfc356fa8212f7504 100644 (file)
@@ -112,7 +112,7 @@ wv_struct_check(void)
  * Read from card's Host Adaptor Status Register.
  */
 static inline u_short
-hasr_read(u_short      ioaddr)
+hasr_read(u_long       ioaddr)
 {
   return(inw(HASR(ioaddr)));
 } /* hasr_read */
@@ -122,7 +122,7 @@ hasr_read(u_short   ioaddr)
  * Write to card's Host Adapter Command Register.
  */
 static inline void
-hacr_write(u_short     ioaddr,
+hacr_write(u_long      ioaddr,
           u_short      hacr)
 {
   outw(hacr, HACR(ioaddr));
@@ -134,7 +134,7 @@ hacr_write(u_short  ioaddr,
  * those times when it is needed.
  */
 static inline void
-hacr_write_slow(u_short        ioaddr,
+hacr_write_slow(u_long ioaddr,
                u_short hacr)
 {
   hacr_write(ioaddr, hacr);
@@ -147,7 +147,7 @@ hacr_write_slow(u_short     ioaddr,
  * Set the channel attention bit.
  */
 static inline void
-set_chan_attn(u_short  ioaddr,
+set_chan_attn(u_long   ioaddr,
              u_short   hacr)
 {
   hacr_write(ioaddr, hacr | HACR_CA);
@@ -158,7 +158,7 @@ set_chan_attn(u_short       ioaddr,
  * Reset, and then set host adaptor into default mode.
  */
 static inline void
-wv_hacr_reset(u_short  ioaddr)
+wv_hacr_reset(u_long   ioaddr)
 {
   hacr_write_slow(ioaddr, HACR_RESET);
   hacr_write(ioaddr, HACR_DEFAULT);
@@ -169,7 +169,7 @@ wv_hacr_reset(u_short       ioaddr)
  * Set the i/o transfer over the ISA bus to 8 bits mode
  */
 static inline void
-wv_16_off(u_short      ioaddr,
+wv_16_off(u_long       ioaddr,
          u_short       hacr)
 {
   hacr &= ~HACR_16BITS;
@@ -181,7 +181,7 @@ wv_16_off(u_short   ioaddr,
  * Set the i/o transfer over the ISA bus to 8 bits mode
  */
 static inline void
-wv_16_on(u_short       ioaddr,
+wv_16_on(u_long                ioaddr,
         u_short        hacr)
 {
   hacr |= HACR_16BITS;
@@ -196,7 +196,7 @@ static inline void
 wv_ints_off(device *   dev)
 {
   net_local *  lp = (net_local *)dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_long       x;
 
   x = wv_splhi();
@@ -215,7 +215,7 @@ static inline void
 wv_ints_on(device *    dev)
 {
   net_local *  lp = (net_local *)dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_long       x;
 
   x = wv_splhi();
@@ -239,7 +239,7 @@ wv_ints_on(device * dev)
  * Read bytes from the PSA.
  */
 static void
-psa_read(u_short       ioaddr,
+psa_read(u_long                ioaddr,
         u_short        hacr,
         int            o,      /* offset in PSA */
         u_char *       b,      /* buffer to fill */
@@ -262,7 +262,7 @@ psa_read(u_short    ioaddr,
  * Write the Paramter Storage Area to the WaveLAN card's memory
  */
 static void
-psa_write(u_short      ioaddr,
+psa_write(u_long       ioaddr,
          u_short       hacr,
          int           o,      /* Offset in psa */
          u_char *      b,      /* Buffer in memory */
@@ -329,7 +329,7 @@ psa_crc(u_short *   psa,    /* The PSA */
  * Write 1 byte to the MMC.
  */
 static inline void
-mmc_out(u_short                ioaddr,
+mmc_out(u_long         ioaddr,
        u_short         o,
        u_char          d)
 {
@@ -347,7 +347,7 @@ mmc_out(u_short             ioaddr,
  * We start by the end because it is the way it should be !
  */
 static inline void
-mmc_write(u_short      ioaddr,
+mmc_write(u_long       ioaddr,
          u_char        o,
          u_char *      b,
          int           n)
@@ -365,7 +365,7 @@ mmc_write(u_short   ioaddr,
  * Optimised version for 1 byte, avoid using memory...
  */
 static inline u_char
-mmc_in(u_short ioaddr,
+mmc_in(u_long  ioaddr,
        u_short o)
 {
   while(inw(HASR(ioaddr)) & HASR_MMC_BUSY)
@@ -386,7 +386,7 @@ mmc_in(u_short      ioaddr,
  * We start by the end because it is the way it should be !
  */
 static inline void
-mmc_read(u_short       ioaddr,
+mmc_read(u_long                ioaddr,
         u_char         o,
         u_char *       b,
         int            n)
@@ -398,13 +398,29 @@ mmc_read(u_short  ioaddr,
     *(--b) = mmc_in(ioaddr, --o);
 } /* mmc_read */
 
+/*------------------------------------------------------------------*/
+/*
+ * Get the type of encryption available...
+ */
+static inline int
+mmc_encr(u_long                ioaddr) /* i/o port of the card */
+{
+  int  temp;
+
+  temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail));
+  if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
+    return 0;
+  else
+    return temp;
+}
+
 /*------------------------------------------------------------------*/
 /*
  * Wait for the frequency EEprom to complete a command...
  * I hope this one will be optimally inlined...
  */
 static inline void
-fee_wait(u_short       ioaddr, /* i/o port of the card */
+fee_wait(u_long                ioaddr, /* i/o port of the card */
         int            delay,  /* Base delay to wait for */
         int            number) /* Number of time to wait */
 {
@@ -420,7 +436,7 @@ fee_wait(u_short    ioaddr, /* i/o port of the card */
  * Read bytes from the Frequency EEprom (frequency select cards).
  */
 static void
-fee_read(u_short       ioaddr, /* i/o port of the card */
+fee_read(u_long                ioaddr, /* i/o port of the card */
         u_short        o,      /* destination offset */
         u_short *      b,      /* data buffer */
         int            n)      /* number of registers */
@@ -445,6 +461,8 @@ fee_read(u_short    ioaddr, /* i/o port of the card */
     }
 }
 
+#ifdef WIRELESS_EXT    /* If wireless extension exist in the kernel */
+
 /*------------------------------------------------------------------*/
 /*
  * Write bytes from the Frequency EEprom (frequency select cards).
@@ -453,7 +471,7 @@ fee_read(u_short    ioaddr, /* i/o port of the card */
  * Jean II
  */
 static void
-fee_write(u_short      ioaddr, /* i/o port of the card */
+fee_write(u_long       ioaddr, /* i/o port of the card */
          u_short       o,      /* destination offset */
          u_short *     b,      /* data buffer */
          int           n)      /* number of registers */
@@ -528,6 +546,7 @@ fee_write(u_short   ioaddr, /* i/o port of the card */
   fee_wait(ioaddr, 10, 100);
 #endif /* EEPROM_IS_PROTECTED */
 }
+#endif /* WIRELESS_EXT */
 
 /************************ I82586 SUBROUTINES *************************/
 /*
@@ -540,7 +559,7 @@ fee_write(u_short   ioaddr, /* i/o port of the card */
  * Why inlining this function make it fail ???
  */
 static /*inline*/ void
-obram_read(u_short     ioaddr,
+obram_read(u_long      ioaddr,
           u_short      o,
           u_char *     b,
           int          n)
@@ -554,7 +573,7 @@ obram_read(u_short  ioaddr,
  * Write bytes to the on-board RAM.
  */
 static inline void
-obram_write(u_short    ioaddr,
+obram_write(u_long     ioaddr,
            u_short     o,
            u_char *    b,
            int         n)
@@ -571,7 +590,7 @@ static void
 wv_ack(device *                dev)
 {
   net_local *  lp = (net_local *)dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_short      scb_cs;
   int          i;
 
@@ -614,7 +633,7 @@ wv_synchronous_cmd(device * dev,
                   const char * str)
 {
   net_local *  lp = (net_local *)dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_short      scb_cmd;
   ach_t                cb;
   int          i;
@@ -660,7 +679,7 @@ wv_synchronous_cmd(device * dev,
  */
 static inline int
 wv_config_complete(device *    dev,
-                  u_short      ioaddr,
+                  u_long       ioaddr,
                   net_local *  lp)
 {
   unsigned short       mcs_addr;
@@ -722,7 +741,7 @@ wv_config_complete(device * dev,
  */
 static int
 wv_complete(device *   dev,
-           u_short     ioaddr,
+           u_long      ioaddr,
            net_local * lp)
 {
   int  nreaped = 0;
@@ -992,7 +1011,7 @@ wv_psa_show(psa_t *        p)
 static void
 wv_mmc_show(device *   dev)
 {
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   net_local *  lp = (net_local *)dev->priv;
   mmr_t                m;
 
@@ -1077,7 +1096,7 @@ wv_mmc_show(device *      dev)
  * Print the last block of the i82586 memory
  */
 static void
-wv_scb_show(unsigned short     ioaddr)
+wv_scb_show(u_long     ioaddr)
 {
   scb_t                scb;
 
@@ -1162,7 +1181,7 @@ wv_cu_show_one(device *           dev,
               int              i,
               u_short          p)
 {
-  unsigned short       ioaddr;
+  u_long               ioaddr;
   ac_tx_t              actx;
 
   ioaddr = dev->base_addr;
@@ -1529,7 +1548,7 @@ wavelan_set_mac_address(device *  dev,
  * (called in wavelan_ioctl)
  */
 static inline int
-wv_set_frequency(u_short       ioaddr, /* i/o port of the card */
+wv_set_frequency(u_long                ioaddr, /* i/o port of the card */
                 iw_freq *      frequency)
 {
   const int    BAND_NUM = 10;  /* Number of bands */
@@ -1550,7 +1569,7 @@ wv_set_frequency(u_short  ioaddr, /* i/o port of the card */
     }
 
   /* Setting by channel (same as wfreqsel) */
-  /* Warning : each channel is 11MHz wide, so some of the channels
+  /* Warning : each channel is 22MHz wide, so some of the channels
    * will interfere... */
   if((frequency->e == 0) &&
      (frequency->m >= 0) && (frequency->m < BAND_NUM))
@@ -1729,7 +1748,7 @@ wv_set_frequency(u_short  ioaddr, /* i/o port of the card */
  * Give the list of available frequencies
  */
 static inline int
-wv_frequency_list(u_short      ioaddr, /* i/o port of the card */
+wv_frequency_list(u_long       ioaddr, /* i/o port of the card */
                  iw_freq *     list,   /* List of frequency to fill */
                  int           max)    /* Maximum number of frequencies */
 {
@@ -1826,7 +1845,7 @@ wavelan_ioctl(struct device *     dev,    /* Device on wich the ioctl apply */
              struct ifreq *    rq,     /* Data passed */
              int               cmd)    /* Ioctl number */
 {
-  unsigned short       ioaddr = dev->base_addr;
+  u_long               ioaddr = dev->base_addr;
   net_local *          lp = (net_local *)dev->priv;    /* lp is not unused */
   struct iwreq *       wrq = (struct iwreq *) rq;
   psa_t                        psa;
@@ -1866,9 +1885,7 @@ wavelan_ioctl(struct device *     dev,    /* Device on wich the ioctl apply */
          m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8;
          mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m,
                    (unsigned char *)&m.w.mmw_netw_id_l, 2);
-         m.w.mmw_loopt_sel = 0x00;
-         mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m,
-                   (unsigned char *)&m.w.mmw_loopt_sel, 1);
+         mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
        }
       else
        {
@@ -1878,10 +1895,8 @@ wavelan_ioctl(struct device *    dev,    /* Device on wich the ioctl apply */
                    (char *)&psa.psa_nwid_select - (char *)&psa,
                    (unsigned char *)&psa.psa_nwid_select, 1);
 
-         /* Disable nwid in the mmc (no check) */
-         m.w.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
-         mmc_write(ioaddr, (char *)&m.w.mmw_loopt_sel - (char *)&m,
-                   (unsigned char *)&m.w.mmw_loopt_sel, 1);
+         /* Disable nwid in the mmc (no filtering) */
+         mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), MMW_LOOPT_SEL_DIS_NWID);
        }
       break;
 
@@ -1950,6 +1965,82 @@ wavelan_ioctl(struct device *    dev,    /* Device on wich the ioctl apply */
       wrq->u.sensitivity = psa.psa_thr_pre_set & 0x3F;
       break;
 
+     case SIOCSIWENCODE:
+       /* Set encryption key */
+       if(!mmc_encr(ioaddr))
+        {
+          ret = -EOPNOTSUPP;
+          break;
+        }
+
+       if(wrq->u.encoding.method)
+        {      /* enable encryption */
+          int          i;
+          long long    key = wrq->u.encoding.code;
+
+          for(i = 7; i >= 0; i--)
+            {
+              psa.psa_encryption_key[i] = key & 0xFF;
+              key >>= 8;
+            }
+           psa.psa_encryption_select = 1;
+          psa_write(ioaddr, lp->hacr,
+                    (char *) &psa.psa_encryption_select - (char *) &psa,
+                    (unsigned char *) &psa.psa_encryption_select, 8+1);
+
+           mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
+                  MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
+           mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
+                    (unsigned char *) &psa.psa_encryption_key, 8);
+        }
+       else
+        {      /* disable encryption */
+          psa.psa_encryption_select = 0;
+          psa_write(ioaddr, lp->hacr,
+                    (char *) &psa.psa_encryption_select - (char *) &psa,
+                    (unsigned char *) &psa.psa_encryption_select, 1);
+
+          mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
+        }
+       break;
+
+     case SIOCGIWENCODE:
+       /* Read the encryption key */
+       if(!mmc_encr(ioaddr))
+        {
+          ret = -EOPNOTSUPP;
+          break;
+        }
+
+       /* only super-user can see encryption key */
+       if(!suser())
+        {
+          ret = -EPERM;
+          break;
+        }
+       else
+        {
+          int          i;
+          long long    key = 0;
+
+          psa_read(ioaddr, lp->hacr,
+                   (char *) &psa.psa_encryption_select - (char *) &psa,
+                   (unsigned char *) &psa.psa_encryption_select, 1+8);
+          for(i = 0; i < 8; i++)
+            {
+              key <<= 8;
+              key += psa.psa_encryption_key[i];
+            }
+          wrq->u.encoding.code = key;
+
+          /* encryption is enabled */
+          if(psa.psa_encryption_select)
+            wrq->u.encoding.method = mmc_encr(ioaddr);
+          else
+            wrq->u.encoding.method = 0;
+        }
+       break;
+
     case SIOCGIWRANGE:
       /* Basic checking... */
       if(wrq->u.data.pointer != (caddr_t) 0)
@@ -2207,7 +2298,7 @@ wavelan_ioctl(struct device *     dev,    /* Device on wich the ioctl apply */
 static iw_stats *
 wavelan_get_wireless_stats(device *    dev)
 {
-  unsigned short       ioaddr = dev->base_addr;
+  u_long               ioaddr = dev->base_addr;
   net_local *          lp = (net_local *) dev->priv;
   mmr_t                        m;
   iw_stats *           wstats;
@@ -2281,7 +2372,7 @@ wv_packet_read(device *           dev,
               int              sksize)
 {
   net_local *          lp = (net_local *) dev->priv;
-  u_short              ioaddr = dev->base_addr;
+  u_long               ioaddr = dev->base_addr;
   struct sk_buff *     skb;
 
 #ifdef DEBUG_RX_TRACE
@@ -2353,8 +2444,9 @@ wv_packet_read(device *           dev,
    */
   netif_rx(skb);
 
+  /* Keep stats up to date */
   lp->stats.rx_packets++;
-  lp->stats.rx_bytes+=sksize;
+  lp->stats.rx_bytes += skb->len;
 
 #ifdef DEBUG_RX_TRACE
   printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2370,7 +2462,7 @@ wv_packet_read(device *           dev,
 static inline void
 wv_receive(device *    dev)
 {
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   net_local *  lp = (net_local *)dev->priv;
   int          nreaped = 0;
 
@@ -2556,7 +2648,7 @@ wv_packet_write(device *  dev,
                short   length)
 {
   net_local *          lp = (net_local *) dev->priv;
-  u_short              ioaddr = dev->base_addr;
+  u_long               ioaddr = dev->base_addr;
   unsigned short       txblock;
   unsigned short       txpred;
   unsigned short       tx_addr;
@@ -2649,6 +2741,9 @@ if (lp->tx_n_in_use > 0)
              (unsigned char *) &nop.nop_h.ac_link,
              sizeof(nop.nop_h.ac_link));
 
+  /* Keep stats up to date */
+  lp->stats.tx_bytes += length;
+
   /* If watchdog not already active, activate it... */
   if(lp->watchdog.prev == (timer_list *) NULL)
     {
@@ -2700,20 +2795,6 @@ wavelan_packet_xmit(struct sk_buff *     skb,
   if(dev->tbusy)
     return 1;
 
-  /*
-   * If some higher layer thinks we've missed
-   * a tx-done interrupt we are passed NULL.
-   * Caution: dev_tint() handles the cli()/sti() itself.
-   */
-  if(skb == (struct sk_buff *)0)
-    {
-#ifdef DEBUG_TX_ERROR
-      printk(KERN_INFO "%s: wavelan_packet_xmit(): skb == NULL\n", dev->name);
-#endif
-      dev_tint(dev);
-      return 0;
-    }
-
   /*
    * Block a timer-based transmit from overlapping.
    * In other words, prevent reentering this routine.
@@ -2761,7 +2842,7 @@ wavelan_packet_xmit(struct sk_buff *      skb,
 static inline int
 wv_mmc_init(device *   dev)
 {
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   net_local *  lp = (net_local *)dev->priv;
   psa_t                psa;
   mmw_t                m;
@@ -2790,6 +2871,9 @@ wv_mmc_init(device *      dev)
       /* As NWID is not set : no NWID checking */
       psa.psa_nwid_select = 0;
 
+      /* Disable encryption */
+      psa.psa_encryption_select = 0;
+
       /* Set to standard values
        * 0x04 for AT,
        * 0x01 for MCA,
@@ -2807,7 +2891,7 @@ wv_mmc_init(device *      dev)
 #ifdef USE_PSA_CONFIG
       /* Write the psa */
       psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,
-               (unsigned char *)psa.psa_nwid, 3);
+               (unsigned char *)psa.psa_nwid, 4);
       psa_write(ioaddr, lp->hacr, (char *)&psa.psa_thr_pre_set - (char *)&psa,
                (unsigned char *)&psa.psa_thr_pre_set, 1);
       psa_write(ioaddr, lp->hacr, (char *)&psa.psa_quality_thr - (char *)&psa,
@@ -2829,6 +2913,14 @@ wv_mmc_init(device *     dev)
   else
     m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
 
+  memcpy(&m.mmw_encr_key, &psa.psa_encryption_key, 
+        sizeof(m.mmw_encr_key));
+
+  if(psa.psa_encryption_select)
+    m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
+  else
+    m.mmw_encr_enable = 0;
+
   m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
   m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
 
@@ -2920,7 +3012,7 @@ static inline int
 wv_ru_start(device *   dev)
 {
   net_local *  lp = (net_local *) dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_short      scb_cs;
   fd_t         fd;
   rbd_t                rbd;
@@ -3014,7 +3106,7 @@ static inline int
 wv_cu_start(device *   dev)
 {
   net_local *  lp = (net_local *) dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   int          i;
   u_short      txblock;
   u_short      first_nop;
@@ -3115,7 +3207,7 @@ static inline int
 wv_82586_start(device *        dev)
 {
   net_local *  lp = (net_local *) dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   scp_t                scp;            /* system configuration pointer */
   iscp_t       iscp;           /* intermediate scp */
   scb_t                scb;            /* system control block */
@@ -3245,7 +3337,7 @@ static void
 wv_82586_config(device *       dev)
 {
   net_local *          lp = (net_local *) dev->priv;
-  u_short              ioaddr = dev->base_addr;
+  u_long               ioaddr = dev->base_addr;
   unsigned short       txblock;
   unsigned short       txpred;
   unsigned short       tx_addr;
@@ -3441,7 +3533,7 @@ static inline void
 wv_82586_stop(device * dev)
 {
   net_local *  lp = (net_local *) dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_short      scb_cmd;
 
 #ifdef DEBUG_CONFIG_TRACE
@@ -3476,7 +3568,7 @@ static int
 wv_hw_reset(device *   dev)
 {
   net_local *  lp = (net_local *)dev->priv;
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name,
@@ -3521,7 +3613,7 @@ wv_hw_reset(device *      dev)
  * (called in wavelan_probe() and init_module())
  */
 static int
-wv_check_ioaddr(u_short                ioaddr,
+wv_check_ioaddr(u_long         ioaddr,
                u_char *        mac)
 {
   int          i;              /* Loop counter */
@@ -3568,7 +3660,7 @@ wavelan_interrupt(int                     irq,
                  struct pt_regs *      regs)
 {
   device *     dev;
-  u_short      ioaddr;
+  u_long       ioaddr;
   net_local *  lp;
   u_short      hasr;
   u_short      status;
@@ -3715,7 +3807,7 @@ wavelan_watchdog(u_long           a)
 {
   device *             dev;
   net_local *          lp;
-  unsigned short       ioaddr;
+  u_long               ioaddr;
   unsigned long                x;
   unsigned int         nreaped;
 
@@ -3910,7 +4002,7 @@ wavelan_close(device *    dev)
 static int
 wavelan_config(device *        dev)
 {
-  u_short      ioaddr = dev->base_addr;
+  u_long       ioaddr = dev->base_addr;
   u_char       irq_mask;
   int          irq;
   net_local *  lp;
index d9c60da22bcdf665d9fffb8bded5170532bf4f63..338ef1f6f81b07403ecf64061f36434b739cfe96 100644 (file)
 
 /* ------------------------ SPECIFIC NOTES ------------------------ */
 /*
+ * wavelan.o is darn too big
+ * -------------------------
+ *     That's true ! There is a very simple way to reduce the driver
+ *     object by 33% (yes !). Comment out the following line :
+ *             #include <linux/wireless.h>
+ *
  * MAC address and hardware detection :
  * ----------------------------------
  *     The detection code of the wavelan chech that the first 3
  * caracteristics of the hardware in a standard way and support for
  * applications for taking advantage of it (like Mobile IP).
  *
- * By default, these wireless extensions are disabled, because they
- * need a patch to the Linux Kernel. This simple patch may be found
- * with the driver + some utilities to access those wireless
- * extensions (iwconfig...). Hopefully, those wireless extensions will
- * make their way in the kernel someday.
+ * You will need to enable the CONFIG_NET_RADIO define in the kernel
+ * configuration to enable the wireless extensions (this is the one
+ * giving access to the radio network device choice).
  *
- * You also will need to enable the CONFIG_NET_RADIO in the kernel
- * configuration to enable the wireless extensions.
+ * It might also be a good idea as well to fetch the wireless tools to
+ * configure the device and play a bit.
  */
 
 /* ---------------------------- FILES ---------------------------- */
  *     Ajay Bakre (bakre@paul.rutgers.edu),
  *     Donald Becker (becker@cesdis.gsfc.nasa.gov),
  *     Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com),
+ *     Brent Elphick <belphick@uwaterloo.ca>,
  *     Anders Klemets (klemets@it.kth.se),
  *     Vladimir V. Kolpakov (w@stier.koenig.ru),
  *     Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
  *     John Rosenberg (johnr@cs.usyd.edu.au),
  *     George Rossi (george@phm.gov.au),
  *     Arthur Scott (arthur@cs.usyd.edu.au),
+ *     Stanislav Sinyagin <stas@isf.ru>
  *     Peter Storey,
  * for their assistance and advice.
  *
  *     - Update to wireless extensions changes
  *     - Silly bug in card initial configuration (psa_conf_status)
  *
- * Changes made for release in 2.1.27 :
- * ----------------------------------
+ * Changes made for release in 2.1.27 & 2.0.30 :
+ * -------------------------------------------
  *     - Small bug in debug code (probably not the last one...)
  *     - Remove extern kerword for wavelan_probe()
  *     - Level threshold is now a standard wireless extension (version 4 !)
  *     - modules parameters types (new module interface)
  *
+ * Changes made for release in 2.1.36 :
+ * ----------------------------------
+ *     - byte count stats (courtesy of David Hinds)
+ *     - Remove dev_tint stuff (courtesy of David Hinds)
+ *     - Encryption setting from Brent Elphick (thanks a lot !)
+ *     - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
+ *
  * Wishes & dreams :
  * ---------------
- *     - Encryption stuff
  *     - Roaming
  */
 
 /************************ CONSTANTS & MACROS ************************/
 
 #ifdef DEBUG_VERSION_SHOW
-static const char      *version        = "wavelan.c : v15 (wireless extensions) 12/2/97\n";
+static const char      *version        = "wavelan.c : v16 (wireless extensions) 17/4/97\n";
 #endif
 
 /* Watchdog temporisation */
@@ -436,69 +448,65 @@ static int
        wv_psa_to_irq(u_char);
 /* ------------------- HOST ADAPTER SUBROUTINES ------------------- */
 static inline u_short          /* data */
-       hasr_read(u_short);     /* Read the host interface : base address */
+       hasr_read(u_long);      /* Read the host interface : base address */
 static inline void
-       hacr_write(u_short,     /* Write to host interface : base address */
+       hacr_write(u_long,      /* Write to host interface : base address */
                   u_short),    /* data */
-       hacr_write_slow(u_short,
+       hacr_write_slow(u_long,
                   u_short),
-       set_chan_attn(u_short,  /* ioaddr */
+       set_chan_attn(u_long,   /* ioaddr */
                      u_short), /* hacr */
-       wv_hacr_reset(u_short), /* ioaddr */
-       wv_16_off(u_short,      /* ioaddr */
+       wv_hacr_reset(u_long),  /* ioaddr */
+       wv_16_off(u_long,       /* ioaddr */
                  u_short),     /* hacr */
-       wv_16_on(u_short,       /* ioaddr */
+       wv_16_on(u_long,        /* ioaddr */
                 u_short),      /* hacr */
        wv_ints_off(device *),
        wv_ints_on(device *);
 /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
 static void
-       psa_read(u_short,       /* Read the Parameter Storage Area */
+       psa_read(u_long,        /* Read the Parameter Storage Area */
                 u_short,       /* hacr */
                 int,           /* offset in PSA */
                 u_char *,      /* buffer to fill */
                 int),          /* size to read */
-       psa_write(u_short,      /* Write to the PSA */
+       psa_write(u_long,       /* Write to the PSA */
                  u_short,      /* hacr */
                  int,          /* Offset in psa */
                  u_char *,     /* Buffer in memory */
                  int);         /* Length of buffer */
 static inline void
-       mmc_out(u_short,        /* Write 1 byte to the Modem Manag Control */
+       mmc_out(u_long,         /* Write 1 byte to the Modem Manag Control */
                u_short,
                u_char),
-       mmc_write(u_short,      /* Write n bytes to the MMC */
+       mmc_write(u_long,       /* Write n bytes to the MMC */
                  u_char,
                  u_char *,
                  int);
 static inline u_char           /* Read 1 byte from the MMC */
-       mmc_in(u_short,
+       mmc_in(u_long,
               u_short);
 static inline void
-       mmc_read(u_short,       /* Read n bytes from the MMC */
+       mmc_read(u_long,        /* Read n bytes from the MMC */
                 u_char,
                 u_char *,
                 int),
-       fee_wait(u_short,       /* Wait for frequency EEprom : base address */
+       fee_wait(u_long,        /* Wait for frequency EEprom : base address */
                 int,           /* Base delay to wait for */
                 int);          /* Number of time to wait */
 static void
-       fee_read(u_short,       /* Read the frequency EEprom : base address */
+       fee_read(u_long,        /* Read the frequency EEprom : base address */
                 u_short,       /* destination offset */
                 u_short *,     /* data buffer */
-                int),          /* number of registers */
-       fee_write(u_short,      /* Write to frequency EEprom : base address */
-                 u_short,      /* destination offset */
-                 u_short *,    /* data buffer */
-                 int);         /* number of registers */
+                int);          /* number of registers */
 /* ---------------------- I82586 SUBROUTINES ----------------------- */
 static /*inline*/ void
-       obram_read(u_short,     /* ioaddr */
+       obram_read(u_long,      /* ioaddr */
                   u_short,     /* o */
                   u_char *,    /* b */
                   int);        /* n */
 static inline void
-       obram_write(u_short,    /* ioaddr */
+       obram_write(u_long,     /* ioaddr */
                    u_short,    /* o */
                    u_char *,   /* b */
                    int);       /* n */
@@ -508,11 +516,11 @@ static inline int
        wv_synchronous_cmd(device *,
                           const char *),
        wv_config_complete(device *,
-                          u_short,
+                          u_long,
                           net_local *);
 static int
        wv_complete(device *,
-                   u_short,
+                   u_long,
                    net_local *);
 static inline void
        wv_82586_reconfig(device *);
@@ -554,7 +562,7 @@ static inline void
        wv_82586_stop(device *);
 static int
        wv_hw_reset(device *),          /* Reset the wavelan hardware */
-       wv_check_ioaddr(u_short,        /* ioaddr */
+       wv_check_ioaddr(u_long,         /* ioaddr */
                        u_char *);      /* mac address (read) */
 /* ---------------------- INTERRUPT HANDLING ---------------------- */
 static void
index db40b655313ac93262dd7cf3b8d8751b65e1a2cc..6b8420a2c3f3c87c1fea1a38715cb0666103fac1 100644 (file)
@@ -1,8 +1,6 @@
 Currently known (or at least suspected) bugs in parport:
 
-o /proc/parport is buggy under 2.0.29 (ls /proc/parport/0 gives no such
-  file or directory).  David has suggested a fix for this.  [/proc/parport
-  has been temporarily taken out]
+o /proc/parport is untested under 2.0.XX
 
 o SCSI aborts for PPA under 2.0.29 [reported by jmr].  Under investigation.
 
index c224c9889c306df73a3d9527f194d789fb931472..6153b8da657add9fcce23c33d9b26ba9127c752b 100644 (file)
@@ -23,14 +23,20 @@ MI_OBJS  :=
 MIX_OBJS :=
 
 ifeq ($(CONFIG_PNP_PARPORT),y)
-  L_OBJS += parport_share.o parport_procfs.o
+  L_OBJS += parport_share.o
+  ifeq ($(CONFIG_PROC_FS),y)
+    L_OBJS += parport_procfs.o
+  endif
   ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y)
     L_OBJS += parport_probe.o
   endif
   LX_OBJS += parport_init.o
 else
   ifeq ($(CONFIG_PNP_PARPORT),m)
-    MI_OBJS += parport_share.o parport_procfs.o
+    MI_OBJS += parport_share.o
+    ifneq ($(CONFIG_PROC_FS),n) 
+      MI_OBJS += parport_procfs.o
+    endif
     ifeq ($(CONFIG_PNP_PARPORT_AUTOPROBE),y)
       MI_OBJS += parport_probe.o
     endif
index cd99017d8c451f77d3da0b9b2c21427c2e56e17d..eea6a01fd2088697c51c7a6117578dd6ba4c53eb 100644 (file)
@@ -2,31 +2,9 @@ Things to be done.
 
 0. Fix the bugs (see BUGS-parport).
 
-1. Write a /proc interface for parport.  As a starting point, we could
-   probably have something like this:
+1. Proper documentation.
 
-   /proc/parport/N/hardware
-
-        Details of the port hardware - chipset, capabilities and so on.
-        Read-only.
-
-   /proc/parport/N/irq
-
-        IRQ number of the port.  Read-write.
-
-   /proc/parport/N/devices
-
-        List of devices connected to this bus, with the currently active
-        one marked in some way.  Probably you'd have the device in the
-        first column, and '*' (for the current device) or '-' (for a
-        lurker) in the second column.
-
-   NOTE: The directory structure has been coded -- but the files are
-         missing ...
-
-2. Proper documentation.
-
-3. Overhaul lp.c:
+2. Overhaul lp.c:
 
    a) It's a mess, and there is a lot of code duplication.
 
@@ -40,4 +18,4 @@ Things to be done.
       bits when they have something to say.  We should read out and deal 
       with (maybe just log) whatever the printer wants to tell the world.
 
-4. Assimilate more drivers.
+3. Assimilate more drivers.
index 76dfe9cda648a847fae296812ba599b2f6a201f4..672d2d86ea88921e5db79be346342c440f7a25a5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_init.c,v 1.1.2.4 1997/04/01 18:19:10 phil Exp $
+/* $Id: parport_init.c,v 1.3.2.4 1997/04/16 21:20:44 phil Exp $
  * Parallel-port initialisation code.
  * 
  * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
@@ -26,8 +26,8 @@
 #include "parport_ll_io.h"
 
 static int io[PARPORT_MAX] = { 0, };
-static int irq[PARPORT_MAX] = { -1, };
-static int dma[PARPORT_MAX] = { -1, };
+static int irq[PARPORT_MAX] = { PARPORT_IRQ_NONE, };
+static int dma[PARPORT_MAX] = { PARPORT_DMA_NONE, };
 
 /******************************************************
  *  DMA detection section:
@@ -76,7 +76,7 @@ static int parport_enable_dma(int dma)
        return dma;
 }
 
-static int parport_detect_dma_transfer(int dma,int size)
+static int parport_detect_dma_transfer(int dma,int size,int *resid)
 {
        int i,n,retv;
        int count=0;
@@ -88,10 +88,11 @@ static int parport_detect_dma_transfer(int dma,int size)
                        clear_dma_ff(i);
                        n = get_dma_residue(i);
                        if (n != size) {
+                               *resid = n;
                                retv = i;
                                if (count > 0) {
                                        retv = -1;      /* Multiple DMA's */
-                                       printk("Multiple DMA detected.\n");
+                                       printk(KERN_ERR "parport: multiple DMA detected.  Huh?\n");
                                }
                                count++;
                        }
@@ -118,7 +119,7 @@ static int programmable_dma_support(struct parport *pb)
                return dma;
 }
 
-/* Only called if port support ECP mode.
+/* Only called if port supports ECP mode.
  *
  * The only restriction on DMA channels is that it has to be
  * between 0 to 7 (inclusive). Used only in an ECP mode, DMAs are
@@ -146,12 +147,11 @@ static int parport_dma_probe(struct parport *pb)
        char *buff;
 
        retv = programmable_dma_support(pb);
-       if( retv != -1 )
+       if (retv != -1)
                return retv;
        
-       buff = kmalloc(16, GFP_KERNEL | GFP_DMA);
-       if( !buff ){
-           printk("parport: memory squezze\n");
+       if (!(buff = kmalloc(2048, GFP_KERNEL | GFP_DMA))) {
+           printk(KERN_ERR "parport: memory squeeze\n");
            return -1;
        }
        
@@ -160,24 +160,26 @@ static int parport_dma_probe(struct parport *pb)
 
        w_ecr(pb, 0xc0);           /* ECP MODE */
        w_ctr(pb, dsr_read );
-       dma=parport_prepare_dma(buff,8);
+       dma=parport_prepare_dma(buff,1000);
        w_ecr(pb, 0xd8);           /* ECP FIFO + enable DMA */
        parport_enable_dma(dma);
-       udelay(30);           /* Give some for DMA tranfer */
-       retv = parport_detect_dma_transfer(dma,8);
+       udelay(500);           /* Give some for DMA tranfer */
+       retv = parport_detect_dma_transfer(dma,1000,&pb->speed);
+       pb->speed = pb->speed * 2000;  /* 500uSec * 2000 = 1sec */
        
        /*
         * National Semiconductors only supports DMA tranfers
         * in ECP MODE
         */
-       if( retv == -1 ){
+       if (retv == -1) {
                w_ecr(pb, 0x60);           /* ECP MODE */
                w_ctr(pb, dsr_read );
-               dma=parport_prepare_dma(buff,8);
+               dma=parport_prepare_dma(buff,1000);
                w_ecr(pb, 0x68);           /* ECP FIFO + enable DMA */
                parport_enable_dma(dma);
-               udelay(30);           /* Give some for DMA tranfer */
-               retv = parport_detect_dma_transfer(dma,8);
+               udelay(500);           /* Give some for DMA tranfer */
+               retv = parport_detect_dma_transfer(dma,1000,&pb->speed);
+               pb->speed = pb->speed * 2000;  /* 500uSec * 2000 = 1sec */
        }
        
        kfree(buff);
@@ -198,10 +200,10 @@ static int epp_clear_timeout(struct parport *pb)
 {
        int r;
 
-    if( !(r_str(pb) & 0x01) )
+       if (!(r_str(pb) & 0x01))
                return 1;
 
-       /* To clear timeout some chip requiere double read */
+       /* To clear timeout some chips require double read */
        r_str(pb);
        r = r_str(pb);
        w_str(pb, r | 0x01); /* Some reset by writing 1 */
@@ -213,23 +215,18 @@ static int epp_clear_timeout(struct parport *pb)
 
 
 /*
- * Checks for por existence, all ports support SPP MODE
+ * Checks for port existence, all ports support SPP MODE
  */
 static int parport_SPP_supported(struct parport *pb)
 {
-       int r,rr;
-       
        /* Do a simple read-write test to make sure the port exists. */
+
        w_dtr(pb, 0xaa);
-       r = r_dtr(pb);
+       if (r_dtr(pb) != 0xaa) return 0;
        
        w_dtr(pb, 0x55);
-       rr = r_dtr(pb);
-       
-       if (r != 0xaa || rr != 0x55) {
-               return 0;
-       }
-       
+       if (r_dtr(pb) != 0x55) return 0;
+
        return PARPORT_MODE_SPP;
 }
 
@@ -249,23 +246,20 @@ static int parport_ECR_present(struct parport *pb)
 {
        int r;
 
-       if( pb->base == 0x3BC )
-               return 0;
-       
        r= r_ctr(pb);   
-       if( (r_ecr(pb) & 0x03) == (r & 0x03) ){
+       if ((r_ecr(pb) & 0x03) == (r & 0x03)) {
                w_ctr(pb, r ^ 0x03 ); /* Toggle bits 0-1 */
 
                r= r_ctr(pb);   
-               if( (r_ecr(pb) & 0x03) == (r & 0x03) )
+               if ((r_ecr(pb) & 0x03) == (r & 0x03))
                        return 0; /* Sure that no ECR register exists */
        }
        
-       if( (r_ecr(pb) & 0x03 ) != 0x01 )
+       if ((r_ecr(pb) & 0x03 ) != 0x01)
                return 0;
 
        w_ecr(pb,0x34);
-       if( r_ecr(pb) != 0x35 )
+       if (r_ecr(pb) != 0x35)
                return 0;
 
        w_ecr(pb,pb->ecr);
@@ -278,20 +272,22 @@ static int parport_ECP_supported(struct parport *pb)
 {
        int i;
        
-       if( !(pb->modes & PARPORT_MODE_ECR) )
+       /* If there is no ECR, we have no hope of supporting ECP. */
+       if (!(pb->modes & PARPORT_MODE_ECR))
                return 0;
+
        /*
-        * Usign LGS chipset it uses ECR register, but
+        * Using LGS chipset it uses ECR register, but
         * it doesn't support ECP or FIFO MODE
         */
        
-       w_ecr(pb,0xc0); /* TEST FIFO */
-       for( i=0 ; i < 1024 && (r_ecr(pb) & 0x01) ; i++ )
+       w_ecr(pb, 0xc0); /* TEST FIFO */
+       for (i=0; i < 1024 && (r_ecr(pb) & 0x01); i++)
                w_fifo(pb, 0xaa);
 
-       w_ecr(pb,pb->ecr);
+       w_ecr(pb, pb->ecr);
 
-       if( i >= 1024 )
+       if (i == 1024)
                return 0;
        
        return PARPORT_MODE_ECP;
@@ -311,11 +307,8 @@ static int parport_ECP_supported(struct parport *pb)
  */
 static int parport_EPP_supported(struct parport *pb)
 {
-       if( pb->base == 0x3BC )
-               return 0;
-
        /* If EPP timeout bit clear then EPP available */
-       if( !epp_clear_timeout(pb) )
+       if (!epp_clear_timeout(pb))
                return 0;  /* No way to clear timeout */
 
        w_ctr(pb, r_ctr(pb) | 0x20);
@@ -325,7 +318,7 @@ static int parport_EPP_supported(struct parport *pb)
        r_epp(pb);
        udelay(30);  /* Wait for possible EPP timeout */
        
-       if( r_str(pb) & 0x01 ){
+       if (r_str(pb) & 0x01) {
                epp_clear_timeout(pb);
                return PARPORT_MODE_EPP;
        }
@@ -337,7 +330,7 @@ static int parport_ECPEPP_supported(struct parport *pb)
 {
        int mode;
 
-       if( !(pb->modes & PARPORT_MODE_ECR) )
+       if (!(pb->modes & PARPORT_MODE_ECR))
                return 0;
        
        /* Search for SMC style EPP+ECP mode */
@@ -345,47 +338,55 @@ static int parport_ECPEPP_supported(struct parport *pb)
        
        mode = parport_EPP_supported(pb);
 
-       w_ecr(pb,pb->ecr);
+       w_ecr(pb, pb->ecr);
        
-       if( mode )
+       if (mode)
                return PARPORT_MODE_ECPEPP;
        
        return 0;
 }
 
-/* Detect LP_PS2 support
- * Bit 5 (0x20) sets the PS/2 data direction, setting this high
- * allows us to read data from the data lines, old style SPP ports
- * will return 0xff.  This may not be reliable if there is a
- * peripheral attached to the port. 
+/* Detect PS/2 support.
+ *
+ * Bit 5 (0x20) sets the PS/2 data direction; setting this high
+ * allows us to read data from the data lines.  In theory we would get back
+ * 0xff but any peripheral attached to the port may drag some or all of the
+ * lines down to zero.  So if we get back anything that isn't the contents
+ * of the data register we deem PS/2 support to be present. 
+ *
+ * Some SPP ports have "half PS/2" ability - you can't turn off the line
+ * drivers, but an external peripheral with sufficiently beefy drivers of
+ * its own can overpower them and assert its own levels onto the bus, from
+ * where they can then be read back as normal.  Ports with this property
+ * and the right type of device attached are likely to fail the SPP test,
+ * (as they will appear to have stuck bits) and so the fact that they might
+ * be misdetected here is rather academic. 
  */
+
 static int parport_PS2_supported(struct parport *pb)
 {
-       int r,rr;
-
+       int ok = 0;
+  
        epp_clear_timeout(pb);
 
-       w_ctr(pb, pb->ctr | 0x20);      /* Tri-state the buffer */
+       w_ctr(pb, pb->ctr | 0x20);   /* try to tri-state the buffer */
        
-       w_dtr(pb, 0xAA);
-       r = r_dtr(pb);
-
        w_dtr(pb, 0x55);
-       rr = r_dtr(pb);
-       
-       w_ctr(pb, pb->ctr);     /* Reset CTR register */
+       if (r_dtr(pb) != 0x55) ok++;
 
-       if (r != 0xAA || rr != 0x55 )
-               return PARPORT_MODE_PS2;
+       w_dtr(pb, 0xaa);
+       if (r_dtr(pb) != 0xaa) ok++;
        
-       return 0;
+       w_ctr(pb, pb->ctr);          /* cancel input mode */
+
+       return ok?PARPORT_MODE_PS2:0;
 }
 
 static int parport_ECPPS2_supported(struct parport *pb)
 {
        int mode;
 
-       if( !(pb->modes & PARPORT_MODE_ECR) )
+       if (!(pb->modes & PARPORT_MODE_ECR))
                return 0;
        
        w_ecr(pb, 0x20);
@@ -402,15 +403,19 @@ static int parport_ECPPS2_supported(struct parport *pb)
 
 /******************************************************
  *  IRQ detection section:
- */
-/*
+ *
  * This code is for detecting ECP interrupts (due to problems with the
  * monolithic interrupt probing routines).
  *
  * In short this is a voting system where the interrupt with the most
  * "votes" is the elected interrupt (it SHOULD work...)
+ *
+ * This is horribly x86-specific at the moment.  I'm not convinced it
+ * belongs at all.
  */
+
 static int intr_vote[16];
+
 static void parport_vote_intr_func(int irq, void *dev_id, struct pt_regs *regs)
 {
        intr_vote[irq]++;
@@ -434,17 +439,16 @@ static long open_intr_election(void)
 
 static int close_intr_election(long tmp)
 {
-       long max_vote = 0;
-       int irq = -1;
+       int irq = PARPORT_IRQ_NONE;
        int i;
 
        /* We ignore the timer - irq 0 */
        for (i = 1; i < 16; i++)
                if (tmp & (1 << i)) {
-                       if (intr_vote[i] > max_vote) {
-                               if (max_vote)
-                                       return -1;
-                               max_vote = intr_vote[i];
+                       if (intr_vote[i]) {
+                               if (irq != PARPORT_IRQ_NONE)
+                                       /* More than one interrupt */
+                                       return PARPORT_IRQ_NONE;
                                irq = i;
                        }
                        free_irq(i, intr_vote);
@@ -488,7 +492,7 @@ static int irq_probe_ECP(struct parport *pb)
        irqs = open_intr_election();
                
        w_ecr(pb, 0x00);            /* Reset FIFO */
-       w_ctr(pb, pb->ctr );    /* Force direction = 0 */
+       w_ctr(pb, pb->ctr );        /* Force direction = 0 */
        w_ecr(pb, 0xd0);            /* TEST FIFO + nErrIntrEn */
 
        /* If Full FIFO sure that WriteIntrThresold is generated */
@@ -497,8 +501,6 @@ static int irq_probe_ECP(struct parport *pb)
        }
                
        pb->irq = close_intr_election(irqs);
-       if (pb->irq == 0)
-               pb->irq = -1;   /* No interrupt detected */
        
        w_ecr(pb, pb->ecr);
 
@@ -506,7 +508,7 @@ static int irq_probe_ECP(struct parport *pb)
 }
 
 /*
- * It's called only if supports EPP on National Semiconductors
+ * This detection seems that only works in National Semiconductors
  * This doesn't work in SMC, LGS, and Winbond 
  */
 static int irq_probe_EPP(struct parport *pb)
@@ -535,8 +537,6 @@ static int irq_probe_EPP(struct parport *pb)
        udelay(20);
 
        pb->irq = close_intr_election(irqs);
-       if (pb->irq == 0)
-               pb->irq = -1;   /* No interrupt detected */
        
        w_ctr(pb,pb->ctr);
        
@@ -572,7 +572,7 @@ static int irq_probe_SPP(struct parport *pb)
 
        pb->irq = probe_irq_off(irqs);
        if (pb->irq <= 0)
-               pb->irq = -1;   /* No interrupt detected */
+               pb->irq = PARPORT_IRQ_NONE;     /* No interrupt detected */
        
        w_ctr(pb,pb->ctr);
        
@@ -583,18 +583,18 @@ static int irq_probe_SPP(struct parport *pb)
  * such as sound cards and network cards seem to like using the
  * printer IRQs.
  *
- * When LP_ECP is available we can autoprobe for IRQs.
+ * When ECP is available we can autoprobe for IRQs.
  * NOTE: If we can autoprobe it, we can register the IRQ.
  */
 static int parport_irq_probe(struct parport *pb)
 {
-       if( pb->modes & PARPORT_MODE_ECR )
+       if (pb->modes & PARPORT_MODE_ECR)
                pb->irq = programmable_irq_support(pb);
 
-       if( pb->modes & PARPORT_MODE_ECP )
+       if (pb->modes & PARPORT_MODE_ECP)
                pb->irq = irq_probe_ECP(pb);
                        
-       if( pb->irq == -1 && (pb->modes & PARPORT_MODE_ECPEPP)){
+       if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_ECPEPP)) {
                w_ecr(pb,0x80);
                pb->irq = irq_probe_EPP(pb);
                w_ecr(pb,pb->ecr);
@@ -602,12 +602,12 @@ static int parport_irq_probe(struct parport *pb)
 
        epp_clear_timeout(pb);
 
-       if( pb->irq == -1 && (pb->modes & PARPORT_MODE_EPP))
+       if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP))
                pb->irq = irq_probe_EPP(pb);
 
        epp_clear_timeout(pb);
 
-       if( pb->irq == -1 )
+       if (pb->irq == PARPORT_IRQ_NONE)
                pb->irq = irq_probe_SPP(pb);
 
        return pb->irq;
@@ -618,12 +618,12 @@ int initialize_parport(struct parport *pb, unsigned long base, int irq, int dma,
 {
        /* Check some parameters */
        if (dma < -2) {
-               printk("parport: Invalid DMA[%d] at base 0x%lx\n",dma,base);
+               printk(KERN_ERR "parport: Invalid DMA[%d] at base 0x%lx\n",dma,base);
                return 0;
        }
 
        if (irq < -2) {
-               printk("parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base);
+               printk(KERN_ERR "parport: Invalid IRQ[%d] at base 0x%lx\n",irq,base);
                return 0;
        }
        
@@ -643,7 +643,7 @@ int initialize_parport(struct parport *pb, unsigned long base, int irq, int dma,
 
        pb->name = kmalloc(15, GFP_KERNEL);
        if (!pb->name) {
-               printk("parport: memory squeeze\n");
+               printk(KERN_ERR "parport: memory squeeze\n");
                return 0;
        }
        sprintf(pb->name, "parport%d", count);
@@ -657,12 +657,15 @@ int initialize_parport(struct parport *pb, unsigned long base, int irq, int dma,
        }
 
        pb->modes |= PARPORT_MODE_SPP;  /* All ports support SPP mode. */
-       pb->modes |= parport_ECR_present(pb);   
-       pb->modes |= parport_ECP_supported(pb);
        pb->modes |= parport_PS2_supported(pb);
-       pb->modes |= parport_ECPPS2_supported(pb);
-       pb->modes |= parport_EPP_supported(pb);
-       pb->modes |= parport_ECPEPP_supported(pb);
+
+       if (pb->base != 0x3bc) {
+               pb->modes |= parport_ECR_present(pb);   
+               pb->modes |= parport_ECP_supported(pb);
+               pb->modes |= parport_ECPPS2_supported(pb);
+               pb->modes |= parport_EPP_supported(pb);
+               pb->modes |= parport_ECPEPP_supported(pb);
+       }
 
        /* Now register regions */
        if ((pb->modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) && 
@@ -678,17 +681,17 @@ int initialize_parport(struct parport *pb, unsigned long base, int irq, int dma,
 
        /* DMA check */
        if (pb->modes & PARPORT_MODE_ECP) {
-               if (pb->dma == -1)
+               if (pb->dma == PARPORT_DMA_NONE)
                        pb->dma = parport_dma_probe(pb);
                else if (pb->dma == -2)
-                       pb->dma = -1;
+                       pb->dma = PARPORT_DMA_NONE;
        }
 
        /* IRQ check */
-       if (pb->irq == -1)
+       if (pb->irq == PARPORT_IRQ_NONE)
                pb->irq = parport_irq_probe(pb);
        else if (pb->irq == -2)
-               pb->irq = -1;
+               pb->irq = PARPORT_IRQ_NONE;
 
        return 1;
 }
@@ -700,7 +703,7 @@ void parport_setup(char *str, int *ints)
 {
        if (ints[0] == 0 || ints[1] == 0) {
                /* Disable parport if "parport=" or "parport=0" in cmdline */
-               io[0] = -2
+               io[0] = PARPORT_DISABLE
                return;
        }
        if (parport_setup_ptr < PARPORT_MAX) {
@@ -738,17 +741,20 @@ int pnp_parport_init(void)
        struct parport *pb;
 
        printk(KERN_INFO "Parallel port sharing: %s\n",
-              "$Revision: 1.1.2.4 $");
+              "$Revision: 1.3.2.4 $");
 
-       if (io[0] == -2) return 1; 
+       if (io[0] == PARPORT_DISABLE) return 1; 
 
-       /* Register /proc/parport */
+#ifdef CONFIG_PROC_FS
        parport_proc_register(NULL);
+#endif
 
        /* Run probes to ensure parport does exist */
 #define PORT(a,b,c) \
                if ((pb = parport_register_port((a), (b), (c))))  \
                        parport_destroy(pb); 
+
+
        if (io[0]) {
                /* If the user specified any ports, use them */
                int i;
@@ -757,16 +763,22 @@ int pnp_parport_init(void)
                }
        } else {
                /* Go for the standard ports. */
-               PORT(0x378, -1, -1);
-               PORT(0x278, -1, -1);
-               PORT(0x3bc, -1, -1);
+               PORT(0x378, PARPORT_IRQ_NONE, PARPORT_DMA_NONE);
+               PORT(0x278, PARPORT_IRQ_NONE, PARPORT_DMA_NONE);
+               PORT(0x3bc, PARPORT_IRQ_NONE, PARPORT_DMA_NONE);
 #undef PORT
        }
 
+#if defined(CONFIG_PNP_PARPORT_AUTOPROBE) || defined(CONFIG_PROC_FS)
+       for (pb = parport_enumerate(); pb; pb = pb->next) {
 #ifdef CONFIG_PNP_PARPORT_AUTOPROBE
-       for (pb = parport_enumerate(); pb; pb = pb->next)
                parport_probe_one(pb);
 #endif
+#ifdef CONFIG_PROC_FS
+               parport_proc_register(pb);
+#endif
+       }
+#endif
 
        return 0;
 }
@@ -784,7 +796,7 @@ void cleanup_module(void)
                kfree(port);
        }
        
-       parport_proc_unregister(NULL);
+       parport_proc_cleanup();
 }
 #endif
 
index c26562bf93eae905bd7241726bf7468b167adb8f..896abbdd4a88f6162ab553bafa9647072cfb4aef 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_procfs.c,v 1.1.2.2 1997/03/26 17:50:36 phil Exp $
+/* $Id: parport_procfs.c,v 1.3.2.6 1997/04/16 21:30:38 phil Exp $
  * Parallel port /proc interface code.
  * 
  * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
 #include <linux/kernel.h>
 #include <linux/malloc.h>
 
-#ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
-#endif
 
 #include <linux/parport.h>
+#include "parport_ll_io.h"
+
+#undef PARPORT_INCLUDE_BENCH
+
+struct proc_dir_entry *base=NULL;
 
-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
+void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs);
 
-/************************************************/
-static long proc_readparport(struct inode * inode, struct file * file,
-                                                        char * buf, unsigned long count)
+static int irq_write_proc(struct file *file, const char *buffer,
+                                         unsigned long count, void *data)
 {
-       printk("proc_readparport\n");
-       return 0;
+       int newirq;
+       struct parport *pp = (struct parport *)data;
+       
+       if (count > 4 )  /* more than 4 digits for a irq 0x?? 0?? ??  */
+               return(-EOVERFLOW);
+
+       if (buffer[0] < 32 || !strncmp(buffer, "none", 4)) {
+               newirq = PARPORT_IRQ_NONE;
+       } else {
+               if (buffer[0] == '0') {
+                       if( buffer[1] == 'x' )
+                               newirq = simple_strtoul(&buffer[2],0,16);
+                       else
+                               newirq = simple_strtoul(&buffer[1],0,8);
+               } else {
+                       newirq = simple_strtoul(buffer,0,10);
+               }
+       }
+
+       if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) 
+               free_irq(pp->irq, pp);
+
+       pp->irq = newirq;
+
+       if (pp->irq != PARPORT_IRQ_NONE && !(pp->flags & PARPORT_FLAG_COMA)) { 
+               struct ppd *pd = pp->cad;
+
+               if (pd == NULL) {
+                       pd = pp->devices;
+                       if (pd != NULL) 
+                               request_irq(pp->irq, pd->irq_func ? 
+                                           pd->irq_func :
+                                           parport_null_intr_func,
+                                           SA_INTERRUPT, pd->name, pd->port);
+               } else {
+                       request_irq(pp->irq, pd->irq_func ? pd->irq_func :
+                                   parport_null_intr_func,
+                                   SA_INTERRUPT, pp->name, pd->port);
+               }
+       }
+
+       return count;
 }
 
-static long proc_writeparport(struct inode * inode, struct file * file,
-                                                         const char * buf, unsigned long count)
+static int irq_read_proc(char *page, char **start, off_t off,
+                                        int count, int *eof, void *data)
 {
-       printk("proc_writeparport\n");
+       struct parport *pp = (struct parport *)data;
+       int len;
        
-       return 0;
+       if (pp->irq == PARPORT_IRQ_NONE)
+               len = sprintf(page, "none\n");
+       else
+               len = sprintf(page, "%d\n", pp->irq);
+       
+       *start = 0;
+       *eof   = 1;
+       return len;
 }
 
-static long long proc_parportlseek(struct inode * inode, struct file * file, 
-                               long long offset, int orig)
+static int devices_read_proc(char *page, char **start, off_t off,
+                                        int count, int *eof, void *data)
 {
-    switch (orig) {
-    case 0:
-       file->f_pos = offset;
-       return(file->f_pos);
-    case 1:
-       file->f_pos += offset;
-       return(file->f_pos);
-    case 2:
-       return(-EINVAL);
-    default:
-       return(-EINVAL);
-    }
+       struct parport *pp = (struct parport *)data;
+       struct ppd *pd1;
+       int len=0;
+
+       for (pd1 = pp->devices; pd1 ; pd1 = pd1->next) {
+               if (pd1 == pp->cad)
+                       len += sprintf(page+len, "+");
+               else
+                       len += sprintf(page+len, " ");
+
+               len += sprintf(page+len, "%s",pd1->name);
+
+               if (pd1 == pp->lurker)
+                       len += sprintf(page+len, " LURK");
+               
+               len += sprintf(page+len,"\n");
+       }
+               
+       *start = 0;
+       *eof   = 1;
+       return len;
 }
 
-static struct file_operations proc_dir_operations = {
-    proc_parportlseek, /* lseek   */
-    proc_readparport,  /* read    */
-    proc_writeparport, /* write   */
-    proc_readdir,          /* readdir */
-    NULL,              /* poll    */
-    NULL,              /* ioctl   */
-    NULL,              /* mmap    */
-    NULL,              /* no special open code    */
-    NULL,              /* no special release code */
-    NULL               /* can't fsync */
-};
-
-/************************************************/
-static struct inode_operations parport_proc_dir_inode_operations = {
-       &proc_dir_operations,   /* default net directory file-ops */
-       NULL,                   /* create */
-       proc_lookup,    /* lookup */
-       NULL,                   /* link */
-       NULL,                   /* unlink */
-       NULL,                   /* symlink */
-       NULL,                   /* mkdir */
-       NULL,                   /* rmdir */
-       NULL,                   /* mknod */
-       NULL,                   /* rename */
-       NULL,                   /* readlink */
-       NULL,                   /* follow_link */
-       NULL,                   /* readpage */
-       NULL,                   /* writepage */
-       NULL,                   /* bmap */
-       NULL,                   /* truncate */
-       NULL                    /* permission */
-};
-
-static struct proc_dir_entry proc_root_parport = {
-       PROC_PARPORT, 7, "parport",
-       S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
-       0, &parport_proc_dir_inode_operations,
-       NULL, NULL,
-       NULL, &proc_root, NULL,
-       NULL, NULL
-};
+static int hardware_read_proc(char *page, char **start, off_t off,
+                                                         int count, int *eof, void *data)
+{
+       struct parport *pp = (struct parport *)data;
+       int len=0;
+       
+       len += sprintf(page+len, "base:\t0x%x\n",pp->base);
+       if (pp->irq == PARPORT_IRQ_NONE)
+               len += sprintf(page+len, "irq:\tnone\n");
+       else
+               len += sprintf(page+len, "irq:\t%d\n",pp->irq);
+       len += sprintf(page+len, "dma:\t%d\n",pp->dma);
+
+       len += sprintf(page+len, "modes:\t");
+       {
+#define printmode(x) {if(pp->modes&PARPORT_MODE_##x){len+=sprintf(page+len,"%s%s",f?",":"",#x);f++;}}
+               int f = 0;
+               printmode(SPP);
+               printmode(PS2);
+               printmode(EPP);
+               printmode(ECP);
+               printmode(ECPEPP);
+               printmode(ECPPS2);
+#undef printmode
+       }
+       len += sprintf(page+len, "\n");
+
+       len += sprintf(page+len, "mode:\t");
+       if (pp->modes & PARPORT_MODE_ECR) {
+               switch (r_ecr(pp) >> 5) {
+               case 0:
+                       len += sprintf(page+len, "SPP");
+                       if( pp->modes & PARPORT_MODE_PS2 )
+                               len += sprintf(page+len, ",PS2");
+                       if( pp->modes & PARPORT_MODE_EPP )
+                               len += sprintf(page+len, ",EPP");
+                       break;
+               case 1:
+                       len += sprintf(page+len, "ECPPS2");
+                       break;
+               case 2:
+                       len += sprintf(page+len, "DATAFIFO");
+                       break;
+               case 3:
+                       len += sprintf(page+len, "ECP");
+                       break;
+               case 4:
+                       len += sprintf(page+len, "ECPEPP");
+                       break;
+               case 5:
+                       len += sprintf(page+len, "Reserved?");
+                       break;
+               case 6:
+                       len += sprintf(page+len, "TEST");
+                       break;
+               case 7:
+                       len += sprintf(page+len, "Configuration");
+                       break;
+               }
+       } else {
+               len += sprintf(page+len, "SPP");
+               if (pp->modes & PARPORT_MODE_PS2)
+                       len += sprintf(page+len, ",PS2");
+               if (pp->modes & PARPORT_MODE_EPP)
+                       len += sprintf(page+len, ",EPP");
+       }
+       len += sprintf(page+len, "\n");
+       
+#if 0
+       /* Now no detection, please fix with an external function */
+       len += sprintf(page+len, "chipset:\tunknown\n");
 #endif
+#ifdef PARPORT_INCLUDE_BENCHMARK
+       if (pp->speed)
+               len += sprintf(page+len, "bench:\t%d Bytes/s\n",pp->speed);
+       else
+               len += sprintf(page+len, "bench:\tunknown\n");
+#endif 
+
+       *start = 0;
+       *eof   = 1;
+       return len;
+}
+
+static struct proc_dir_entry *new_proc_entry(const char *name, mode_t mode,
+                                            struct proc_dir_entry *parent,
+                                            unsigned short ino)
+{
+       struct proc_dir_entry *ent;
+
+       ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+       if (!ent)
+               return NULL;
+       memset(ent, 0, sizeof(struct proc_dir_entry));
+       
+       if (mode == S_IFDIR)
+               mode |= S_IRUGO | S_IXUGO;
+       else if (mode == 0)
+               mode = S_IFREG | S_IRUGO;
+
+
+       ent->low_ino = ino;
+       ent->name = name;
+       ent->namelen = strlen(name);
+       ent->mode = mode;
+       if (S_ISDIR(mode)) 
+               ent->nlink = 2;
+       else
+               ent->nlink = 1;
+
+       proc_register(parent, ent);
+       
+       return ent;
+}
+
+
+int parport_proc_init()
+{
+       base = new_proc_entry("parport", S_IFDIR, &proc_root,PROC_PARPORT);
+
+       if (base)
+               return 1;
+       else {
+               printk(KERN_ERR "parport: Error creating proc entry /proc/parport\n");
+               return 0;
+       }
+}
+
+int parport_proc_cleanup()
+{
+       if (base)
+               proc_unregister(&proc_root,base->low_ino);
+
+       base = NULL;
+       
+       return 0;
+}
 
 int parport_proc_register(struct parport *pp)
 {
-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
-       return proc_register(&proc_root, &proc_root_parport);
-#else
+       struct proc_dir_entry *ent;
+       static int conta=0;
+       char *name;
+
+       memset(&pp->pdir,0,sizeof(struct parport_dir));
+
+       if (!base) {
+               printk(KERN_ERR "parport: Error entry /proc/parport, not generated?\n");
+               return 1;
+       }
+       
+       name = pp->pdir.name;
+       sprintf(name,"%d",conta++);
+
+       ent = new_proc_entry(name, S_IFDIR, base,0);
+       if (!ent) {
+               printk(KERN_ERR "parport: Error registering proc_entry /proc/%s\n",name);
+               return 1;
+       }
+       pp->pdir.entry = ent;
+
+       ent = new_proc_entry("irq", S_IFREG | S_IRUGO | S_IWUSR, pp->pdir.entry,0);
+       if (!ent) {
+               printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/irq\n",name);
+               return 1;
+       }
+       ent->read_proc = irq_read_proc;
+       ent->write_proc= irq_write_proc;
+       ent->data      = pp;
+       pp->pdir.irq   = ent;
+       
+       ent = new_proc_entry("devices", 0, pp->pdir.entry,0);
+       if (!ent) {
+               printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/devices\n",name);
+               return 1;
+       }
+       ent->read_proc   = devices_read_proc;
+       ent->data        = pp;
+       pp->pdir.devices = ent;
+       
+       ent = new_proc_entry("hardware", 0, pp->pdir.entry,0);
+       if (!ent) {
+               printk(KERN_ERR "parport: Error registering proc_entry /proc/%s/hardware\n",name);
+               return 1;
+       }
+       ent->read_proc    = hardware_read_proc;
+       ent->data         = pp;
+       pp->pdir.hardware = ent;
        return 0;
-#endif
 }
 
-void parport_proc_unregister(struct parport *pp)
+int parport_proc_unregister(struct parport *pp)
 {
-#if defined(CONFIG_PROC_FS) && defined(NOT_DEFINED)
-       if( pp ){
-               proc_unregister(&proc_root_parport, pp->proc_dir->low_ino);
-               kfree(pp->proc_dir);
-       }else{
-               proc_unregister(&proc_root, proc_root_parport.low_ino);
+       if (pp->pdir.entry) {
+               if (pp->pdir.irq) {
+                       proc_unregister(pp->pdir.entry, pp->pdir.irq->low_ino);
+                       kfree(pp->pdir.irq);
+               }
+               
+               if (pp->pdir.devices) {
+                       proc_unregister(pp->pdir.entry,
+                                       pp->pdir.devices->low_ino);
+                       kfree(pp->pdir.devices);
+               }
+               
+               if (pp->pdir.hardware) {
+                       proc_unregister(pp->pdir.entry,
+                                       pp->pdir.hardware->low_ino);
+                       kfree(pp->pdir.hardware);
+               }
+               
+               proc_unregister(base, pp->pdir.entry->low_ino);
+               kfree(pp->pdir.entry);
        }
-#endif
+       
+       return 0;
 }
index 4294c6d808a51cc03ad895487e18e78ff54c19f0..fc19fffd411f2a5692fdb9609184ad2eb28bf788 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: parport_share.c,v 1.1.2.4 1997/04/01 18:19:11 phil Exp $
+/* $Id: parport_share.c,v 1.3.2.5 1997/04/16 21:20:44 phil Exp $
  * Parallel-port resource manager code.
  * 
  * Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
@@ -21,6 +21,8 @@
 #include <linux/kernel.h>
 #include <linux/malloc.h>
 
+#undef PARPORT_PARANOID
+
 #include "parport_ll_io.h"
 
 static struct parport *portlist = NULL, *portlist_tail = NULL;
@@ -36,7 +38,7 @@ struct parport *parport_enumerate(void)
        return portlist;
 }
 
-static void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
+void parport_null_intr_func(int irq, void *dev_id, struct pt_regs *regs)
 {
        /* NULL function - Does nothing */
        return;
@@ -85,7 +87,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma)
        }
        memcpy(tmp, &new, sizeof(struct parport));
 
-       if (new.irq != -1) {
+       if (new.irq != PARPORT_IRQ_NONE) {
                if (request_irq(new.irq, parport_null_intr_func,
                          SA_INTERRUPT, new.name, tmp) != 0) {
                        printk(KERN_INFO "%s: unable to claim IRQ %d\n", 
@@ -197,11 +199,10 @@ struct ppd *parport_register_device(struct parport *port, const char *name,
                                return NULL;
                        }
                }
-               if (port->irq != -1) {
-                       if (request_irq(port->irq, 
-                                                       parport_null_intr_func,
-                                                       SA_INTERRUPT, port->name,
-                                                       port) != 0) {
+               if (port->irq != PARPORT_IRQ_NONE) {
+                       if (request_irq(port->irq, parport_null_intr_func,
+                                       SA_INTERRUPT, port->name,
+                                       port) != 0) {
                                release_region(port->base, port->size);
                                if( port->modes & PARPORT_MODE_ECR )
                                        release_region(port->base+0x400, 3);
@@ -213,7 +214,6 @@ struct ppd *parport_register_device(struct parport *port, const char *name,
                port->flags &= ~PARPORT_FLAG_COMA;
        }
 
-
        tmp = kmalloc(sizeof(struct ppd), GFP_KERNEL);
        tmp->name = (char *) name;
        tmp->port = port;
@@ -251,8 +251,7 @@ void parport_unregister_device(struct ppd *dev)
        port = dev->port;
 
        if (port->cad == dev) {
-               printk(KERN_INFO "%s: refused to unregister currently active device %s\n",
-                          port->name, dev->name);
+               printk(KERN_INFO "%s: refused to unregister currently active device %s\n", port->name, dev->name);
                return;
        }
 
@@ -299,8 +298,9 @@ int parport_claim(struct ppd *dev)
                        if (dev->port->modes & PARPORT_MODE_ECR)
                                dev->port->cad->ecr = dev->port->ecr = 
                                        r_ecr(dev->port);
-                       dev->port->cad->ctr = dev->port->ctr =
-                               r_ctr(dev->port);
+                       if (dev->port->modes & PARPORT_MODE_SPP)
+                               dev->port->cad->ctr = dev->port->ctr =
+                                       r_ctr(dev->port);
                } else
                        return -EAGAIN;
        }
@@ -326,7 +326,8 @@ int parport_claim(struct ppd *dev)
        /* Restore control registers */
        if (dev->port->modes & PARPORT_MODE_ECR)
                if (dev->ecr != dev->port->ecr) w_ecr(dev->port, dev->ecr);
-       if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr);
+       if (dev->port->modes & PARPORT_MODE_SPP)
+               if (dev->ctr != dev->port->ctr) w_ctr(dev->port, dev->ctr);
 
        return 0;
 }
@@ -337,8 +338,7 @@ void parport_release(struct ppd *dev)
 
        /* Make sure that dev is the current device */
        if (dev->port->cad != dev) {
-               printk(KERN_WARNING "%s: %s tried to release parport when not owner\n",
-                          dev->port->name, dev->name);
+               printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", dev->port->name, dev->name);
                return;
        }
        dev->port->cad = NULL;
@@ -346,12 +346,13 @@ void parport_release(struct ppd *dev)
        /* Save control registers */
        if (dev->port->modes & PARPORT_MODE_ECR)
                dev->ecr = dev->port->ecr = r_ecr(dev->port);
-       dev->ctr = dev->port->ctr = r_ctr(dev->port);
+       if (dev->port->modes & PARPORT_MODE_SPP)
+               dev->ctr = dev->port->ctr = r_ctr(dev->port);
        
        if (dev->port->irq >= 0) {
                free_irq(dev->port->irq, dev->port);
                request_irq(dev->port->irq, parport_null_intr_func,
-                                       SA_INTERRUPT, dev->port->name, dev->port);
+                           SA_INTERRUPT, dev->port->name, dev->port);
        }
 
        /* Walk the list, offering a wakeup callback to everybody other
@@ -384,16 +385,22 @@ void parport_release(struct ppd *dev)
        if (dev->port->lurker && (dev->port->lurker != dev)) {
                if (dev->port->lurker->wakeup) {
                        dev->port->lurker->wakeup(dev->port->lurker->private);
-                       return;
+               } 
+#ifdef PARPORT_PARANOID
+               else {  /* can't happen */
+                       printk(KERN_DEBUG
+                         "%s (%s): lurker's wakeup callback went away!\n",
+                              dev->port->name, dev->name);
                }
-               printk(KERN_DEBUG
-                      "%s (%s): lurker's wakeup callback went away!\n",
-                      dev->port->name, dev->name);
+#endif
        }
 }
 
 /* The following read funktions are an implementation of a status readback
  * and device id request confirming to IEEE1284-1994.
+ *
+ * These probably ought to go in some seperate file, so people like the SPARC
+ * don't have to pull them in.
  */
 
 /* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to
index dbb4aaab9f064f25ecca388dbe1625ed4c5a17b9..3f25aa8281ed1607d88deb0271f51eb1c2735663 100644 (file)
@@ -10,6 +10,7 @@ if [ "$CONFIG_SUN_FB_DISPLAY" = "n" ]; then
        bool 'bwtwo support' SUN_FB_BWTWO
        bool 'leo/zx support' SUN_FB_LEO
        bool 'weitek P9X00 support' TADPOLE_FB_WEITEK
+       bool 'creator support' SUN_FB_CREATOR
        if [ "$TADPOLE_FB_WEITEK" = "n" ]; then
                fbs=$SUN_FB_CGSIX
                fbs=$fbs$SUN_FB_TCX
@@ -34,6 +35,7 @@ else
        define_bool SUN_FB_BWTWO y
        define_bool SUN_FB_LEO y
        define_bool TADPOLE_FB_WEITEK y
+       define_bool SUN_FB_CREATOR y
 fi
 
 comment 'Misc Linux/SPARC drivers'
index ed878f5f2e805ae4999553be0022bdfc176ec441..4ce803b34d3c63b3b0d4712e3ddf19790a4293e1 100644 (file)
@@ -31,6 +31,9 @@ endif
 ifdef TADPOLE_FB_WEITEK
  FB_OBJS +=    weitek.o
 endif
+ifdef SUN_FB_CREATOR
+ FB_OBJS += creator.o
+endif
 #ifdef SUN_FB_FAST_ONE
 # FB_OBJS +=   sun_8bit_fast1.o
 #endif
index ba537014c36e8458ee3f9731249a0f95df75530a..2fd13874836f8979a2358f562e07cf5f2f5cb1b8 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 
 #if defined(__sparc__)
+# include <linux/init.h>
 # include <linux/delay.h>         /* udelay() */
 
 # include <asm/oplib.h>           /* OpenProm Library */
index 91d77ad785f1bf6e7f17c7b6bbd6d5e57541dc00..be68d09c9b22576e1b85f9f38958e6531e474440 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bwtwo.c,v 1.12 1997/04/10 03:02:40 davem Exp $
+/* $Id: bwtwo.c,v 1.13 1997/04/14 17:04:55 jj Exp $
  * bwtwo.c: bwtwo console driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -86,7 +86,7 @@ bwtwo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
        /* This routine should also map the register if asked for,
         * but we don't do that yet.
         */
-       map_offset = get_phys ((uint) fb->base);
+       map_offset = get_phys ((unsigned long) fb->base);
        r = io_remap_page_range (vma->vm_start, map_offset, map_size,
                                 vma->vm_page_prot, fb->space);
        if (r) return -EAGAIN;
@@ -143,10 +143,10 @@ static u8 bw2regs_66hz[] __initdata = {
        0x10, 0x20,     0
 };
 
-__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, unsigned long bwtwo, int bw2_io,
+__initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, u32 bwtwo, int bw2_io,
                             struct linux_sbus_device *sbdp))
 {
-       printk ("bwtwo%d at 0x%8.8x\n", slot, (uint)bwtwo);
+       printk ("bwtwo%d at 0x%8.8x\n", slot, bwtwo);
        fb->type.fb_cmsize = 0;
        fb->mmap = bwtwo_mmap;
        fb->loadcmap = 0;
@@ -156,7 +156,7 @@ __initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, unsigned long bwtwo, int bw
        fb->unblank = bwtwo_unblank;
 
        fb->info.bwtwo.regs =
-               sparc_alloc_io ((u32)(bwtwo + BWTWO_REGISTER_OFFSET),
+               sparc_alloc_io (bwtwo + BWTWO_REGISTER_OFFSET,
                                0, sizeof (struct bwtwo_regs),
                "bwtwo_regs", bw2_io, 0);
 
@@ -201,7 +201,7 @@ __initfunc(void bwtwo_setup (fbinfo_t *fb, int slot, unsigned long bwtwo, int bw
        }
 
        if(!fb->base)
-               fb->base = (unsigned long) sparc_alloc_io((u32)bwtwo, 0,
+               fb->base = (unsigned long) sparc_alloc_io(bwtwo, 0,
                  ((fb->type.fb_depth*fb->type.fb_height*fb->type.fb_width)/8),
                  "bwtwo_fbase", bw2_io, 0);
 
index 5c3189681fde349bf1e45867757d910a94998274..d42a4343cea4a9d666fed74b2e5d9cc7ec40dba8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgfourteen.c,v 1.18 1997/03/24 17:44:27 jj Exp $
+/* $Id: cgfourteen.c,v 1.19 1997/04/14 17:04:57 jj Exp $
  * cgfourteen.c: Sun SparcStation console support.
  *
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -183,22 +183,22 @@ cg14_mmap (struct inode *inode, struct file *file,
                        printk ("Wee!  They are mapping the register, report this to miguel@gnu.ai.mit.edu\n");
                        printk ("Mapping fb->info.regs!\n");
                        map_size = 0x7000;
-                       map_offset = get_phys ((uint) fb->info.cg14.regs);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.regs);
                        break;
                        
                case CG3_MMAP_OFFSET:
                        map_size = size-page;
-                       map_offset = get_phys ((uint) fb->base);
+                       map_offset = get_phys ((unsigned long) fb->base);
                        break;
 
                case MDI_PLANAR_X16_MAP:
                        map_size = ram_size/2;
-                       map_offset = get_phys ((uint) fb->base) | 0x2000000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x2000000;
                        break;
                        
                case MDI_PLANAR_C16_MAP:
                        map_size = ram_size/2;
-                       map_offset = get_phys ((uint) fb->base) | 0x2800000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x2800000;
                        break;
                        
                case MDI_CHUNKY_XBGR_MAP:
@@ -208,50 +208,50 @@ cg14_mmap (struct inode *inode, struct file *file,
                        
                case MDI_CHUNKY_BGR_MAP:
                        map_size = ram_size;
-                       map_offset = get_phys ((uint) fb->base) | 0x1000000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x1000000;
                        break;
                        
                case MDI_PLANAR_X32_MAP:
                        map_size = ram_size/4;
-                       map_offset = get_phys ((uint) fb->base) | 0x3000000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x3000000;
                        break;
                case MDI_PLANAR_B32_MAP:
                        map_size = ram_size/4;
-                       map_offset = get_phys ((uint) fb->base) | 0x3400000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x3400000;
                        break;
                case MDI_PLANAR_G32_MAP:
                        map_size = ram_size/4;
-                       map_offset = get_phys ((uint) fb->base) | 0x3800000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x3800000;
                        break;
                case MDI_PLANAR_R32_MAP:
                        map_size = ram_size/4;
-                       map_offset = get_phys ((uint) fb->base) | 0x3c00000;
+                       map_offset = get_phys ((unsigned long) fb->base) | 0x3c00000;
                        break;
 
                case MDI_CURSOR_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint) fb->info.cg14.cursor_regs);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.cursor_regs);
                        break;
                        
                case CG14_REGS:
                        printk ("Wee!  They are mapping the register, report this to miguel@gnu.ai.mit.edu\n");
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint) fb->info.cg14.regs);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.regs);
                        break;
                        
                case CG14_XLUT:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint) fb->info.cg14.regs+0x3000);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x3000);
                        break;
                        
                case CG14_CLUT1:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint) fb->info.cg14.regs+0x4000);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x4000);
                        break;
                        
                case CG14_CLUT2:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint) fb->info.cg14.regs+0x5000);
+                       map_offset = get_phys ((unsigned long) fb->info.cg14.regs+0x5000);
                        break;
                        
                default:
@@ -424,11 +424,11 @@ cg14_reset (fbinfo_t *fb)
        *mcr = (*mcr & ~(CG14_MCR_PIXMODE_MASK));
 }
 
-__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, unsigned long cg14, int cg14_io))
+__initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, u32 cg14, int cg14_io))
 {
        struct cg14_info *cg14info;
        uint bases [2];
-       uint cg14regs = 0;
+       unsigned long cg14regs = 0;
        struct cg14_regs *regs = 0;
 
        if (!cg14) {
@@ -468,5 +468,5 @@ __initfunc(void cg14_setup (fbinfo_t *fb, int slot, int con_node, unsigned long
        /* If the bit is turned on, the card has 8 mb of ram, otherwise just 4 */
        cg14info->ramsize = (regs->vca & CG14_VCA_8MB_MASK ? 8 : 4) * 1024 * 1024;
        printk ("cgfourteen%d at 0x%8.8x with %d megs of RAM rev=%d, impl=%d\n",
-               slot, (uint)cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf);
+               slot, cg14, cg14info->ramsize/(1024*1024), regs->rev >> 4, regs->rev & 0xf);
 }
index b607d6bf32b5a04b7d79504b88d3fabe5a3e74e3..5f91c1308cadd22f2d2223c4502041cb00c66673 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.26 1997/04/10 03:02:40 davem Exp $
+/* $Id: cgsix.c,v 1.27 1997/04/14 17:04:55 jj Exp $
  * cgsix.c: cgsix frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -264,17 +264,14 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                        map_size = PAGE_SIZE;
                        map_offset = get_phys ((unsigned long)fb->info.cg6.bt);
                        break;
-                       
                case CG6_DHC:
                        map_size = PAGE_SIZE * 40;
                        map_offset = get_phys ((unsigned long)fb->info.cg6.dhc);
                        break;
-                       
                case CG6_ROM:
                        map_size = PAGE_SIZE * 16;
                        map_offset = get_phys ((unsigned long)fb->info.cg6.rom);
                        break;
-
                case CG6_RAM:
                        map_size = size-page;
                        map_offset = get_phys ((unsigned long) fb->base);
@@ -422,12 +419,12 @@ cg6_reset (fbinfo_t *fb)
        cg6->bt->control |= 0x03 << 24;
 }
 
-__initfunc(void cg6_setup (fbinfo_t *fb, int slot, unsigned long cg6, int cg6_io))
+__initfunc(void cg6_setup (fbinfo_t *fb, int slot, u32 cg6, int cg6_io))
 {
        struct cg6_info *cg6info;
        unsigned int rev, cpu, conf;
 
-       printk ("cgsix%d at 0x%8.8x ", slot, (uint) cg6);
+       printk ("cgsix%d at 0x%8.8x ", slot, cg6);
        
        /* Fill in parameters we left out */
        fb->type.fb_cmsize = 256;
@@ -447,23 +444,23 @@ __initfunc(void cg6_setup (fbinfo_t *fb, int slot, unsigned long cg6, int cg6_io
        cg6info = (struct cg6_info *) &fb->info.cg6;
 
        /* Map the hardware registers */
-       cg6info->bt = sparc_alloc_io ((u32)(cg6+CG6_BROOKTREE_OFFSET), 0,
+       cg6info->bt = sparc_alloc_io (cg6+CG6_BROOKTREE_OFFSET, 0,
                 sizeof (struct bt_regs), "cgsix_dac", cg6_io, 0);
-       cg6info->fhc = sparc_alloc_io ((u32)(cg6+CG6_FHC_OFFSET), 0,
+       cg6info->fhc = sparc_alloc_io (cg6+CG6_FHC_OFFSET, 0,
                 sizeof (int), "cgsix_fhc", cg6_io, 0);
-       cg6info->thc = sparc_alloc_io ((u32)(cg6+CG6_THC_OFFSET), 0,
+       cg6info->thc = sparc_alloc_io (cg6+CG6_THC_OFFSET, 0,
                 sizeof (struct cg6_thc), "cgsix_thc", cg6_io, 0);
-       cg6info->tec = sparc_alloc_io ((u32)(cg6+CG6_TEC_OFFSET), 0,
+       cg6info->tec = sparc_alloc_io (cg6+CG6_TEC_OFFSET, 0,
                 sizeof (struct cg6_tec), "cgsix_tec", cg6_io, 0);
-       cg6info->dhc = sparc_alloc_io ((u32)(cg6+CG6_DHC_OFFSET), 0,
+       cg6info->dhc = sparc_alloc_io (cg6+CG6_DHC_OFFSET, 0,
                 0x40000, "cgsix_dhc", cg6_io, 0);
-       cg6info->fbc = sparc_alloc_io ((u32)(cg6+CG6_FBC_OFFSET), 0,
+       cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0,
                 0x1000, "cgsix_fbc", cg6_io, 0);
-       cg6info->rom = sparc_alloc_io ((u32)(cg6+CG6_ROM_OFFSET), 0,
+       cg6info->rom = sparc_alloc_io (cg6+CG6_ROM_OFFSET, 0,
                 0x10000, "cgsix_rom", cg6_io, 0);
        if (!fb->base) {
                fb->base = (unsigned long)
-                       sparc_alloc_io ((u32)(cg6+CG6_RAM_OFFSET), 0,
+                       sparc_alloc_io (cg6+CG6_RAM_OFFSET, 0,
                                        fb->type.fb_size, "cgsix_ram", cg6_io, 0);
        }
        if (slot == sun_prom_console_id)
index ee5f1bfc90a32b9bc3209f61baf63c71448eb5dd..ac1265c6132379c09c8c7b2349438cd7fdd27f4d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgthree.c,v 1.16 1997/04/10 03:02:41 davem Exp $
+/* $Id: cgthree.c,v 1.18 1997/04/16 17:51:09 jj Exp $
  * cgtree.c: cg3 frame buffer driver
  *
  * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -109,7 +109,7 @@ cg3_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                switch (vma->vm_offset+page){
                case CG3_MMAP_OFFSET:
                        map_size = size-page;
-                       map_offset = get_phys ((uint) fb->base);
+                       map_offset = get_phys ((unsigned long) fb->base);
                        if (map_size > fb->type.fb_size)
                                map_size = fb->type.fb_size;
                        break;
@@ -178,7 +178,7 @@ static u_char cg3_dacvals[] __initdata = {
 };
 
 
-__initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io,
+__initfunc(void cg3_setup (fbinfo_t *fb, int slot, u32 cg3, int cg3_io,
                           struct linux_sbus_device *sbdp))
 {
        struct cg3_info *cg3info = (struct cg3_info *) &fb->info.cg3;
@@ -200,10 +200,10 @@ __initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io
                                }
                        }
                }
-               printk ("cgRDI%d at 0x%8.8x\n", slot, (uint)cg3);
+               printk ("cgRDI%d at 0x%8.8x\n", slot, cg3);
                cg3info->cgrdi = 1;
        } else {
-               printk ("cgthree%d at 0x%8.8x\n", slot, (uint)cg3);
+               printk ("cgthree%d at 0x%8.8x\n", slot, cg3);
                cg3info->cgrdi = 0;
        }
        
@@ -218,7 +218,7 @@ __initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io
        fb->unblank = cg3_unblank;
 
        /* Map the card registers */
-       cg3info->regs = sparc_alloc_io ((u32)(cg3+CG3_REGS), 0,
+       cg3info->regs = sparc_alloc_io (cg3+CG3_REGS, 0,
                 sizeof (struct cg3_regs),"cg3_regs", cg3_io, 0);
 
        if (!prom_getbool(sbdp->prom_node, "width")) {
@@ -258,8 +258,8 @@ __initfunc(void cg3_setup (fbinfo_t *fb, int slot, unsigned long cg3, int cg3_io
        }
 
        if (!fb->base){
-               fb->base=(uint) sparc_alloc_io ((u32)(cg3+CG3_RAM), 0,
-                                   fb->type.fb_size, "cg3_ram", cg3_io, 0);
+               fb->base=(unsigned long) sparc_alloc_io (cg3+CG3_RAM, 0,
+                                        fb->type.fb_size, "cg3_ram", cg3_io, 0);
        }
 }
 
index bf3b037186b77bbb7dd845cb5ceea9050fdf6dc2..029eac81bbb10d47e603a0c93dd8d6fbe4003bd7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fb.h,v 1.24 1997/03/24 17:44:15 jj Exp $
+/* $Id: fb.h,v 1.26 1997/04/17 02:29:33 miguel Exp $
  * fb.h: contains the definitions of the structures that various sun
  *       frame buffer can use to do console driver stuff.
  *
@@ -183,8 +183,8 @@ extern int con_height, con_linebytes;
 extern int ints_per_line;
 
 /* used in the mmap routines */
-extern unsigned int get_phys (unsigned int addr);
-extern int get_iospace (unsigned int addr);
+extern unsigned int get_phys (unsigned long addr);
+extern int get_iospace (unsigned long addr);
 extern void render_screen(void);
 
 extern void sun_hw_hide_cursor(void);
@@ -197,12 +197,14 @@ extern unsigned long sun_cg_postsetup(fbinfo_t *, unsigned long);
 
 #define FB_DEV(x) (MINOR(x) / 32)
 
-extern void cg3_setup (fbinfo_t *, int, unsigned long, int, struct linux_sbus_device *);
-extern void cg6_setup (fbinfo_t *, int, unsigned long, int);
-extern void cg14_setup (fbinfo_t *, int, int, unsigned long, int);
-extern void bwtwo_setup (fbinfo_t *, int, unsigned long, int,
+extern void cg3_setup (fbinfo_t *, int, u32, int, struct linux_sbus_device *);
+extern void cg6_setup (fbinfo_t *, int, u32, int);
+extern void cg14_setup (fbinfo_t *, int, int, u32, int);
+extern void bwtwo_setup (fbinfo_t *, int, u32, int,
                         struct linux_sbus_device *);
-extern void leo_setup (fbinfo_t *, int, unsigned long, int);
-extern void tcx_setup (fbinfo_t *, int, int, unsigned long, struct linux_sbus_device *);
+extern void leo_setup (fbinfo_t *, int, u32, int);
+extern void tcx_setup (fbinfo_t *, int, int, u32, struct linux_sbus_device *);
+extern void creator_setup (fbinfo_t *, int, int, unsigned long, int);
+extern int io_remap_page_range(unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
 
 #endif __SPARC_FB_H_
index 0fce4fe4c415a5f5a8929bdb87a9048a866fe499..b3ec23867dc0c15dff41d95ef9801c2252c8607b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: leo.c,v 1.14 1997/04/10 17:06:09 jj Exp $
+/* $Id: leo.c,v 1.15 1997/04/14 17:04:54 jj Exp $
  * leo.c: SUNW,leo 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -156,19 +156,19 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                switch (vma->vm_offset+page){
                case LEO_SS0_MAP:
                        map_size = 0x800000;
-                       map_offset = get_phys ((uint)fb->base);
+                       map_offset = get_phys ((unsigned long)fb->base);
                        break;
                case LEO_LC_SS0_USR_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.lc_ss0_usr);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_usr);
                        break;
                case LEO_LD_SS0_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.ld_ss0);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss0);
                        break;
                case LEO_LX_CURSOR_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.cursor);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.cursor);
                        break;
                case LEO_SS1_MAP:       
                        map_size = 0x800000;
@@ -176,11 +176,11 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                        break;
                case LEO_LC_SS1_USR_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.lc_ss1_usr);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_usr);
                        break;
                case LEO_LD_SS1_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.ld_ss1);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.ld_ss1);
                        break;
                case LEO_UNK_MAP:       
                        map_size = PAGE_SIZE;
@@ -188,19 +188,19 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                        break;
                case LEO_LX_KRN_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.lx_krn);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.lx_krn);
                        break;
                case LEO_LC_SS0_KRN_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.lc_ss0_krn);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss0_krn);
                        break;
                case LEO_LC_SS1_KRN_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.lc_ss1_krn);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.lc_ss1_krn);
                        break;
                case LEO_LD_GBL_MAP:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.leo.ld_gbl);
+                       map_offset = get_phys ((unsigned long)fb->info.leo.ld_gbl);
                        break;
                case LEO_UNK2_MAP:
                        map_size = 0x100000;
@@ -509,14 +509,14 @@ __initfunc(static unsigned long leo_postsetup (fbinfo_t *fb, unsigned long memor
        return memory_start + (256*4*3) + 256 + 256*3;
 }
 
-__initfunc(void leo_setup (fbinfo_t *fb, int slot, unsigned long leo, int leo_io))
+__initfunc(void leo_setup (fbinfo_t *fb, int slot, u32 leo, int leo_io))
 {
        struct leo_info *leoinfo;
        int i;
        struct fb_wid_item wi;
        struct fb_wid_list wl;
        
-       printk ("leo%d at 0x%8.8x ", slot, (uint) leo);
+       printk ("leo%d at 0x%8.8x ", slot, leo);
        
        /* Fill in parameters we left out */
        fb->type.fb_size = 0x800000; /* 8MB */
@@ -543,25 +543,25 @@ __initfunc(void leo_setup (fbinfo_t *fb, int slot, unsigned long leo, int leo_io
 
        leoinfo->offset = leo;
        /* Map the hardware registers */
-       leoinfo->lc_ss0_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_KRN), 0,
+       leoinfo->lc_ss0_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS0_KRN, 0,
                 PAGE_SIZE,"leo_lc_ss0_krn", fb->space, 0);
-       leoinfo->lc_ss0_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS0_USR), 0,
+       leoinfo->lc_ss0_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS0_USR, 0,
                 PAGE_SIZE,"leo_lc_ss0_usr", fb->space, 0);
-       leoinfo->lc_ss1_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_KRN), 0,
+       leoinfo->lc_ss1_krn = sparc_alloc_io(leo + LEO_OFF_LC_SS1_KRN, 0,
                 PAGE_SIZE,"leo_lc_ss1_krn", fb->space, 0);
-       leoinfo->lc_ss1_usr = sparc_alloc_io((u32)(leo + LEO_OFF_LC_SS1_USR), 0,
+       leoinfo->lc_ss1_usr = sparc_alloc_io(leo + LEO_OFF_LC_SS1_USR, 0,
                 PAGE_SIZE,"leo_lc_ss1_usr", fb->space, 0);
-       leoinfo->ld_ss0 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS0), 0,
+       leoinfo->ld_ss0 = sparc_alloc_io(leo + LEO_OFF_LD_SS0, 0,
                 PAGE_SIZE,"leo_ld_ss0", fb->space, 0);
-       leoinfo->ld_ss1 = sparc_alloc_io((u32)(leo + LEO_OFF_LD_SS1), 0,
+       leoinfo->ld_ss1 = sparc_alloc_io(leo + LEO_OFF_LD_SS1, 0,
                 PAGE_SIZE,"leo_ld_ss1", fb->space, 0);
-       leoinfo->ld_gbl = sparc_alloc_io((u32)(leo + LEO_OFF_LD_GBL), 0,
+       leoinfo->ld_gbl = sparc_alloc_io(leo + LEO_OFF_LD_GBL, 0,
                 PAGE_SIZE,"leo_ld_gbl", fb->space, 0);
-       leoinfo->lx_krn = sparc_alloc_io((u32)(leo + LEO_OFF_LX_KRN), 0,
+       leoinfo->lx_krn = sparc_alloc_io(leo + LEO_OFF_LX_KRN, 0,
                 PAGE_SIZE,"leo_lx_krn", fb->space, 0);
-       leoinfo->cursor = sparc_alloc_io((u32)(leo + LEO_OFF_LX_CURSOR), 0,
+       leoinfo->cursor = sparc_alloc_io(leo + LEO_OFF_LX_CURSOR, 0,
                 sizeof(struct leo_cursor),"leo_lx_crsr", fb->space, 0);
-       fb->base = (long)sparc_alloc_io((u32)(leo + LEO_OFF_SS0), 0,
+       fb->base = (long)sparc_alloc_io(leo + LEO_OFF_SS0, 0,
                 0x800000,"leo_ss0", fb->space, 0);
        
        leoinfo->ld_ss0->unk = 0xffff;
index dd35c856cf4731de7c6af512272526556cf11be1..20b65c6583cd5f644b0218b82f32880cd4a8b92e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: suncons.c,v 1.58 1997/04/04 00:50:04 davem Exp $
+/* $Id: suncons.c,v 1.61 1997/04/17 02:29:36 miguel Exp $
  *
  * suncons.c: Sun SparcStation console support.
  *
@@ -87,7 +87,7 @@
 #define cmapsz 8192
 
 #include "suncons_font.h"
-#include "linux_logo.h"
+#include <asm/linux_logo.h>
 
 fbinfo_t *fbinfo;
 int fbinfos;
@@ -382,7 +382,7 @@ render_screen(void)
 
     count = video_num_columns * video_num_lines;
     contents = (unsigned short *) video_mem_base;
-    
+
     for (;count--; contents++)
        sun_blitc (*contents, (unsigned long) contents);
 }
@@ -434,11 +434,7 @@ __initfunc(void con_type_init_finish(void))
        putconsxy(0, q);
        ush = (unsigned short *) video_mem_base + video_num_columns * 2 + 20 + 11 * (linux_num_cpus - 1);
 
-#ifdef __sparc_v9__
-       p = "Linux/UltraSPARC version " UTS_RELEASE;
-#else
-       p = "Linux/SPARC version " UTS_RELEASE;
-#endif
+       p = linux_logo_banner;
        for (; *p; p++, ush++) {
                *ush = (attr << 8) + *p;
                sun_blitc (*ush, (unsigned long) ush);
@@ -764,35 +760,15 @@ console_restore_palette (void)
 }
 
 unsigned int
-get_phys (unsigned int addr)
+get_phys (unsigned long addr)
 {
-       switch (sparc_cpu_model){
-       case sun4c:
-               return sun4c_get_pte (addr) << PAGE_SHIFT;
-       case sun4m:
-               return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
-       case sun4u:
-               /* FIXME: */ return 0;
-       default:
-               panic ("get_phys called for unsupported cpu model\n");
-               return 0;
-       }
+       return __get_phys(addr);
 }
 
 int
-get_iospace (unsigned int addr)
+get_iospace (unsigned long addr)
 {
-       switch (sparc_cpu_model){
-       case sun4c:
-               return -1; /* Don't check iospace on sun4c */
-       case sun4m:
-               return (srmmu_get_pte (addr) >> 28);
-       case sun4u:
-               /* FIXME: */ return 0;
-       default:
-               panic ("get_iospace called for unsupported cpu model\n");
-               return -1;
-       }
+       return __get_iospace(addr);
 }
 
 __initfunc(unsigned long sun_cg_postsetup(fbinfo_t *fb, unsigned long start_mem))
@@ -803,7 +779,7 @@ __initfunc(unsigned long sun_cg_postsetup(fbinfo_t *fb, unsigned long start_mem)
 
 static char *known_cards [] __initdata = {
        "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", "SUNW,tcx",
-       "cgfourteen", "SUNW,leo", 0
+       "cgfourteen", "SUNW,leo", "SUNW,ffb", 0
 };
 static char *v0_known_cards [] __initdata = {
        "cgsix", "cgthree", "cgRDI", "cgthree+", "bwtwo", 0
@@ -848,6 +824,16 @@ __initfunc(static int cg14_present(void))
        return n;
 }
 
+__initfunc(static int creator_present (void))
+{
+       int root, n;
+
+       root = prom_getchild (prom_root_node);
+       if ((n = prom_searchsiblings (root, "SUNW,ffb")) == 0)
+               return 0;
+       return n;
+}
+
 __initfunc(static void
           sparc_framebuffer_setup(int primary, int con_node,
                                   int type, struct linux_sbus_device *sbdp, 
@@ -940,79 +926,87 @@ __initfunc(static void
        case FBTYPE_SUNLEO:
                leo_setup (&fbinfo [n], n, base, io);
                break;
+#endif
+#ifdef SUN_FB_CREATOR
+       case FBTYPE_CREATOR:
+               creator_setup (&fbinfo [n], n, con_node, base, io);
+               break;
 #endif
        default:
                fbinfo [n].type.fb_type = FBTYPE_NOTYPE;
                return;
        }
-       if (!n) {
-               con_type = type;
-               con_height = fbinfo [n].type.fb_height;
-               con_width = fbinfo [n].type.fb_width;
-               con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8;
-               for (i = 0; scr_def [i].depth; i++){
-                       if ((scr_def [i].resx != con_width) ||
-                           (scr_def [i].resy != con_height))
-                               continue;
-                       if (scr_def [i].depth != con_depth)
-                               continue;
-                       x_margin = scr_def [i].x_margin;
-                       y_margin = scr_def [i].y_margin;
-                       chars_per_line = (con_width * con_depth) / 8;
-                       skip_bytes = chars_per_line * y_margin + x_margin;
-                       ints_per_line = chars_per_line / 4;
-                       ints_per_cursor = 14 * ints_per_line;
-                       bytes_per_row = CHAR_HEIGHT * chars_per_line;
-                       ORIG_VIDEO_COLS = con_width / 8 -
-                                               2 * x_margin / con_depth;
-                       ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16;
-                       switch (chars_per_line) {
-                       case 1280:
-                               if (ORIG_VIDEO_COLS == 144)
-                                       color_fbuf_offset =
-                                               color_fbuf_offset_1280_144;
-                               break;
-                       case 1152:
-                               if (ORIG_VIDEO_COLS == 128)
-                                       color_fbuf_offset =
-                                               color_fbuf_offset_1152_128;
-                               break;
-                       case 1024:
-                               if (ORIG_VIDEO_COLS == 128)
-                                       color_fbuf_offset =
-                                               color_fbuf_offset_1024_128;
-                               break;
-                       case 800:
-                               if (ORIG_VIDEO_COLS == 96)
-                                       color_fbuf_offset =
-                                               color_fbuf_offset_800_96;
-                               break;
-                       case 640:
-                               if (ORIG_VIDEO_COLS == 80)
-                                       color_fbuf_offset =
-                                               color_fbuf_offset_640_80;
-                               break;
-                       }
-                       break;
-               }
-
-               if (!scr_def [i].depth){
-                       x_margin = y_margin = 0;
-                       prom_printf ("console: unknown video resolution %dx%d,"
-                                    " depth %d\n",
-                                    con_width, con_height, con_depth);
-                       prom_halt ();
-               }
 
-               /* P3: I fear this strips 15inch 1024/768 PC-like
-                * monitors out. */
-               if ((linebytes*8) / con_depth != con_width) {
-                       prom_printf("console: unusual video, linebytes=%d, "
-                                   "width=%d, height=%d depth=%d\n",
-                                   linebytes, con_width, con_height,
-                                   con_depth);
-                       prom_halt ();
+       if (n)
+               return;
+       
+       /* Code below here is just executed for the first frame buffer */
+       con_type = type;
+       con_height = fbinfo [n].type.fb_height;
+       con_width = fbinfo [n].type.fb_width;
+       con_depth = (type == FBTYPE_SUN2BW) ? 1 : 8;
+       for (i = 0; scr_def [i].depth; i++){
+               if ((scr_def [i].resx != con_width) ||
+                   (scr_def [i].resy != con_height))
+                       continue;
+               if (scr_def [i].depth != con_depth)
+                       continue;
+               x_margin = scr_def [i].x_margin;
+               y_margin = scr_def [i].y_margin;
+               chars_per_line = (con_width * con_depth) / 8;
+               skip_bytes = chars_per_line * y_margin + x_margin;
+               ints_per_line = chars_per_line / 4;
+               ints_per_cursor = 14 * ints_per_line;
+               bytes_per_row = CHAR_HEIGHT * chars_per_line;
+               ORIG_VIDEO_COLS = con_width / 8 -
+                       2 * x_margin / con_depth;
+               ORIG_VIDEO_LINES = (con_height - 2 * y_margin) / 16;
+               switch (chars_per_line) {
+               case 1280:
+                       if (ORIG_VIDEO_COLS == 144)
+                               color_fbuf_offset =
+                                       color_fbuf_offset_1280_144;
+                       break;
+               case 1152:
+                       if (ORIG_VIDEO_COLS == 128)
+                               color_fbuf_offset =
+                                       color_fbuf_offset_1152_128;
+                       break;
+               case 1024:
+                       if (ORIG_VIDEO_COLS == 128)
+                               color_fbuf_offset =
+                                       color_fbuf_offset_1024_128;
+                       break;
+               case 800:
+                       if (ORIG_VIDEO_COLS == 96)
+                               color_fbuf_offset =
+                                       color_fbuf_offset_800_96;
+                       break;
+               case 640:
+                       if (ORIG_VIDEO_COLS == 80)
+                               color_fbuf_offset =
+                                       color_fbuf_offset_640_80;
+                       break;
                }
+               break;
+       }
+       
+       if (!scr_def [i].depth){
+               x_margin = y_margin = 0;
+               prom_printf ("console: unknown video resolution %dx%d,"
+                            " depth %d\n",
+                            con_width, con_height, con_depth);
+               prom_halt ();
+       }
+       
+       /* P3: I fear this strips 15inch 1024/768 PC-like
+        * monitors out. */
+       if ((linebytes*8) / con_depth != con_width) {
+               prom_printf("console: unusual video, linebytes=%d, "
+                           "width=%d, height=%d depth=%d\n",
+                           linebytes, con_width, con_height,
+                           con_depth);
+               prom_halt ();
        }
 }
 
@@ -1022,9 +1016,9 @@ __initfunc(static int sparc_console_probe(void))
        char prop[16];
        struct linux_sbus_device *sbdp, *sbdprom;
        struct linux_sbus *sbus;
-       int cg14 = 0;
+       int creator = 0, cg14 = 0;
        char prom_name[40];     
-       int type;
+       int type, card_found = 0;
        unsigned long con_base;
        u32 tmp;
        u32 prom_console_node = 0;
@@ -1109,18 +1103,22 @@ __initfunc(static int sparc_console_probe(void))
                                break;
                        }
                }
-               if (!sbdprom) /* I'm just wondering if this if shouldn't be deleted.
-                                Is /obio/cgfourteen present only if /sbus/cgfourteen
-                                is not? If so, then the test here should be deleted.
-                                Otherwise, this comment should be deleted. */
-                       cg14 = cg14_present ();
-               if (!sbdprom && !cg14) {
+               if (sbdprom)
+                   card_found = 1;
+               if (!card_found)
+                   card_found = cg14 = cg14_present ();
+               if (!card_found){
+                       prom_printf ("Searching for a creator\n");
+                       card_found = creator = creator_present ();
+               }
+               if (!card_found){
                        prom_printf ("Could not find a known video card on this machine\n");
                        prom_halt ();
                }
                
                for_all_sbusdev(sbdp, sbus) {
-                       if (!known_card (sbdp->prom_name, known_cards)) continue;
+                       if (!known_card (sbdp->prom_name, known_cards))
+                               continue;
                        con_node = sbdp->prom_node;
                        prom_apply_sbus_ranges (sbdp->my_bus, &sbdp->reg_addrs [0],
                                                sbdp->num_registers, sbdp);
@@ -1171,6 +1169,11 @@ __initfunc(static int sparc_console_probe(void))
                                                 0, 0, 0, prom_console_node == cg14,
                                                 prom_searchsiblings (prom_getchild (prom_root_node), "obio"));
                }
+               if (creator){
+                       sparc_framebuffer_setup (!sbdprom, creator, FBTYPE_CREATOR,
+                                                0, 0, 0, prom_console_node == creator,
+                                                prom_getchild (prom_root_node));
+               }
                break;
        default:
                return -1;
index 92b2d002d7cb30472aede1fc58065ce5f9ed9f0b..cd4fe4ee3494834463541b501db41ccac4ec49ca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sunserial.c,v 1.37 1997/04/12 23:33:14 ecd Exp $
+/* $Id: sunserial.c,v 1.38 1997/04/14 17:05:00 jj Exp $
  * serial.c: Serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1857,7 +1857,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
 
 static void show_serial_version(void)
 {
-       char *revision = "$Revision: 1.37 $";
+       char *revision = "$Revision: 1.38 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
@@ -1991,7 +1991,7 @@ static struct sun_zslayout *get_zs(int chip)
        if(!vaddr[0])
                panic("get_zs whee no serial chip mappable");
 
-       return (struct sun_zslayout *) vaddr[0];
+       return (struct sun_zslayout *)(unsigned long) vaddr[0];
 }
 
 static inline void
@@ -2541,7 +2541,7 @@ __initfunc(int rs_init(void))
 
        for (info = zs_chain, i=0; info; info = info->zs_next, i++) {
                info->magic = SERIAL_MAGIC;
-               info->port = (int) info->zs_channel;
+               info->port = (long) info->zs_channel;
                info->line = i;
                info->tty = 0;
                info->irq = zilog_irq;
index f025c8d892cbb35c85debafab19c2c7ef78697b1..2ecabda624b01a716ddab6f32935ed40ae79ad55 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tcx.c,v 1.11 1997/04/10 03:02:43 davem Exp $
+/* $Id: tcx.c,v 1.12 1997/04/14 17:04:51 jj Exp $
  * tcx.c: SUNW,tcx 24/8bit frame buffer driver
  *
  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -126,24 +126,24 @@ tcx_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
                switch (vma->vm_offset+page){
                case TCX_RAM8BIT:
                        map_size = fb->type.fb_size;
-                       map_offset = get_phys ((uint) fb->base);
+                       map_offset = get_phys ((unsigned long) fb->base);
                        break;
                case TCX_TEC:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.tcx.tec);
+                       map_offset = get_phys ((unsigned long)fb->info.tcx.tec);
                        break;
                case TCX_BTREGS:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.tcx.bt);
+                       map_offset = get_phys ((unsigned long)fb->info.tcx.bt);
                        break;
                case TCX_THC:
                        map_size = PAGE_SIZE;
-                       map_offset = get_phys ((uint)fb->info.tcx.thc);
+                       map_offset = get_phys ((unsigned long)fb->info.tcx.thc);
                        break;
                case TCX_CONTROLPLANE:
                        if (fb->info.tcx.tcx_cplane) {
                                map_size = fb->info.tcx.tcx_sizes [TCX_CONTROLPLANE_OFFSET];
-                               map_offset = get_phys ((uint)fb->info.tcx.tcx_cplane);
+                               map_offset = get_phys ((unsigned long)fb->info.tcx.tcx_cplane);
                        } else
                                map_size = 0;
                        break;
@@ -272,12 +272,12 @@ tcx_reset (fbinfo_t *fb)
        tcx->bt->control |= 0x03 << 24;
 }
 
-__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, unsigned long tcx, struct linux_sbus_device *sbdp))
+__initfunc(void tcx_setup (fbinfo_t *fb, int slot, int node, u32 tcx, struct linux_sbus_device *sbdp))
 {
        struct tcx_info *tcxinfo;
        int i;
 
-       printk ("tcx%d at 0x%8.8x ", slot, (uint) tcx);
+       printk ("tcx%d at 0x%8.8x ", slot, tcx);
        
        /* Fill in parameters we left out */
        fb->type.fb_cmsize = 256;
index 6c0174706038b6771f442810e1ed6af57f6390e7..0fa0cb5fc3949d1447849a0cd1ecff9589c7566d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: weitek.c,v 1.8 1997/03/24 17:44:26 jj Exp $
+/* $Id: weitek.c,v 1.9 1997/04/14 17:04:57 jj Exp $
  * weitek.c: Tadpole P9100/P9000 console driver
  *
  * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
@@ -54,13 +54,13 @@ weitek_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma,
                switch (vma->vm_offset+page){
                case WEITEK_VRAM_OFFSET:
                        map_size = size-page;
-                       map_offset = get_phys ((uint) fb->base);
+                       map_offset = get_phys ((unsigned long) fb->base);
                        if (map_size > fb->type.fb_size)
                                map_size = fb->type.fb_size;
                        break;
                case WEITEK_GX_REG_OFFSET:
                        map_size = size-page;
-                       map_offset = get_phys ((uint) fb->base);
+                       map_offset = get_phys ((unsigned long) fb->base);
                        if (map_size > fb->type.fb_size)
                                map_size = fb->type.fb_size;
                        break;
@@ -95,11 +95,11 @@ weitek_loadcmap (void *fbinfo, int index, int count)
 }
 #endif
 
-__initfunc(void weitek_setup(fbinfo_t *fb, int slot, unsigned long addr, int io))
+__initfunc(void weitek_setup(fbinfo_t *fb, int slot, u32 addr, int io))
 {
        extern struct screen_info screen_info;
        
-       printk ("weitek%d at 0x%8.8x\n", slot, (uint)addr);
+       printk ("weitek%d at 0x%8.8x\n", slot, addr);
        
        /* Fill in parameters we left out */
        fb->type.fb_type        = FBTYPE_NOTSUN1;
index 03e308f917717c2e819c0a674cb1d5ce2f2db1d4..4d59647cc7870fc364a4f4a0b485be9043f1c0c5 100644 (file)
@@ -74,10 +74,10 @@ fill_sbus_device(int nd, struct linux_sbus_device *sbus_dev))
                sbus_dev->slot = sbus_dev->reg_addrs[0].which_io;
                sbus_dev->offset = base;
                sbus_dev->reg_addrs[0].phys_addr = 
-                       (char *) sbus_devaddr(sbus_dev->slot, base);
+                       sbus_devaddr(sbus_dev->slot, base);
                for(grrr=1; grrr<sbus_dev->num_registers; grrr++) {
                        base = (unsigned long) sbus_dev->reg_addrs[grrr].phys_addr;
-                       sbus_dev->reg_addrs[grrr].phys_addr = (char *) 
+                       sbus_dev->reg_addrs[grrr].phys_addr =
                                sbus_devaddr(sbus_dev->slot, base);
                }
                /* That surely sucked */
index ddb138eb4958d2ee68dda3d5e78996082aff503c..a8638cc97336fa4dec77cdeee107961f535004e4 100644 (file)
@@ -9,7 +9,7 @@
 #include <asm/pgtable.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 #include <asm/irq.h>
 
 #include "scsi.h"
@@ -211,7 +211,7 @@ int a2091_detect(Scsi_Host_Template *tpnt)
        address = cd->cd_BoardAddr;
        instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata));
        instance->base = (unsigned char *)ZTWO_VADDR(address);
-       instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC;
+       instance->irq = IRQ_AMIGA_PORTS;
        instance->unique_id = key;
        DMA(instance)->DAWR = DAWR_A2091;
        wd33c93_init(instance, (wd33c93_regs *)&(DMA(instance)->SASR),
index fc9bce3aae00743e9946a8db039dd5f35cb31ff9..93aa6efa7aa3108b22acb7f4cf8e2b8dcd8fd6a8 100644 (file)
@@ -181,7 +181,7 @@ int a3000_detect(Scsi_Host_Template *tpnt)
 
     a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata));
     a3000_host->base = (unsigned char *)ZTWO_VADDR(0xDD0000);
-    a3000_host->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC;
+    a3000_host->irq = IRQ_AMIGA_PORTS;
     DMA(a3000_host)->DAWR = DAWR_A3000;
     wd33c93_init(a3000_host, (wd33c93_regs *)&(DMA(a3000_host)->SASR),
                 dma_setup, dma_stop, WD33C93_FS_12_15);
index ab2644c8e45083986f6681bc6a2cf7f3c4790d80..497b47f676a13e71fd0ec42f5f76536f87f17c0f 100644 (file)
@@ -753,10 +753,6 @@ static void NCR5380_print_status (struct Scsi_Host *instance)
         pos += sprintf(pos, fmt , ## args); } while(0)
 static
 char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
-static
-char *lprint_command (unsigned char *cmd, char *pos, char *buffer, int len);
-static
-char *lprint_opcode(int opcode, char *pos, char *buffer, int length);
 
 #ifndef NCR5380_proc_info
 static
@@ -769,6 +765,14 @@ int NCR5380_proc_info (char *buffer, char **start, off_t offset,
     struct NCR5380_hostdata *hostdata;
     Scsi_Cmnd *ptr;
     unsigned long flags;
+    off_t begin = 0;
+#define check_offset()                         \
+    do {                                       \
+       if (pos - buffer < offset - begin) {    \
+           begin += pos - buffer;              \
+           pos = buffer;                       \
+       }                                       \
+    } while (0)
 
     for (instance = first_instance; instance && HOSTNO != hostno;
         instance = instance->next)
@@ -781,58 +785,54 @@ int NCR5380_proc_info (char *buffer, char **start, off_t offset,
        return(-ENOSYS);  /* Currently this is a no-op */
     }
     SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
+    check_offset();
     save_flags(flags);
     cli();
     SPRINTF("NCR5380: coroutine is%s running.\n", main_running ? "" : "n't");
+    check_offset();
     if (!hostdata->connected)
        SPRINTF("scsi%d: no currently connected command\n", HOSTNO);
     else
        pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected,
                                pos, buffer, length);
     SPRINTF("scsi%d: issue_queue\n", HOSTNO);
-    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr))
+    check_offset();
+    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) {
        pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
+       check_offset();
+    }
 
     SPRINTF("scsi%d: disconnected_queue\n", HOSTNO);
+    check_offset();
     for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
-        ptr = NEXT(ptr))
+        ptr = NEXT(ptr)) {
        pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
+       check_offset();
+    }
 
     restore_flags(flags);
-    *start = buffer;
-    if (pos - buffer < offset)
+    *start = buffer + (offset - begin);
+    if (pos - buffer < offset - begin)
        return 0;
-    else if (pos - buffer - offset < length)
-       return pos - buffer - offset;
+    else if (pos - buffer - (offset - begin) < length)
+       return pos - buffer - (offset - begin);
     return length;
 }
 
 static char *
 lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length)
 {
+    int i, s;
+    unsigned char *command;
     SPRINTF("scsi%d: destination target %d, lun %d\n",
            H_NO(cmd), cmd->target, cmd->lun);
     SPRINTF("        command = ");
-    pos = lprint_command (cmd->cmnd, pos, buffer, length);
-    return (pos);
-}
-
-static char *
-lprint_command (unsigned char *command, char *pos, char *buffer, int length)
-{
-    int i, s;
-    pos = lprint_opcode(command[0], pos, buffer, length);
+    command = cmd->cmnd;
+    SPRINTF("%2d (0x%02x)", command[0], command[0]);
     for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-       SPRINTF("%02x ", command[i]);
+       SPRINTF(" %02x", command[i]);
     SPRINTF("\n");
-    return(pos);
-}
-
-static 
-char *lprint_opcode(int opcode, char *pos, char *buffer, int length)
-{
-    SPRINTF("%2d (0x%02x)", opcode, opcode);
-    return(pos);
+    return pos;
 }
 
 
index 325f8d7fb30afc0ecaf890b923d95fd6531860cf..d0de9dcdbf667b5837c07d72f159d08570f3fbf7 100644 (file)
@@ -239,13 +239,18 @@ static unsigned long      atari_dma_stram_mask;
 static int atari_read_overruns = 0;
 #endif
 
-int setup_can_queue = -1;
-int setup_cmd_per_lun = -1;
-int setup_sg_tablesize = -1;
+static int setup_can_queue = -1;
+MODULE_PARM(setup_can_queue, "i");
+static int setup_cmd_per_lun = -1;
+MODULE_PARM(setup_cmd_per_lun, "i");
+static int setup_sg_tablesize = -1;
+MODULE_PARM(setup_sg_tablesize, "i");
 #ifdef SUPPORT_TAGS
-int setup_use_tagged_queuing = -1;
+static int setup_use_tagged_queuing = -1;
+MODULE_PARM(setup_use_tagged_queuing, "i");
 #endif
-int setup_hostid = -1;
+static int setup_hostid = -1;
+MODULE_PARM(setup_hostid, "i");
 
 
 #if defined(REAL_DMA)
@@ -660,7 +665,7 @@ int atari_scsi_detect (Scsi_Host_Template *host)
        if (setup_use_tagged_queuing < 0)
                setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
 #endif
-
+#ifdef REAL_DMA
        /* If running on a Falcon and if there's TT-Ram (i.e., more than one
         * memory block, since there's always ST-Ram in a Falcon), then allocate a
         * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative
@@ -673,10 +678,14 @@ int atari_scsi_detect (Scsi_Host_Template *host)
                atari_dma_phys_buffer = VTOP( atari_dma_buffer );
                atari_dma_orig_addr = 0;
        }
-
+#endif
        instance = scsi_register (host, sizeof (struct NCR5380_hostdata));
        atari_scsi_host = instance;
-       instance->irq = IS_A_TT() ? IRQ_TT_MFP_SCSI : IRQ_MFP_FSCSI;
+       /* Set irq to 0, to avoid that the mid-level code disables our interrupt
+        * during queue_command calls. This is completely unnecessary, and even
+        * worse causes bad problems on the Falcon, where the int is shared with
+        * IDE and floppy! */
+       instance->irq = 0;
 
        atari_scsi_reset_boot();
        NCR5380_init (instance, 0);
@@ -693,8 +702,8 @@ int atari_scsi_detect (Scsi_Host_Template *host)
                tt_scsi_dma.dma_ctrl = 0;
                atari_dma_residual = 0;
 #endif /* REAL_DMA */
-
-               if (is_medusa) {
+#ifdef REAL_DMA
+               if (is_medusa || is_hades) {
                        /* While the read overruns (described by Drew Eckhardt in
                         * NCR5380.c) never happened on TTs, they do in fact on the Medusa
                         * (This was the cause why SCSI didn't work right for so long
@@ -709,6 +718,7 @@ int atari_scsi_detect (Scsi_Host_Template *host)
                         */
                        atari_read_overruns = 4;
                }
+#endif
                
        }
        else { /* ! IS_A_TT */
index e46b23f23d2f4cffe6d9651d5e5f629a6e170b46..0380ff99a76971024d28ba3cadc27c41f5398b99 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/blk.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/init.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -639,7 +640,7 @@ static inline void esp_bootup_reset(struct Sparc_ESP *esp, struct Sparc_ESP_regs
 /* Detecting ESP chips on the machine.  This is the simple and easy
  * version.
  */
-int esp_detect(Scsi_Host_Template *tpnt)
+__initfunc(int esp_detect(Scsi_Host_Template *tpnt))
 {
        struct Sparc_ESP *esp, *elink;
        struct Scsi_Host *esp_host;
index e3798b6ab8305946e00f3b7054360d8acb438eee..76da3403fb9a878023daa4641731a64811e9ef8b 100644 (file)
@@ -9,7 +9,7 @@
 #include <asm/pgtable.h>
 #include <asm/amigaints.h>
 #include <asm/amigahw.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 #include <asm/irq.h>
 
 #include "scsi.h"
@@ -204,7 +204,7 @@ int gvp11_detect(Scsi_Host_Template *tpnt)
     struct Scsi_Host *instance;
     caddr_t address;
     enum GVP_ident epc;
-    int key;
+    int key = 0;
     struct ConfigDev *cd;
 
     if (!MACH_IS_AMIGA || called)
@@ -214,9 +214,18 @@ int gvp11_detect(Scsi_Host_Template *tpnt)
     tpnt->proc_dir = &proc_scsi_gvp11;
     tpnt->proc_info = &wd33c93_proc_info;
 
-    while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, 0))) {
+    while ((key = zorro_find(MANUF_GVP, PROD_GVPIISCSI, 0, key))) {
        cd = zorro_get_board(key);
        address = cd->cd_BoardAddr;
+
+       /*
+        * Rumors state that some GVP ram boards use the same product
+        * code as the SCSI controllers. Therefore if the board-size
+        * is not 64KB we asume it is a ram board and bail out.
+        */
+       if (cd->cd_BoardSize != 0x10000)
+               continue;
+
        /* check extended product code */
        epc = *(unsigned short *)(ZTWO_VADDR(address) + 0x8000);
        epc = epc & GVP_PRODMASK;
@@ -237,7 +246,7 @@ int gvp11_detect(Scsi_Host_Template *tpnt)
 
        instance = scsi_register (tpnt, sizeof (struct WD33C93_hostdata));
        instance->base = (unsigned char *)ZTWO_VADDR(address);
-       instance->irq = IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC;
+       instance->irq = IRQ_AMIGA_PORTS;
        instance->unique_id = key;
 
        if (gvp11_xfer_mask)
@@ -307,11 +316,11 @@ Scsi_Host_Template driver_template = GVP11_SCSI;
 int gvp11_release(struct Scsi_Host *instance)
 {
 #ifdef MODULE
-DMA(instance)->CNTR = 0;
-zorro_unconfig_board(instance->unique_id, 0);
-if (--num_gvp11 == 0)
-  free_irq(IRQ_AMIGA_PORTS, gvp11_intr);
-  wd33c93_release();
+    DMA(instance)->CNTR = 0;
+    zorro_unconfig_board(instance->unique_id, 0);
+    if (--num_gvp11 == 0)
+           free_irq(IRQ_AMIGA_PORTS, gvp11_intr);
+    wd33c93_release();
 #endif
-return 1;
+    return 1;
 }
index c1202f87722262d65c81328e574b45cf5818d5bb..e737b812b9284d4d7a09165f6df9df41c78443aa 100644 (file)
@@ -40,7 +40,7 @@
 */
 
 /*
-**     6 April 1997, version 1.18d
+**     16 April 1997, version 1.18e
 **
 **     Supported SCSI-II features:
 **         Synchronous negotiation
@@ -4520,7 +4520,7 @@ static void ncr_start_reset(ncb_p np, int settle_delay)
 **
 **==========================================================
 */
-int ncr_reset_bus (Scsi_Cmnd *cmd)
+int ncr_reset_bus (Scsi_Cmnd *cmd, int sync_reset)
 {
         struct Scsi_Host   *host      = cmd->host;
 /*     Scsi_Device        *device    = cmd->device; */
@@ -4572,11 +4572,12 @@ int ncr_reset_bus (Scsi_Cmnd *cmd)
  */
        ncr_wakeup(np, HS_RESET);
 /*
- * If the involved command was not in a driver queue, and is 
- * not in the waiting list, complete it with DID_RESET status,
+ * If the involved command was not in a driver queue, and the 
+ * scsi driver told us reset is synchronous, and the command is not 
+ * currently in the waiting list, complete it with DID_RESET status,
  * in order to keep it alive.
  */
-       if (!found && cmd && !remove_from_waiting_list(np, cmd)) {
+       if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
                cmd->result = ScsiResult(DID_RESET, 0);
                cmd->scsi_done(cmd);
        }
@@ -6363,27 +6364,13 @@ void ncr_exception (ncb_p np)
                ((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) {
                /*
                **      Unexpected data cycle while waiting for disconnect.
+               **      LDSC and CON bits may help in order to understand 
+               **      what really happened. Print some info message and let 
+               **      the reset function reset the BUS and the NCR.
                */
-               if (INB(nc_sstat2) & LDSC) {
-                       /*
-                       **      It's an early reconnect.
-                       **      Let's continue ...
-                       */
-                       OUTONB (nc_dcntl, (STD|NOCOM));
-                       /*
-                       **      info message
-                       */
-                       printf ("%s: INFO: LDSC while IID.\n",
-                               ncr_name (np));
-                       return;
-               };
-               printf ("%s: target %d doesn't release the bus.\n",
-                       ncr_name (np), (int)INB (nc_ctest0)&0x0f);
-               /*
-               **      return without restarting the NCR.
-               **      timeout will do the real work.
-               */
-               return;
+               printf("%s:%d: data cycle while waiting for disconnect, LDSC=%d CON=%d\n",
+                       ncr_name (np), (int)(INB(nc_ctest0)&0x0f),
+                       (0!=(INB(nc_sstat2)&LDSC)), (0!=(INB(nc_scntl1)&ISCON)));
        };
 
        /*----------------------------------------
@@ -7375,7 +7362,7 @@ out:
 /*==========================================================
 **
 **
-**     Aquire a control block
+**     Acquire a control block
 **
 **
 **==========================================================
@@ -8617,25 +8604,93 @@ static void ncr53c8xx_timeout(unsigned long np)
 **   Linux entry point of reset() function
 */
 
-#if    LINUX_VERSION_CODE >= LinuxVersionCode(1,3,98)
+#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
+
 int ncr53c8xx_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
+{
+       int sts;
+       unsigned long flags;
+
+       printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
+               cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
+
+       save_flags(flags); cli();
+
+       /*
+        * We have to just ignore reset requests in some situations.
+        */
+#if defined SCSI_RESET_NOT_RUNNING
+       if (cmd->serial_number != cmd->serial_number_at_timeout) {
+               sts = SCSI_RESET_NOT_RUNNING;
+               goto out;
+       }
+#endif
+       /*
+        * If the mid-level driver told us reset is synchronous, it seems 
+        * that we must call the done() callback for the involved command, 
+        * even if this command was not queued to the low-level driver, 
+        * before returning SCSI_RESET_SUCCESS.
+        */
+
+       sts = ncr_reset_bus(cmd,
+       (reset_flags & (SCSI_RESET_SYNCHRONOUS | SCSI_RESET_ASYNCHRONOUS)) == SCSI_RESET_SYNCHRONOUS);
+       /*
+        * Since we always reset the controller, when we return success, 
+        * we add this information to the return code.
+        */
+#if defined SCSI_RESET_HOST_RESET
+       if (sts == SCSI_RESET_SUCCESS)
+               sts |= SCSI_RESET_HOST_RESET;
+#endif
+
+out:
+       restore_flags(flags);
+       return sts;
+}
 #else
 int ncr53c8xx_reset(Scsi_Cmnd *cmd)
-#endif
 {
        printk("ncr53c8xx_reset: command pid %lu\n", cmd->pid);
-       return ncr_reset_bus(cmd);
+       return ncr_reset_bus(cmd, 1);
 }
+#endif
 
 /*
 **   Linux entry point of abort() function
 */
 
+#if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS
+
+int ncr53c8xx_abort(Scsi_Cmnd *cmd)
+{
+       int sts;
+       unsigned long flags;
+
+       printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
+               cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
+
+       save_flags(flags); cli();
+
+       /*
+        * We have to just ignore abort requests in some situations.
+        */
+       if (cmd->serial_number != cmd->serial_number_at_timeout) {
+               sts = SCSI_ABORT_NOT_RUNNING;
+               goto out;
+       }
+
+       sts = ncr_abort_command(cmd);
+out:
+       restore_flags(flags);
+       return sts;
+}
+#else
 int ncr53c8xx_abort(Scsi_Cmnd *cmd)
 {
        printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid);
        return ncr_abort_command(cmd);
 }
+#endif
 
 #ifdef MODULE
 int ncr53c8xx_release(struct Scsi_Host *host)
index 28f36400f36e8fdabbe990cb63689ee31fe1b703..7cfcc53c5910bd256af65eb96f50b581b59d544a 100644 (file)
@@ -45,7 +45,7 @@
 /*
 **     Name and revision of the driver
 */
-#define SCSI_NCR_DRIVER_NAME           "ncr53c8xx - revision 1.18d"
+#define SCSI_NCR_DRIVER_NAME           "ncr53c8xx - revision 1.18e"
  
 /*
 **     If SCSI_NCR_SETUP_SPECIAL_FEATURES is defined,
index 011eb6dd131f54198a394123d0bdf0c4771498ad..581f280e8fbeffc60c8e31fa3546adf231baef07 100644 (file)
@@ -1132,69 +1132,72 @@ int ppa_detect(Scsi_Host_Template * host)
        nhosts = 0;
 
        for (i = 0; pb; i++, pb=pb->next) {
-               int modes;
-
-               /* transfer global values here */
-               if (ppa_speed >= 0)
-                       ppa_hosts[i].speed = ppa_speed;
-               if (ppa_speed_fast >= 0)
-                       ppa_hosts[i].speed_fast = ppa_speed_fast;
-
-               ppa_hosts[i].dev =
-                   parport_register_device(pb, "ppa", NULL, ppa_wakeup,
-                             NULL, PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]);
-
-               /* Claim the bus so it remembers what we do to the control
-                * registers. [ CTR and ECP ]
-                */
-               ppa_pb_claim(i);
-               w_ctr(i, 0x0c);
-               modes = ppa_hosts[i].dev->port->modes;
-
-               ppa_hosts[i].mode = PPA_NIBBLE;
-               if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) {
-                       ppa_hosts[i].mode = PPA_EPP_32;
-                       printk("PPA: Parport [ EPP ]\n");
-               } else if (modes & PARPORT_MODE_ECP) {
-                       w_ecr(i, 0x20);
-                       ppa_hosts[i].mode = PPA_PS2;
-                       printk("PPA: Parport [ ECP in PS2 submode ]\n");
-               } else if (modes & PARPORT_MODE_PS2) {
-                       ppa_hosts[i].mode = PPA_PS2;
-                       printk("PPA: Parport [ PS2 ]\n");
-               }
-               /* Done configuration */
-               ppa_pb_release(i);
+               int modes = pb->modes;
+
+               /* We only understand PC-style ports */
+               if (modes & PARPORT_MODE_SPP) {
+
+                       /* transfer global values here */
+                       if (ppa_speed >= 0)
+                               ppa_hosts[i].speed = ppa_speed;
+                       if (ppa_speed_fast >= 0)
+                               ppa_hosts[i].speed_fast = ppa_speed_fast;
+                       
+                       ppa_hosts[i].dev = parport_register_device(pb, "ppa", 
+                                   NULL, ppa_wakeup, NULL,
+                                   PARPORT_DEV_TRAN, (void *) &ppa_hosts[i]);
+                       
+                       /* Claim the bus so it remembers what we do to the
+                        * control registers. [ CTR and ECP ]
+                        */
+                       ppa_pb_claim(i);
+                       w_ctr(i, 0x0c);
+
+                       ppa_hosts[i].mode = PPA_NIBBLE;
+                       if (modes & (PARPORT_MODE_EPP | PARPORT_MODE_ECPEPP)) {
+                               ppa_hosts[i].mode = PPA_EPP_32;
+                               printk("PPA: Parport [ EPP ]\n");
+                       } else if (modes & PARPORT_MODE_ECP) {
+                               w_ecr(i, 0x20);
+                               ppa_hosts[i].mode = PPA_PS2;
+                               printk("PPA: Parport [ ECP in PS2 submode ]\n");
+                       } else if (modes & PARPORT_MODE_PS2) {
+                               ppa_hosts[i].mode = PPA_PS2;
+                               printk("PPA: Parport [ PS2 ]\n");
+                       }
+                       /* Done configuration */
+                       ppa_pb_release(i);
 
-               rs = ppa_init(i);
-               if (rs) {
-                       parport_unregister_device(ppa_hosts[i].dev);
-                       continue;
-               }
-               /* now the glue ... */
-               switch (ppa_hosts[i].mode) {
-               case PPA_NIBBLE:
-               case PPA_PS2:
-                       ports = 3;
-                       break;
-               case PPA_EPP_8:
-               case PPA_EPP_16:
-               case PPA_EPP_32:
-                       ports = 8;
-                       break;
-               default:        /* Never gets here */
-                       continue;
+                       rs = ppa_init(i);
+                       if (rs) {
+                               parport_unregister_device(ppa_hosts[i].dev);
+                               continue;
+                       }
+                       /* now the glue ... */
+                       switch (ppa_hosts[i].mode) {
+                       case PPA_NIBBLE:
+                       case PPA_PS2:
+                               ports = 3;
+                               break;
+                       case PPA_EPP_8:
+                       case PPA_EPP_16:
+                       case PPA_EPP_32:
+                               ports = 8;
+                               break;
+                       default:        /* Never gets here */
+                               continue;
+                       }
+                       
+                       host->can_queue = PPA_CAN_QUEUE;
+                       host->sg_tablesize = ppa_sg;
+                       hreg = scsi_register(host, 0);
+                       hreg->io_port = pb->base;
+                       hreg->n_io_port = ports;
+                       hreg->dma_channel = -1;
+                       hreg->unique_id = i;
+                       ppa_hosts[i].host = hreg->host_no;
+                       nhosts++;
                }
-
-               host->can_queue = PPA_CAN_QUEUE;
-               host->sg_tablesize = ppa_sg;
-               hreg = scsi_register(host, 0);
-               hreg->io_port = pb->base;
-               hreg->n_io_port = ports;
-               hreg->dma_channel = -1;
-               hreg->unique_id = i;
-               ppa_hosts[i].host = hreg->host_no;
-               nhosts++;
        }
        if (nhosts == 0)
                return 0;
index 145f4280be2ac557889c5f1fa0785fb857dcf1a6..54658955fe544184e488f54a1d8fc13e9ab11664 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/blk.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/init.h>
 
 #include <asm/byteorder.h>
 
@@ -342,7 +343,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
 
 #define PTI_RESET_LIMIT 400
 
-static int qlogicpti_load_firmware(struct qlogicpti *qpti)
+__initfunc(static int qlogicpti_load_firmware(struct qlogicpti *qpti))
 {
        struct qlogicpti_regs *qregs = qpti->qregs;
        unsigned short csum = 0;
@@ -561,7 +562,7 @@ static inline void qlogicpti_set_hostdev_defaults(struct qlogicpti *qpti)
 static void qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs);
 
 /* Detect all PTI Qlogic ISP's in the machine. */
-int qlogicpti_detect(Scsi_Host_Template *tpnt)
+__initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt))
 {
        struct qlogicpti *qpti, *qlink;
        struct Scsi_Host *qpti_host;
index 4d9bb001e63d23c43eb887975d4ec4f6d97244e8..b6e48a06ae34e3362b5b51bfc1322c9741ee0544 100644 (file)
@@ -2,7 +2,7 @@
 
 unsigned short risc_code_addr01 = 0x1000;
 
-unsigned short risc_code01[] = {
+unsigned short risc_code01[] __initdata = {
        0x0078, 0x1030, 0x0000, 0x231f, 0x0000, 0x12ff, 0x2043, 0x4f50,
        0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932,
        0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749,
index 4723ad2e949c1d48abe313c7496761890e8e37c9..91560bc896bc956104cd62d511fb381bae5ed68c 100644 (file)
@@ -28,9 +28,9 @@
  *
  *    -  Target Disconnection/Reconnection  is now supported. Any
  *          system with more than one device active on the SCSI bus
- *          will benefit from this. The driver defaults to what I'm
- *          'adaptive disconnect' - meaning that each command is
- *          evaluated individually as to whether or not it should
+ *          will benefit from this. The driver defaults to what I
+ *          call 'adaptive disconnect' - meaning that each command
+ *          is evaluated individually as to whether or not it should
  *          be run with the option to disconnect/reselect (if the
  *          device chooses), or as a "SCSI-bus-hog".
  *
 #include "hosts.h"
 
 
-#define PROC_INTERFACE     /* add code for /proc/scsi/wd33c93/xxx interface */
-#ifdef  PROC_INTERFACE
-#define PROC_STATISTICS    /* add code for keeping various real time stats */
-#endif
-
-#define SYNC_DEBUG         /* extra info on sync negotiation printed */
-#undef DEBUGGING_ON        /* enable command-line debugging bitmask */
-#define DEBUG_DEFAULTS 0   /* default debugging bitmask */
-
-#define WD33C93_VERSION    "1.23"
-#define WD33C93_DATE       "04/Nov/1996"
+#define WD33C93_VERSION    "1.24"
+#define WD33C93_DATE       "29/Jan/1997"
 
-#ifdef DEBUGGING_ON
-#define DB(f,a) if (hostdata->args & (f)) a;
-#else
-#define DB(f,a)
-#endif
+/*
+ * Note - the following defines have been moved to 'wd33c93.h':
+ *
+ *    PROC_INTERFACE
+ *    PROC_STATISTICS
+ *    SYNC_DEBUG
+ *    DEBUGGING_ON
+ *    DEBUG_DEFAULTS
+ *
+ */
 
 
 #include "wd33c93.h"
  * keywords (lower case required) and arguments:
  *
  * -  nosync:bitmask -bitmask is a byte where the 1st 7 bits correspond with
- *                    the 7 possible SCSI devices. Set a bit to prevent sync
- *                    negotiation on that device. To maintain backwards
- *                    compatibility, a command-line such as "wd33c93=255" will
- *                    be automatically translated to "wd33c93=nosync:0xff".
+ *                    the 7 possible SCSI devices. Set a bit to negotiate for
+ *                    asynchronous transfers on that device. To maintain
+ *                    backwards compatibility, a command-line such as
+ *                    "wd33c93=255" will be automatically translated to
+ *                    "wd33c93=nosync:0xff".
  * -  nodma:x        -x = 1 to disable DMA, x = 0 to enable it. Argument is
  *                    optional - if not present, same as "nodma:1".
  * -  period:ns      -ns is the minimum # of nanoseconds in a SCSI data transfer
@@ -166,7 +163,7 @@ static char *setup_strings[] =
 
 
 
-inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num)
+static inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num)
 {
    regp->SASR = reg_num;
    return(regp->SCMD);
@@ -176,21 +173,21 @@ inline uchar read_wd33c93(wd33c93_regs *regp,uchar reg_num)
 #define READ_AUX_STAT() (regp->SASR)
 
 
-inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value)
+static inline void write_wd33c93(wd33c93_regs *regp,uchar reg_num, uchar value)
 {
    regp->SASR = reg_num;
    regp->SCMD = value;
 }
 
 
-inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd)
+static inline void write_wd33c93_cmd(wd33c93_regs *regp, uchar cmd)
 {
    regp->SASR = WD_COMMAND;
    regp->SCMD = cmd;
 }
 
 
-inline uchar read_1_byte(wd33c93_regs *regp)
+static inline uchar read_1_byte(wd33c93_regs *regp)
 {
 uchar asr;
 uchar x = 0;
@@ -206,7 +203,7 @@ uchar x = 0;
 }
 
 
-void write_wd33c93_count(wd33c93_regs *regp,unsigned long value)
+static void write_wd33c93_count(wd33c93_regs *regp,unsigned long value)
 {
    regp->SASR = WD_TRANSFER_COUNT_MSB;
    regp->SCMD = value >> 16;
@@ -215,7 +212,7 @@ void write_wd33c93_count(wd33c93_regs *regp,unsigned long value)
 }
 
 
-unsigned long read_wd33c93_count(wd33c93_regs *regp)
+static unsigned long read_wd33c93_count(wd33c93_regs *regp)
 {
 unsigned long value;
 
@@ -265,7 +262,7 @@ static struct sx_period sx_table[] = {
    {1000,0x00},
    {0,   0} };
 
-int round_period(unsigned int period)
+static int round_period(unsigned int period)
 {
 int x;
 
@@ -278,7 +275,7 @@ int x;
    return 7;
 }
 
-uchar calc_sync_xfer(unsigned int period, unsigned int offset)
+static uchar calc_sync_xfer(unsigned int period, unsigned int offset)
 {
 uchar result;
 
@@ -290,14 +287,13 @@ uchar result;
 
 
 
-void wd33c93_execute(struct Scsi_Host *instance);
+static void wd33c93_execute(struct Scsi_Host *instance);
 
 int wd33c93_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
-struct WD33C93_hostdata *hostdata;
-Scsi_Cmnd *tmp;
-
-   disable_irq(cmd->host->irq);
+   struct WD33C93_hostdata *hostdata;
+   Scsi_Cmnd *tmp;
+   unsigned long flags;
 
    hostdata = (struct WD33C93_hostdata *)cmd->host->hostdata;
 
@@ -351,6 +347,9 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld( ",cmd->target,cmd->cmnd[0],cmd->pid))
     * sense data is not lost before REQUEST_SENSE executes.
     */
 
+   save_flags(flags);
+   cli();
+
    if (!(hostdata->input_Q) || (cmd->cmnd[0] == REQUEST_SENSE)) {
       cmd->host_scribble = (uchar *)hostdata->input_Q;
       hostdata->input_Q = cmd;
@@ -370,7 +369,7 @@ DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld( ",cmd->target,cmd->cmnd[0],cmd->pid))
 
 DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
 
-   enable_irq(cmd->host->irq);
+   restore_flags(flags);
    return 0;
 }
 
@@ -381,15 +380,18 @@ DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
  * already connected, we give up immediately. Otherwise, look through
  * the input_Q, using the first command we find that's intended
  * for a currently non-busy target/lun.
+ *
+ * wd33c93_execute() is always called with interrupts disabled or from
+ * the wd33c93_intr itself, which means that a wd33c93 interrupt
+ * cannot occur while we are in here.
  */
-void wd33c93_execute (struct Scsi_Host *instance)
+static void wd33c93_execute (struct Scsi_Host *instance)
 {
 struct WD33C93_hostdata *hostdata;
 wd33c93_regs *regp;
 Scsi_Cmnd *cmd, *prev;
 int i;
 
-   disable_irq(instance->irq);
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
    regp = hostdata->regp;
 
@@ -399,7 +401,6 @@ DB(DB_EXECUTE,printk("EX("))
 
 DB(DB_EXECUTE,printk(")EX-0 "))
 
-      enable_irq(instance->irq);
       return;
       }
 
@@ -423,7 +424,6 @@ DB(DB_EXECUTE,printk(")EX-0 "))
 
 DB(DB_EXECUTE,printk(")EX-1 "))
 
-      enable_irq(instance->irq);
       return;
       }
 
@@ -500,6 +500,7 @@ yes:
 #endif
 
 no:
+
    write_wd33c93(regp, WD_SOURCE_ID, ((cmd->SCp.phase)?SRCID_ER:0));
 
    write_wd33c93(regp, WD_TARGET_LUN, cmd->lun);
@@ -525,17 +526,14 @@ no:
  * sync_xfer[] entry is initialized to the default/safe value. SS_UNSET
  * means that the parameters are undetermined as yet, and that we
  * need to send an SDTR message to this device after selection is
- * complete. We set SS_FIRST to tell the interrupt routine to do so,
- * unless we've been asked not to try synchronous transfers on this
- * target (and _all_ luns within it): In this case we set SS_SET to
- * make the defaults final.
+ * complete: We set SS_FIRST to tell the interrupt routine to do so.
+ * If we've been asked not to try synchronous transfers on this
+ * target (and _all_ luns within it), we'll still send the SDTR message
+ * later, but at that time we'll negotiate for async by specifying a
+ * sync fifo depth of 0.
  */
-      if (hostdata->sync_stat[cmd->target] == SS_UNSET) {
-         if (hostdata->no_sync & (1 << cmd->target))
-            hostdata->sync_stat[cmd->target] = SS_SET;
-         else
+      if (hostdata->sync_stat[cmd->target] == SS_UNSET)
             hostdata->sync_stat[cmd->target] = SS_FIRST;
-         }
       hostdata->state = S_SELECTING;
       write_wd33c93_count(regp,0); /* guarantee a DATA_PHASE interrupt */
       write_wd33c93_cmd(regp, WD_CMD_SEL_ATN);
@@ -600,13 +598,11 @@ no:
     */
       
 DB(DB_EXECUTE,printk("%s%ld)EX-2 ",(cmd->SCp.phase)?"d:":"",cmd->pid))
-
-   enable_irq(instance->irq);
 }
 
 
 
-void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt,
+static void transfer_pio(wd33c93_regs *regp, uchar *buf, int cnt,
                   int data_in_dir, struct WD33C93_hostdata *hostdata)
 {
 uchar asr;
@@ -642,7 +638,7 @@ DB(DB_TRANSFER,printk("(%p,%d,%s:",buf,cnt,data_in_dir?"in":"out"))
 
 
 
-void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir)
+static void transfer_bytes(wd33c93_regs *regp, Scsi_Cmnd *cmd, int data_in_dir)
 {
 struct WD33C93_hostdata *hostdata;
 unsigned long length;
@@ -725,7 +721,7 @@ struct WD33C93_hostdata *hostdata;
 Scsi_Cmnd *patch, *cmd;
 wd33c93_regs *regp;
 uchar asr, sr, phs, id, lun, *ucp, msg;
-unsigned long length;
+unsigned long length, flags;
 
    hostdata = (struct WD33C93_hostdata *)instance->hostdata;
    regp = hostdata->regp;
@@ -734,6 +730,8 @@ unsigned long length;
    if (!(asr & ASR_INT) || (asr & ASR_BSY))
       return;
 
+   save_flags(flags);
+
 #ifdef PROC_STATISTICS
    hostdata->int_cnt++;
 #endif
@@ -776,7 +774,6 @@ DB(DB_TRANSFER,printk("%p/%d]",cmd->SCp.ptr,cmd->SCp.this_residual))
       case CSR_TIMEOUT:
 DB(DB_INTR,printk("TIMEOUT"))
 
-         disable_irq(instance->irq);
          if (hostdata->state == S_RUNNING_LEVEL2)
             hostdata->connected = NULL;
          else {
@@ -789,11 +786,22 @@ DB(DB_INTR,printk("TIMEOUT"))
          hostdata->state = S_UNCONNECTED;
          cmd->scsi_done(cmd);
 
+        /* From esp.c:
+         * There is a window of time within the scsi_done() path
+         * of execution where interrupts are turned back on full
+         * blast and left that way.  During that time we could
+         * reconnect to a disconnected command, then we'd bomb
+         * out below.  We could also end up executing two commands
+         * at _once_.  ...just so you know why the restore_flags()
+         * is here...
+         */
+
+        restore_flags(flags);
+
 /* We are not connected to a target - check to see if there
  * are commands waiting to be executed.
  */
 
-        enable_irq(instance->irq);
          wd33c93_execute(instance);
          break;
 
@@ -801,7 +809,6 @@ DB(DB_INTR,printk("TIMEOUT"))
 /* Note: this interrupt should not occur in a LEVEL2 command */
 
       case CSR_SELECT:
-        disable_irq(instance->irq);
 
 DB(DB_INTR,printk("SELECT"))
          hostdata->connected = cmd = (Scsi_Cmnd *)hostdata->selecting;
@@ -820,13 +827,23 @@ printk(" sending SDTR ");
 
             hostdata->sync_stat[cmd->target] = SS_WAITING;
 
-      /* tack on a 2nd message to ask about synchronous transfers */
+/* Tack on a 2nd message to ask about synchronous transfers. If we've
+ * been asked to do only asynchronous transfers on this device, we
+ * request a fifo depth of 0, which is equivalent to async - should
+ * solve the problems some people have had with GVP's Guru ROM.
+ */
 
             hostdata->outgoing_msg[1] = EXTENDED_MESSAGE;
             hostdata->outgoing_msg[2] = 3;
             hostdata->outgoing_msg[3] = EXTENDED_SDTR;
+            if (hostdata->no_sync & (1 << cmd->target)) {
+               hostdata->outgoing_msg[4] = hostdata->default_sx_per/4;
+               hostdata->outgoing_msg[5] = 0;
+               }
+            else {
             hostdata->outgoing_msg[4] = OPTIMUM_SX_PER/4;
             hostdata->outgoing_msg[5] = OPTIMUM_SX_OFF;
+               }
             hostdata->outgoing_len = 6;
             }
          else
@@ -891,7 +908,6 @@ DB(DB_INTR,printk("=%02x",cmd->SCp.Status))
       case CSR_SRV_REQ  |PHS_MESS_IN:
 DB(DB_INTR,printk("MSG_IN="))
 
-         disable_irq(instance->irq);
          msg = read_1_byte(regp);
          sr = read_wd33c93(regp, WD_SCSI_STATUS);  /* clear interrupt */
 
@@ -1034,13 +1050,13 @@ printk("sync_xfer=%02x",hostdata->sync_xfer[cmd->target]);
                write_wd33c93_cmd(regp,WD_CMD_NEGATE_ACK);
                hostdata->state = S_CONNECTED;
             }
+         restore_flags(flags);
          break;
 
 
 /* Note: this interrupt will occur only after a LEVEL2 command */
 
       case CSR_SEL_XFER_DONE:
-         disable_irq(instance->irq);
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
@@ -1065,7 +1081,7 @@ DB(DB_INTR,printk("SX-DONE-%ld",cmd->pid))
 /* We are no longer  connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-           enable_irq(instance->irq);
+           restore_flags(flags);
             wd33c93_execute(instance);
             }
          else {
@@ -1124,8 +1140,6 @@ DB(DB_INTR,printk("%02x",hostdata->outgoing_msg[0]))
  * so we treat it as a normal command-complete-disconnect.
  */
 
-         disable_irq(instance->irq);
-
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
  */
@@ -1149,13 +1163,13 @@ DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-         enable_irq(instance->irq);
+        /* look above for comments on scsi_done() */
+        restore_flags(flags);
          wd33c93_execute(instance);
          break;
 
 
       case CSR_DISC:
-         disable_irq(instance->irq);
 
 /* Make sure that reselection is enabled at this point - it may
  * have been turned off for the command that just completed.
@@ -1177,6 +1191,7 @@ DB(DB_INTR,printk("DISC-%ld",cmd->pid))
                else if (cmd->SCp.Status != GOOD)
                   cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
                cmd->scsi_done(cmd);
+              restore_flags(flags);
                break;
             case S_PRE_TMP_DISC:
             case S_RUNNING_LEVEL2:
@@ -1198,7 +1213,6 @@ DB(DB_INTR,printk("DISC-%ld",cmd->pid))
 /* We are no longer connected to a target - check to see if
  * there are commands waiting to be executed.
  */
-         enable_irq(instance->irq);
          wd33c93_execute(instance);
          break;
 
@@ -1206,8 +1220,6 @@ DB(DB_INTR,printk("DISC-%ld",cmd->pid))
       case CSR_RESEL_AM:
 DB(DB_INTR,printk("RESEL"))
 
-         disable_irq(instance->irq);
-
    /* First we have to make sure this reselection didn't */
    /* happen during Arbitration/Selection of some other device. */
    /* If yes, put losing command back on top of input_Q. */
@@ -1306,15 +1318,13 @@ DB(DB_INTR,printk("-%ld",cmd->pid))
          printk("--UNKNOWN INTERRUPT:%02x:%02x:%02x--",asr,sr,phs);
       }
 
-   enable_irq(instance->irq);
-
 DB(DB_INTR,printk("} "))
 
 }
 
 
 
-void reset_wd33c93(struct Scsi_Host *instance)
+static void reset_wd33c93(struct Scsi_Host *instance)
 {
 struct WD33C93_hostdata *hostdata;
 wd33c93_regs *regp;
@@ -1595,7 +1605,7 @@ char *p1,*p2;
 /* check_setup_strings() returns index if key found, 0 if not
  */
 
-int check_setup_strings(char *key, int *flags, int *val, char *buf)
+static int check_setup_strings(char *key, int *flags, int *val, char *buf)
 {
 int x;
 char *cp;
@@ -1724,16 +1734,17 @@ char buf[32];
    reset_wd33c93(instance);
    sti();
 
-   printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d\n",instance->host_no,
+   printk("wd33c93-%d: chip=%s/%d no_sync=0x%x no_dma=%d",instance->host_no,
          (hostdata->chip==C_WD33C93)?"WD33c93":
          (hostdata->chip==C_WD33C93A)?"WD33c93A":
          (hostdata->chip==C_WD33C93B)?"WD33c93B":"unknown",
          hostdata->microcode,hostdata->no_sync,hostdata->no_dma);
 #ifdef DEBUGGING_ON
-   printk("           debug_flags=0x%02x setup_strings=",hostdata->args);
+   printk(" debug_flags=0x%02x\n",hostdata->args);
 #else
-   printk("           debugging=OFF setup_strings=");
+   printk(" debugging=OFF\n");
 #endif
+   printk("           setup_strings=");
    for (i=0; i<MAX_SETUP_STRINGS; i++)
       printk("%s,",setup_strings[i]);
    printk("\n");
index c2b214bf543532eb098d2346ca4c0c60c594eb25..acf10d2f1c3f7de05f33f5766342cea29b814d22 100644 (file)
@@ -2,7 +2,7 @@
  *    wd33c93.h -  Linux device driver definitions for the
  *                 Commodore Amiga A2091/590 SCSI controller card
  *
- *    IMPORTANT: This file is for version 1.23 - 04/Nov/1996
+ *    IMPORTANT: This file is for version 1.24 - 29/Jan/1997
  *
  * Copyright (c) 1996 John Shifflett, GeoLog Consulting
  *    john@geolog.com
 #define WD33C93_H
 
 
+#define PROC_INTERFACE     /* add code for /proc/scsi/wd33c93/xxx interface */
+#ifdef  PROC_INTERFACE
+#define PROC_STATISTICS    /* add code for keeping various real time stats */
+#endif
+
+#define SYNC_DEBUG         /* extra info on sync negotiation printed */
+#define DEBUGGING_ON       /* enable command-line debugging bitmask */
+#define DEBUG_DEFAULTS 0   /* default debugging bitmask */
+
+
+#ifdef DEBUGGING_ON
+#define DB(f,a) if (hostdata->args & (f)) a;
+#else
+#define DB(f,a)
+#endif
+
 #define uchar unsigned char
 
 
@@ -231,13 +247,17 @@ struct WD33C93_hostdata {
     uchar            sync_stat[8];     /* status of sync negotiation per target */
     uchar            no_sync;          /* bitmask: don't do sync on these targets */
     uchar            no_dma;           /* set this flag to disable DMA */
+#ifdef PROC_INTERFACE
     uchar            proc;             /* bitmask: what's in proc output */
+#ifdef PROC_STATISTICS
     unsigned long    cmd_cnt[8];       /* # of commands issued per target */
     unsigned long    int_cnt;          /* # of interrupts serviced */
     unsigned long    pio_cnt;          /* # of pio data transfers */
     unsigned long    dma_cnt;          /* # of DMA data transfers */
     unsigned long    disc_allowed_cnt[8]; /* # of disconnects allowed per target */
     unsigned long    disc_done_cnt[8]; /* # of disconnects done per target*/
+#endif
+#endif
     };
 
 
index 0c11f3109741e5cbbf1b9d4fde2b4f5b006da1ae..9b6626f7da20d56d7a66e4216cc77f17bf292efd 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/amigaffs.h>
 #include <linux/major.h>
 #include <linux/blkdev.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
@@ -987,8 +988,7 @@ static struct file_system_type affs_fs_type = {
        NULL
 };
 
-int
-init_affs_fs(void)
+__initfunc(int init_affs_fs(void))
 {
        return register_filesystem(&affs_fs_type);
 }
index 2d44d1e388c2c7c1b5d6de4049a2a8539706ca05..a4857cb99a1933cf8b51cfdfb2ad6fb82e85c6dc 100644 (file)
@@ -10,7 +10,6 @@
  *
  * ------------------------------------------------------------------------- */
 
-#include <linux/modversions.h>
 #include <linux/module.h>
 #include <linux/auto_fs.h>
 
index 697f3cfd8976a772120b4ee7fdbc04f843f3e7b6..d9ef6d6acd755e0b2d0fb150fafac68d56bdd827 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/malloc.h>
 #include <linux/binfmts.h>
 #include <linux/personality.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -89,7 +90,7 @@ do_aout_core_dump(long signr, struct pt_regs * regs)
 #       define START_DATA(u)   (u.start_data)
 #elif defined(__sparc__)
 #       define START_DATA(u)    (u.u_tsize)
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__mc68000__)
 #       define START_DATA(u)   (u.u_tsize << PAGE_SHIFT)
 #endif
 #ifdef __sparc__
@@ -555,7 +556,8 @@ load_aout_library(int fd)
 }
 
 
-int init_aout_binfmt(void) {
+__initfunc(int init_aout_binfmt(void))
+{
        return register_binfmt(&aout_format);
 }
 
index f2ae27a7cd64f4becd7d71e5646ec892b4f36934..7e11c751066b38015c05b08c2824158c82821e4b 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/shm.h>
 #include <linux/personality.h>
 #include <linux/elfcore.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -1124,7 +1125,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 #else
        if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
        {
-               printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) (%d)\n",
+               printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
                        sizeof(elf_gregset_t), sizeof(struct pt_regs));
        }
        else
@@ -1276,7 +1277,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 }
 #endif         /* USE_ELF_CORE_DUMP */
 
-int init_elf_binfmt(void)
+__initfunc(int init_elf_binfmt(void))
 {
        return register_binfmt(&elf_format);
 }
index 6e014588d2ecf5ccb7256d3d06990a799506db2b..e724ddd074b53346edc5530242db37f222b06673 100644 (file)
@@ -100,11 +100,12 @@ struct linux_binfmt em86_format = {
 #ifndef MODULE
        NULL, 0, load_em86, NULL, NULL
 #else
-       NULL, &mod_use_count_, load_em86, NULL, NULL
+       NULL, &__this_module, load_em86, NULL, NULL
 #endif
 };
 
-int init_em86_binfmt(void) {
+__initfunc(int init_em86_binfmt(void))
+{
        return register_binfmt(&em86_format);
 }
 
index 75b4eef03c665e5019ad166101fda95d53b1dfb6..fcf664c5d4e16af232375b9be46d449d4d78aac5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/stat.h>
 #include <linux/malloc.h>
 #include <linux/binfmts.h>
+#include <linux/init.h>
 
 #define _PATH_JAVA     "/usr/bin/java"
 #define _PATH_APPLET   "/usr/bin/appletviewer"
@@ -165,7 +166,8 @@ static struct linux_binfmt applet_format = {
 #endif
 };
 
-int init_java_binfmt(void) {
+__initfunc(int init_java_binfmt(void))
+{
        register_binfmt(&java_format);
        return register_binfmt(&applet_format);
 }
index bae184714aa580bbb0700352891664df7eb3e4e6..1bd2f0d10bc77d1939a8c2390fac131ab80a1ba5 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/stat.h>
 #include <linux/malloc.h>
 #include <linux/binfmts.h>
+#include <linux/init.h>
 
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
@@ -103,7 +104,8 @@ struct linux_binfmt script_format = {
 #endif
 };
 
-int init_script_binfmt(void) {
+__initfunc(int init_script_binfmt(void))
+{
        return register_binfmt(&script_format);
 }
 
index b1bf3345c5c216114d8d74eda65704fa5f277a22..4af3e8a631055ad255820dffa6a31a12cfbdfc39 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -41,6 +41,7 @@
 #include <linux/personality.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -65,7 +66,7 @@ asmlinkage int sys_brk(unsigned long);
 
 static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
 
-void binfmt_setup(void)
+__initfunc(void binfmt_setup(void))
 {
 #ifdef CONFIG_BINFMT_ELF
        init_elf_binfmt();
@@ -533,7 +534,7 @@ int prepare_binprm(struct linux_binprm *bprm)
                if (IS_NOSUID(bprm->inode)
                    || (current->flags & PF_PTRACED)
                    || (current->fs->count > 1)
-                   || (current->sig->count > 1)
+                   || (atomic_read(&current->sig->count) > 1)
                    || (current->files->count > 1)) {
                        if (!suser())
                                return -EPERM;
index b23c6530deb3959ebaa45f5ebb6221f43a4a2347..26e18852edcccae50bba979afcc4f0373c37dbd8 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/blkdev.h>
+#include <linux/init.h>
 
 static char error_buf[1024];
 
@@ -727,7 +728,7 @@ static struct file_system_type ext2_fs_type = {
         ext2_read_super, "ext2", 1, NULL
 };
 
-int init_ext2_fs(void)
+__initfunc(int init_ext2_fs(void))
 {
         return register_filesystem(&ext2_fs_type);
 }
index f66a53f4abf4551cf9d381f75b99ca329b76c615..5bc73819c75075cba2f995fe07849b8faee9ad57 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/locks.h>
 #include <linux/stat.h>
 #include <linux/string.h>
+#include <linux/init.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
@@ -1748,7 +1749,7 @@ static struct file_system_type hpfs_fs_type = {
         hpfs_read_super, "hpfs", 1, NULL
 };
 
-int init_hpfs_fs(void)
+__initfunc(int init_hpfs_fs(void))
 {
         return register_filesystem(&hpfs_fs_type);
 }
index dbf9c9920a1a32f8c9f5e96c00129d6c9e286d91..7a4943edec73200f4078c1dca9d7415a99b7fcae 100644 (file)
@@ -155,6 +155,11 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                        filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
                                       + ISOFS_BLOCK_SIZE);
                        offset = 0;
+                       if( filp->f_pos >= inode->i_size )
+                         {
+                           return 0;
+                         }
+
                        block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
                        if (!block)
                                return 0;
index de50e03244eacde7f5cb6b051f115d3a6335f46a..8d9ce9d969b00f8e2752cc0d6cacefcbcf8f52c6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/malloc.h>
 #include <linux/errno.h>
 #include <linux/cdrom.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -920,7 +921,7 @@ static struct file_system_type iso9660_fs_type = {
        isofs_read_super, "iso9660", 1, NULL
 };
 
-int init_iso9660_fs(void)
+__initfunc(int init_iso9660_fs(void))
 {
         return register_filesystem(&iso9660_fs_type);
 }
index 8cdadf83684eefe02d4b0b7e5849255d04676ae2..71f816b47b1d927642166b63c7d360ee2585ec66 100644 (file)
@@ -98,6 +98,12 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
                        offset = 0;
                        f_pos = ((f_pos & ~(ISOFS_BLOCK_SIZE - 1))
                                 + ISOFS_BLOCK_SIZE);
+
+                       if( f_pos >= dir->i_size )
+                         {
+                           return 0;
+                         }
+
                        block = isofs_bmap(dir,f_pos>>bufbits);
                        if (!block || !(bh = bread(dir->i_dev,block,bufsize)))
                                return 0;
index 7d2d1665fc192d872ffa7669f482cd1bdf16225d..027c230a8423d06d68cd310d8930b65899a93b5d 100644 (file)
@@ -21,7 +21,7 @@
 #define NLM_HOST_MAX           64
 #define NLM_HOST_NRHASH                32
 #define NLM_ADDRHASH(addr)     (ntohl(addr) & (NLM_HOST_NRHASH-1))
-#define NLM_PTRHASH(ptr)       ((((u32) ptr) / 32) & (NLM_HOST_NRHASH-1))
+#define NLM_PTRHASH(ptr)       ((((u32)(unsigned long) ptr) / 32) & (NLM_HOST_NRHASH-1))
 #define NLM_HOST_REBIND                (60 * HZ)
 #define NLM_HOST_EXPIRE                ((nrhosts > NLM_HOST_MAX)? 300 * HZ : 120 * HZ)
 #define NLM_HOST_COLLECT       ((nrhosts > NLM_HOST_MAX)? 120 * HZ :  60 * HZ)
@@ -81,8 +81,8 @@ nlm_lookup_host(struct svc_client *clnt, struct sockaddr_in *sin,
                return NULL;
        }
 
-       dprintk("lockd: nlm_lookup_host(%08lx, p=%d, v=%d)\n",
-                       sin? ntohl(sin->sin_addr.s_addr) : 0, proto, version);
+       dprintk("lockd: nlm_lookup_host(%08x, p=%d, v=%d)\n",
+                       (unsigned)(sin? ntohl(sin->sin_addr.s_addr) : 0), proto, version);
 
        if (clnt)
                hash = NLM_PTRHASH(clnt);
@@ -164,8 +164,8 @@ nlm_bind_host(struct nlm_host *host)
        struct rpc_clnt *clnt;
        struct rpc_xprt *xprt;
 
-       dprintk("lockd: nlm_bind_host(%08lx)\n",
-                       ntohl(host->h_addr.sin_addr.s_addr));
+       dprintk("lockd: nlm_bind_host(%08x)\n",
+                       (unsigned)ntohl(host->h_addr.sin_addr.s_addr));
 
        /* Lock host handle */
        down(&host->h_sema);
index 77ca134a24d2d9b957966a89b531c8ef61732695..fc133b51ea1c22f1bf5d02e6d41da932004818a5 100644 (file)
@@ -130,8 +130,8 @@ lockd(struct svc_rqst *rqstp)
                        break;
                }
 
-               dprintk("lockd: request from %08lx\n",
-                               ntohl(rqstp->rq_addr.sin_addr.s_addr));
+               dprintk("lockd: request from %08x\n",
+                               (unsigned)ntohl(rqstp->rq_addr.sin_addr.s_addr));
 
                /*
                 * Look up the NFS client handle. The handle is needed for
index 3474c20b87e8ea5a2fa03bb6fac9dbdc5094fb6f..faf5ce8a4f9f81409ed4c2d9b412dead81a3a526 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -946,7 +947,7 @@ static struct file_system_type minix_fs_type = {
        minix_read_super, "minix", 1, NULL
 };
 
-int init_minix_fs(void)
+__initfunc(int init_minix_fs(void))
 {
         return register_filesystem(&minix_fs_type);
 }
index bdcc0a518478488d0bb03143b1ff5c134ac23234..914a178a9bce3a150a5439a293c79f5b38d8e5d2 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/mm.h>
 #include <linux/msdos_fs.h>
+#include <linux/init.h>
 
 /*
  * Support for umsdos fs
@@ -33,7 +34,7 @@ static struct file_system_type msdos_fs_type = {
        msdos_read_super, "msdos", 1, NULL
 };
 
-int init_msdos_fs(void)
+__initfunc(int init_msdos_fs(void))
 {
        return register_filesystem(&msdos_fs_type);
 }
index 743ac5194e0bc98ef7c936d98946424d8fb8c2b6..1db0dcc78193da0f1fb811b740ea4764733377b4 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/locks.h>
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
+#include <linux/init.h>
 #ifdef CONFIG_KERNELD
 #include <linux/kerneld.h>
 #endif
@@ -409,7 +410,7 @@ static struct file_system_type ncp_fs_type =
        ncp_read_super, "ncpfs", 0, NULL
 };
 
-int init_ncp_fs(void)
+__initfunc(int init_ncp_fs(void))
 {
        return register_filesystem(&ncp_fs_type);
 }
index 98d646e0c72560177ffc11540bddd4a1d963d17e..a11b9fb6ababcc23de8c9f72d5316710791e3b46 100644 (file)
@@ -206,7 +206,7 @@ again:
                }
                if (entry) {
                        dfprintk(DIRCACHE, "NFS: found dircache entry %d\n",
-                                               cache - dircache);
+                                               (int)(cache - dircache));
                        cache->locked = 1;
                        break;
                }
@@ -223,7 +223,7 @@ again:
                        goto again;
                }
                dfprintk(DIRCACHE, "NFS: using free dircache entry %d\n",
-                               free - dircache);
+                               (int)(free - dircache));
                cache->cookie = cookie;
                cache->locked = 1;
                cache->valid  = 0;
@@ -298,7 +298,7 @@ nfs_invalidate_dircache(struct inode *inode)
        ino_t           ino = inode->i_ino;
        int             i;
 
-       dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, ino);
+       dfprintk(DIRCACHE, "NFS: invalidate dircache for %x/%ld\n", dev, (long)ino);
        for (i = 0, cache = dircache; i < NFS_MAX_DIRCACHE; i++, cache++) {
                if (!cache->locked && cache->dev == dev && cache->ino == ino)
                        cache->valid = 0;       /* brute force */
@@ -445,7 +445,7 @@ static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
                return;
 
        dfprintk(LOOKUPCACHE, "NFS: lookup_cache_remove(%x/%ld)\n",
-                               dev, fileid);
+                               dev, (long)fileid);
 
        for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
                entry = nfs_lookup_cache + i;
index 322f093335457443bb3da56c5a7cbc9647cd8168..81da8f9968ddbd4e9528631ff6c3ba262a419bdd 100644 (file)
@@ -49,8 +49,8 @@ nfs_mount(struct sockaddr_in *addr, char *path, struct nfs_fh *fh)
        char                    hostname[32];
        int                     status;
 
-       dprintk("NFS:      nfs_mount(%08lx:%s)\n",
-                       ntohl(addr->sin_addr.s_addr), path);
+       dprintk("NFS:      nfs_mount(%08x:%s)\n",
+                       (unsigned)ntohl(addr->sin_addr.s_addr), path);
 
        strcpy(hostname, in_ntoa(addr->sin_addr.s_addr));
        if (!(mnt_clnt = mnt_create(hostname, addr)))
index 213162f316f607199002ddc14af9d0c8fe4d2278..5eec5eb65e0d9f76e8fd2027b0bd33748942cf1c 100644 (file)
@@ -222,7 +222,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
        struct iovec *iov = req->rq_rvec;
        int     status, count, recvd, hdrlen;
 
-       dprintk("RPC:      readres OK status %lx\n", ntohl(*p));
+       dprintk("RPC:      readres OK status %lx\n", (long)ntohl(*p));
        if ((status = ntohl(*p++)))
                return -nfs_stat_to_errno(status);
        p = xdr_decode_fattr(p, res->fattr);
@@ -414,9 +414,16 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs_readdirres *res)
                }
                string -= len;
                if ((void *) (entry+1) > (void *) string) {
+                       /* This may actually happen because an nfs_entry
+                        * will take up more space than the XDR data. On
+                        * 32bit machines that's due to 8byte alignment,
+                        * on 64bit machines that's because the char * takes
+                        * up 2 longs.
+                        *
+                        * THIS IS BAD!
+                        */
                        printk(KERN_NOTICE "NFS: should not happen in %s!\n",
-                                       __FUNCTION__);
-                       printk(KERN_NOTICE "NFS: len = %d, entry+1=%p, string=%p\n", len, entry+1, string);
+                               __FUNCTION__);
                        break;
                }
 
@@ -464,7 +471,7 @@ nfs_xdr_attrstat(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
 {
        int     status;
 
-       dprintk("RPC:      attrstat status %lx\n", ntohl(*p));
+       dprintk("RPC:      attrstat status %lx\n", (long)ntohl(*p));
        if ((status = ntohl(*p++)))
                return -nfs_stat_to_errno(status);
        xdr_decode_fattr(p, fattr);
@@ -482,7 +489,7 @@ nfs_xdr_diropres(struct rpc_rqst *req, u32 *p, struct nfs_diropok *res)
 {
        int     status;
 
-       dprintk("RPC:      diropres status %lx\n", ntohl(*p));
+       dprintk("RPC:      diropres status %lx\n", (long)ntohl(*p));
        if ((status = ntohl(*p++)))
                return -nfs_stat_to_errno(status);
        p = xdr_decode_fhandle(p, res->fh);
index 5a6a1a60265dbeca4a03c8e4fb07efe490000ac7..ecec8a22b770e988c900ec6c76e6b126f98022ec 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <linux/net.h>
-#include <linux/in.h>
 #include <linux/unistd.h>
 #include <linux/malloc.h>
 #include <linux/in.h>
index b09849c07b2e7fb93453d6f4157e7bddb95e8332..e5bb9d51bad1391e78da0dfb40382f62ff1c8cc8 100644 (file)
@@ -365,7 +365,7 @@ static int proc_self_readlink(struct inode * inode, char * buffer, int buflen)
        char tmp[30];
 
        iput(inode);
-       len = 1 + sprintf(tmp, "%d", current->pid);
+       len = sprintf(tmp, "%d", current->pid);
        if (buflen < len)
                len = buflen;
        copy_to_user(buffer, tmp, len);
index 5ff50e6efd1d5237c5260724cb5998a126427578..f3f73c66e76e2481c017ef317571b1d32a09f625 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/romfs_fs.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -640,8 +641,7 @@ static struct file_system_type romfs_fs_type = {
        romfs_read_super, "romfs", 1, NULL
 };
 
-int
-init_romfs_fs(void)
+__initfunc(int init_romfs_fs(void))
 {
        return register_filesystem(&romfs_fs_type);
 }
index efc5a7f308658ea249900607003adeec09753a63..7ab7d15ff6a694ebf175d0ed9271f92000935098 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/locks.h>
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -432,8 +433,7 @@ static struct file_system_type smb_fs_type =
        smb_read_super, "smbfs", 0, NULL
 };
 
-int
-init_smb_fs(void)
+__initfunc(int init_smb_fs(void))
 {
        return register_filesystem(&smb_fs_type);
 }
index 0e4509e79ca0716ecc826f10e68e0d694c7fc8dd..ebbf0bb4fb576b9a727549dce7066867fddd3b73 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -979,7 +980,7 @@ static struct file_system_type sysv_fs_type[3] = {
        {sysv_read_super, "coherent", 1, NULL}
 };
 
-int init_sysv_fs(void)
+__initfunc(int init_sysv_fs(void))
 {
        int i;
        int ouch;
index 695e243ac4fb30e5a0aaf66e2f260bded90e37f6..44d7241ef73a919378fd72325b2a2f2f04933dc4 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (C) 1996  Eddie C. Dost  (ecd@skynet.be)
  *
- * $Id: ufs_super.c,v 1.22 1997/01/16 14:17:41 davem Exp $
+ * $Id: ufs_super.c,v 1.23 1997/04/16 04:53:39 tdyas Exp $
  *
  */
 
@@ -27,6 +27,7 @@
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/locks.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -51,8 +52,7 @@ static struct file_system_type ufs_fs_type = {
        ufs_read_super, "ufs", 1, NULL
 };
 
-int
-init_ufs_fs(void)
+__initfunc(int init_ufs_fs(void))
 {
        return(register_filesystem(&ufs_fs_type));
 }
index eb00ad917e97b39db21ecbed118c8ac268638a98..8a00fd8338b115f28230602a81e2b9e2f8e80864 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/module.h>
 
+#include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
 #include <linux/kernel.h>
@@ -499,7 +500,7 @@ static struct file_system_type umsdos_fs_type = {
        UMSDOS_read_super, "umsdos", 1, NULL
 };
 
-int init_umsdos_fs(void)
+__initfunc(int init_umsdos_fs(void))
 {
        return register_filesystem(&umsdos_fs_type);
 }
index 17c439390f99d0f3ac7cca1d82daa31a74dc0608..badb6c7e21ce42a022171f019f13f253221d4640 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -1587,7 +1588,7 @@ EXPORT_SYMBOL(vfat_read_super);
 EXPORT_SYMBOL(vfat_read_inode);
 EXPORT_SYMBOL(vfat_lookup);
 
-int init_vfat_fs(void)
+__initfunc(int init_vfat_fs(void))
 {
        return register_filesystem(&vfat_fs_type);
 }
index ba62e86845f439f713b6e19e9b767b69cb7b9c37..2485cd781a4a76bea9ce2f07a26c19b05fc6791d 100644 (file)
@@ -15,7 +15,7 @@ typedef struct { volatile int counter; } atomic_t;
 typedef struct { int counter; } atomic_t;
 #endif
 
-#define ATOMIC_INIT    { 0 }
+#define ATOMIC_INIT(i) { (i) }
 
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v,i)                ((v)->counter = (i))
index c073337e6a2170b24de3788ad4131a6a39df4e1b..b94573f1311ca57d19a66f090237c09dd91cecef 100644 (file)
@@ -15,8 +15,8 @@ struct semaphore {
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
 
 extern void __down(struct semaphore * sem);
 extern int  __down_interruptible(struct semaphore * sem);
index 07bd9ec0879d183c9189a378fbedc4b0485f870e..5f5d69297f9c871ea84dca7513d21edcda5b5712 100644 (file)
@@ -6,7 +6,7 @@
 #define lock_kernel()                          do { } while(0)
 #define unlock_kernel()                                do { } while(0)
 #define release_kernel_lock(task, cpu, depth)  ((depth) = 1)
-#define reaquire_kernel_lock(task, cpu, depth) do { } while (0)
+#define reacquire_kernel_lock(task, cpu, depth)        do { } while (0)
 
 #else
 
index 2c4af2336585656390b1d90500b2d335acd197aa..aef56398ec00abc3a1a1cd4f47ca4b3d07ecfb08 100644 (file)
@@ -6,16 +6,37 @@
 typedef struct { } spinlock_t;
 #define SPIN_LOCK_UNLOCKED { }
 
-#define spin_lock_init(lock)                   do { } while(0)
+/*
+ * Basic spinlocks - one can enter at a time
+ */
+
 #define spin_lock(lock)                                do { } while(0)
 #define spin_trylock(lock)                     do { } while(0)
 #define spin_unlock(lock)                      do { } while(0)
 #define spin_lock_irq(lock)                    setipl(7)
 #define spin_unlock_irq(lock)                  setipl(0)
-
 #define spin_lock_irqsave(lock, flags)         swpipl(flags,7)
 #define spin_unlock_irqrestore(lock, flags)    setipl(flags)
 
+/*
+ * Read-write locks: we can have multiple readers, but
+ * only one writer
+ */
+
+#define read_lock(lock)                                do { } while(0)
+#define read_unlock(lock)                      do { } while(0)
+#define read_lock_irq(lock)                    setipl(7)
+#define read_unlock_irq(lock)                  setipl(0)
+#define read_lock_irqsave(lock, flags)         swpipl(flags,7)
+#define read_unlock_irqrestore(lock, flags)    setipl(flags)
+
+#define write_lock(lock)                               do { } while(0)
+#define write_unlock(lock)                     do { } while(0)
+#define write_lock_irq(lock)                   setipl(7)
+#define write_unlock_irq(lock)                 setipl(0)
+#define write_lock_irqsave(lock, flags)                swpipl(flags,7)
+#define write_unlock_irqrestore(lock, flags)   setipl(flags)
+
 #else
 
 /* Simple spin lock operations.  There are two variants, one clears IRQ's
@@ -31,6 +52,8 @@ typedef struct {
 
 #define SPIN_LOCK_UNLOCKED { 0, 0 }
 
+#define spin_lock_init(lock)   do { (lock)->lock = 0; (lock)->previous = 0; } while(0)
+
 typedef struct { unsigned long a[100]; } __dummy_lock_t;
 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
 
index f6b77c0dc320b40ea1cd8374b8b276c4ad3d6b11..5690c46e2929882796741d896311f77459f517a6 100644 (file)
@@ -25,7 +25,7 @@ typedef struct { volatile int counter; } atomic_t;
 typedef struct { int counter; } atomic_t;
 #endif
 
-#define ATOMIC_INIT    { 0 }
+#define ATOMIC_INIT(i) { (i) }
 
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v,i)                (((v)->counter) = (i))
index de13c5a8b3362fd754f682e457707f9c072e4f5b..83215545f95607480a73a88c14754eb82c1ee995 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef _I386_INIT_H
 #define _I386_INIT_H
 
-#ifndef MODULE
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initdata __attribute__ ((__section__ (".data.init")))
 #define __initfunc(__arginit) \
 #define __INIT         .section        ".text.init",#alloc,#execinstr
 #define __FINIT        .previous
 #define __INITDATA     .section        ".data.init",#alloc,#write
-#else
-#define        __init
-#define __initdata
-#define __initfunc(__arginit) __arginit
-/* For assembly routines */
-#define __INIT
-#define __FINIT
-#define __INITDATA
-#endif
 
 #endif
index caad760503179c5b53f815f34de6064c334bee19..4395dfce026163986adbc306e90aaca2bbbd5906 100644 (file)
@@ -28,8 +28,8 @@ struct semaphore {
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { { 1 }, 0, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { { 0 }, 0, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL })
 
 asmlinkage void __down_failed(void /* special register calling convention */);
 asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
index b03c6ef44083fc91f2f76fb61896216c026adce0..f1d977f224a532a7ccdeeb8192610fd7b1056d44 100644 (file)
@@ -234,52 +234,6 @@ extern __inline int smp_processor_id(void)
        return GET_APIC_ID(*(unsigned long *)(apic_reg+APIC_ID));
 }
 
-/* These read/change the "processes available" counter in the scheduler. */
-extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr)
-{
-       int cpu = smp_processor_id();
-       while(set_bit(31, ctr))
-       {
-               while(test_bit(31,ctr))
-               {
-                       if(clear_bit(cpu,&smp_invalidate_needed))
-                       {
-                               unsigned long tmpreg;
-                               __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3"
-                                                    : "=r" (tmpreg) : : "memory");
-                               set_bit(cpu,&cpu_callin_map[0]);
-                       }
-               }
-       }
-       *ctr = (*ctr + 1);
-       clear_bit(31, ctr);
-}
-
-extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr)
-{
-       int cpu = smp_processor_id();
-       while(set_bit(31, ctr))
-       {
-               while(test_bit(31,ctr))
-               {
-                       if(clear_bit(cpu,&smp_invalidate_needed))
-                       {
-                               unsigned long tmpreg;
-                               __asm__ __volatile__("movl %%cr3,%0\n\tmovl %0,%%cr3"
-                                                    : "=r" (tmpreg) : : "memory");
-                               set_bit(cpu,&cpu_callin_map[0]);
-                       }
-               }
-       }
-       *ctr = (*ctr - 1);
-       clear_bit(31, ctr);
-}
-
-extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
-{
-       return (*ctr & 0x7fffffff);
-}
-
 #endif /* !ASSEMBLY */
 
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
index 766e7cff5293a94f17b0e0b685ad73538c4a6ca3..160e3562dacc4b8672323191fceb9dbb974bdeea 100644 (file)
@@ -8,7 +8,7 @@
 #define lock_kernel()                          do { } while(0)
 #define unlock_kernel()                                do { } while(0)
 #define release_kernel_lock(task, cpu, depth)  ((depth) = 1)
-#define reaquire_kernel_lock(task, cpu, depth) do { } while(0)
+#define reacquire_kernel_lock(task, cpu, depth)        do { } while(0)
 
 #else
 
@@ -27,8 +27,8 @@ do { \
        __sti(); \
 } while (0)
 
-/* Re-aquire the kernel lock */
-#define reaquire_kernel_lock(task, cpu, depth) \
+/* Re-acquire the kernel lock */
+#define reacquire_kernel_lock(task, cpu, depth) \
 do { if (depth) __asm__ __volatile__( \
        "cli\n\t" \
        "movl $0f,%%eax\n\t" \
index a2d3d1a5448985faade51de62dfdd4c89ec99aea..03b18cb9c2254952489cb57f87973f4fab9f716a 100644 (file)
@@ -3,6 +3,9 @@
 
 #ifndef __SMP__
 
+/*
+ * Your basic spinlocks, allowing only a single CPU anywhere
+ */
 typedef struct { } spinlock_t;
 #define SPIN_LOCK_UNLOCKED { }
 
@@ -18,9 +21,41 @@ typedef struct { } spinlock_t;
 #define spin_unlock_irqrestore(lock, flags) \
        restore_flags(flags)
 
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct { } rwlock_t;
+#define RW_LOCK_UNLOCKED { }
+
+#define read_lock(lock)                do { } while(0)
+#define read_unlock(lock)      do { } while(0)
+#define write_lock(lock)       do { } while(0)
+#define write_unlock(lock)     do { } while(0)
+#define read_lock_irq(lock)    cli()
+#define read_unlock_irq(lock)  sti()
+#define write_lock_irq(lock)   cli()
+#define write_unlock_irq(lock) sti()
+
+#define read_lock_irqsave(lock, flags) \
+       do { save_flags(flags); cli(); } while (0)
+#define read_unlock_irqrestore(lock, flags) \
+       restore_flags(flags)
+#define write_lock_irqsave(lock, flags)        \
+       do { save_flags(flags); cli(); } while (0)
+#define write_unlock_irqrestore(lock, flags) \
+       restore_flags(flags)
+
 #else
 
-/* Simple spin lock operations.  There are two variants, one clears IRQ's
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
  * on the local processor, one does not.
  *
  * We make no fairness assumptions. They have a cost.
@@ -33,6 +68,8 @@ typedef struct {
 
 #define SPIN_LOCK_UNLOCKED { 0, 0 }
 
+#define spin_lock_init(x)      do { (x)->lock = 0; (x)->previous = 0; } while(0)
+
 typedef struct { unsigned long a[100]; } __dummy_lock_t;
 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
 
@@ -92,5 +129,79 @@ l1:
 #define spin_unlock_irqrestore(lock, flags) \
        do { spin_unlock(lock); __restore_flags(flags); } while (0)
 
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct {
+       volatile unsigned int lock;
+       unsigned long previous;
+} rwlock_t;
+
+#define RW_LOCK_UNLOCKED { 0, 0 }
+
+/*
+ * On x86, we implement read-write locks as a 32-bit counter
+ * with the high bit (sign) being the "write" bit.
+ *
+ * The inline assembly is non-obvious. Think about it.
+ */
+#define read_lock(rw)  \
+       asm volatile("\n1:\t" \
+                    "lock ; incl %0\n\t" \
+                    "js 2f\n" \
+                    ".text 2\n" \
+                    "2:\tlock ; decl %0\n" \
+                    "3:\tcmpl $0,%0\n\t" \
+                    "js 3b\n\t" \
+                    "jmp 1b\n" \
+                    ".text" \
+                    :"=m" (__dummy_lock(&(rw)->lock)))
+
+#define read_unlock(rw) \
+       asm volatile("lock ; decl %0" \
+               :"=m" (__dummy_lock(&(rw)->lock)))
+
+#define write_lock(rw) \
+       asm volatile("\n1:\t" \
+                    "lock ; btsl $31,%0\n\t" \
+                    "jc 3f\n\t" \
+                    "testl $0x7fffffff,%0\n\t" \
+                    "jne 4f\n" \
+                    "2:\n" \
+                    ".text 2\n" \
+                    "3:\ttestl $-1,%0\n\t" \
+                    "js 3b\n\t" \
+                    "lock ; btsl $31,%0\n\t" \
+                    "jc 3b\n" \
+                    "4:\ttestl $0x7fffffff,%0\n\t" \
+                    "jne 4b\n\t" \
+                    "jmp 2b\n" \
+                    ".text" \
+                    :"=m" (__dummy_lock(&(rw)->lock)))
+
+#define write_unlock(rw) \
+       asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock)))
+
+#define read_lock_irq(lock)    do { __cli(); read_lock(lock); } while (0)
+#define read_unlock_irq(lock)  do { read_unlock(lock); __sti(); } while (0)
+#define write_lock_irq(lock)   do { __cli(); write_lock(lock); } while (0)
+#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0)
+
+#define read_lock_irqsave(lock, flags) \
+       do { __save_flags(flags); __cli(); read_lock(lock); } while (0)
+#define read_unlock_irqrestore(lock, flags) \
+       do { read_unlock(lock); __restore_flags(flags); } while (0)
+#define write_lock_irqsave(lock, flags)        \
+       do { __save_flags(flags); __cli(); write_lock(lock); } while (0)
+#define write_unlock_irqrestore(lock, flags) \
+       do { write_unlock(lock); __restore_flags(flags); } while (0)
+
 #endif /* SMP */
 #endif /* __ASM_SPINLOCK_H */
index 0c225ee7ce8a628a3e3f2144405c8397c9eef2e6..53ce7e6746080bc044a5f0da94c67ae39f86ae57 100644 (file)
 **
 */
 
-#define AMI_IRQS            (24)
+#define AUTO_IRQS           (8)
 #define AMI_STD_IRQS        (14)
 #define CIA_IRQS            (5)
+#define AMI_IRQS            (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */
 
 /* vertical blanking interrupt */
-#define IRQ_AMIGA_VERTB     (IRQ_MACHSPEC | 0)
+#define IRQ_AMIGA_VERTB     0
 
 /* copper interrupt */
-#define IRQ_AMIGA_COPPER    (IRQ_MACHSPEC | 1)
+#define IRQ_AMIGA_COPPER    1
 
 /* Audio interrupts */
-#define IRQ_AMIGA_AUD0     (IRQ_MACHSPEC | 2)
-#define IRQ_AMIGA_AUD1     (IRQ_MACHSPEC | 3)
-#define IRQ_AMIGA_AUD2     (IRQ_MACHSPEC | 4)
-#define IRQ_AMIGA_AUD3     (IRQ_MACHSPEC | 5)
+#define IRQ_AMIGA_AUD0     2
+#define IRQ_AMIGA_AUD1     3
+#define IRQ_AMIGA_AUD2     4
+#define IRQ_AMIGA_AUD3     5
 
 /* Blitter done interrupt */
-#define IRQ_AMIGA_BLIT     (IRQ_MACHSPEC | 6)
+#define IRQ_AMIGA_BLIT     6
 
 /* floppy disk interrupts */
-#define IRQ_AMIGA_DSKSYN    (IRQ_MACHSPEC | 7)
-#define IRQ_AMIGA_DSKBLK    (IRQ_MACHSPEC | 8)
+#define IRQ_AMIGA_DSKSYN    7
+#define IRQ_AMIGA_DSKBLK    8
 
 /* builtin serial port interrupts */
-#define IRQ_AMIGA_RBF      (IRQ_MACHSPEC | 9)
-#define IRQ_AMIGA_TBE      (IRQ_MACHSPEC | 10)
+#define IRQ_AMIGA_RBF      9
+#define IRQ_AMIGA_TBE      10
 
 /* software interrupts */
-#define IRQ_AMIGA_SOFT      (IRQ_MACHSPEC | 11)
+#define IRQ_AMIGA_SOFT      11
 
 /* interrupts from external hardware */
-#define IRQ_AMIGA_PORTS            (IRQ_MACHSPEC | 12)
-#define IRQ_AMIGA_EXTER            (IRQ_MACHSPEC | 13)
+#define IRQ_AMIGA_PORTS            12
+#define IRQ_AMIGA_EXTER            13
 
 /* CIA interrupt sources */
-#define IRQ_AMIGA_CIAA      (IRQ_MACHSPEC | 14)
-#define IRQ_AMIGA_CIAA_TA   (IRQ_MACHSPEC | 14)
-#define IRQ_AMIGA_CIAA_TB   (IRQ_MACHSPEC | 15)
-#define IRQ_AMIGA_CIAA_ALRM (IRQ_MACHSPEC | 16)
-#define IRQ_AMIGA_CIAA_SP   (IRQ_MACHSPEC | 17)
-#define IRQ_AMIGA_CIAA_FLG  (IRQ_MACHSPEC | 18)
-#define IRQ_AMIGA_CIAB      (IRQ_MACHSPEC | 19)
-#define IRQ_AMIGA_CIAB_TA   (IRQ_MACHSPEC | 19)
-#define IRQ_AMIGA_CIAB_TB   (IRQ_MACHSPEC | 20)
-#define IRQ_AMIGA_CIAB_ALRM (IRQ_MACHSPEC | 21)
-#define IRQ_AMIGA_CIAB_SP   (IRQ_MACHSPEC | 22)
-#define IRQ_AMIGA_CIAB_FLG  (IRQ_MACHSPEC | 23)
+#define IRQ_AMIGA_CIAA      14
+#define IRQ_AMIGA_CIAA_TA   14
+#define IRQ_AMIGA_CIAA_TB   15
+#define IRQ_AMIGA_CIAA_ALRM 16
+#define IRQ_AMIGA_CIAA_SP   17
+#define IRQ_AMIGA_CIAA_FLG  18
+#define IRQ_AMIGA_CIAB      19
+#define IRQ_AMIGA_CIAB_TA   19
+#define IRQ_AMIGA_CIAB_TB   20
+#define IRQ_AMIGA_CIAB_ALRM 21
+#define IRQ_AMIGA_CIAB_SP   22
+#define IRQ_AMIGA_CIAB_FLG  23
+
+/* auto-vector interrupts */
+#define IRQ_AMIGA_AUTO      24
+#define IRQ_AMIGA_AUTO_0    24 /* This is just a dummy */
+#define IRQ_AMIGA_AUTO_1    25
+#define IRQ_AMIGA_AUTO_2    26
+#define IRQ_AMIGA_AUTO_3    27
+#define IRQ_AMIGA_AUTO_4    28
+#define IRQ_AMIGA_AUTO_5    29
+#define IRQ_AMIGA_AUTO_6    30
+#define IRQ_AMIGA_AUTO_7    31
 
 #define IRQ_FLOPPY         IRQ_AMIGA_DSKBLK
 
index 0483ed45d782b15ecc191c6775df8e8d03ecc8d6..5b137e7696fc49df55f746dfbe4d5e84fa240b38 100644 (file)
@@ -79,6 +79,7 @@ struct atari_hw_present {
     ATARIHW_DECLARE(SCU);              /* System Control Unit */
     ATARIHW_DECLARE(BLITTER);          /* Blitter */
     ATARIHW_DECLARE(VME);              /* VME Bus */
+    ATARIHW_DECLARE(DSP56K);           /* DSP56k processor in Falcon */
 };
 
 extern struct atari_hw_present atari_hw_present;
@@ -97,6 +98,7 @@ void *atari_stram_alloc (long size, unsigned long *start_mem );
 void atari_stram_free (void *);
 
 extern int is_medusa;
+extern int is_hades;
 
 /* Do cache push/invalidate for DMA read/write. This function obeys the
  * snooping on some machines (Medusa) and processors: The Medusa itself can
@@ -356,8 +358,8 @@ struct CODEC
 {
   u_char tracks;
   u_char input_source;
-#define CODEC_SOURCE_MATRIX     1
-#define CODEC_SOURCE_ADC        2
+#define CODEC_SOURCE_ADC        1
+#define CODEC_SOURCE_MATRIX     2
   u_char adc_source;
 #define ADC_SOURCE_RIGHT_PSG    1
 #define ADC_SOURCE_LEFT_PSG     2
@@ -673,17 +675,28 @@ struct TT_DMASND {
 };
 # define tt_dmasnd ((*(volatile struct TT_DMASND *)TT_DMASND_BAS))
 
-#define        DMASND_CTRL_OFF         0x00
-#define        DMASND_CTRL_ON          0x01
-#define        DMASND_CTRL_REPEAT      0x02
-#define        DMASND_MODE_MONO        0x80
-#define        DMASND_MODE_STEREO      0x00
-#define DMASND_MODE_8BIT       0x00
-#define DMASND_MODE_16BIT      0x40    /* Falcon only */
-#define        DMASND_MODE_6KHZ        0x00    /* Falcon: mute */
-#define        DMASND_MODE_12KHZ       0x01
-#define        DMASND_MODE_25KHZ       0x02
-#define        DMASND_MODE_50KHZ       0x03
+#define DMASND_MFP_INT_REPLAY     0x01
+#define DMASND_MFP_INT_RECORD     0x02
+#define DMASND_TIMERA_INT_REPLAY  0x04
+#define DMASND_TIMERA_INT_RECORD  0x08
+
+#define        DMASND_CTRL_OFF           0x00
+#define        DMASND_CTRL_ON            0x01
+#define        DMASND_CTRL_REPEAT        0x02
+#define DMASND_CTRL_RECORD_ON     0x10
+#define DMASND_CTRL_RECORD_OFF    0x00
+#define DMASND_CTRL_RECORD_REPEAT 0x20
+#define DMASND_CTRL_SELECT_REPLAY 0x00
+#define DMASND_CTRL_SELECT_RECORD 0x80
+#define        DMASND_MODE_MONO          0x80
+#define        DMASND_MODE_STEREO        0x00
+#define DMASND_MODE_8BIT         0x00
+#define DMASND_MODE_16BIT        0x40  /* Falcon only */
+#define        DMASND_MODE_6KHZ          0x00  /* Falcon: mute */
+#define        DMASND_MODE_12KHZ         0x01
+#define        DMASND_MODE_25KHZ         0x02
+#define        DMASND_MODE_50KHZ         0x03
 
 #define DMASNDSetBase(bufstart)                                                \
     do {                                                               \
index e2bb42b4ccb58ef06ce0d728ae57fa7fc31e9485..c151f55a99bd1fdf0f9bf4478b1cb9376fcfa37d 100644 (file)
 **
 */
 
-#define STMFP_SOURCE_BASE   8
-#define TTMFP_SOURCE_BASE   24
-#define SCC_SOURCE_BASE            40
-#define VME_SOURCE_BASE                56
-#define VME_MAX_SOURCES                16
+#define STMFP_SOURCE_BASE  8
+#define TTMFP_SOURCE_BASE  24
+#define SCC_SOURCE_BASE    40
+#define VME_SOURCE_BASE    56
+#define VME_MAX_SOURCES    16
 
 #define NUM_ATARI_SOURCES   (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE)
 
 #define IRQ_TYPE_FAST     1
 #define IRQ_TYPE_PRIO     2
 
-#define        IRQ_SPURIOUS      (IRQ_MACHSPEC | 0)
+#define        IRQ_SPURIOUS      (0)
 
 /* auto-vector interrupts */
-#define IRQ_AUTO_1        (IRQ_MACHSPEC | 1)
-#define IRQ_AUTO_2        (IRQ_MACHSPEC | 2)
-#define IRQ_AUTO_3        (IRQ_MACHSPEC | 3)
-#define IRQ_AUTO_4        (IRQ_MACHSPEC | 4)
-#define IRQ_AUTO_5        (IRQ_MACHSPEC | 5)
-#define IRQ_AUTO_6        (IRQ_MACHSPEC | 6)
-#define IRQ_AUTO_7        (IRQ_MACHSPEC | 7)
+#define IRQ_AUTO_1        (1)
+#define IRQ_AUTO_2        (2)
+#define IRQ_AUTO_3        (3)
+#define IRQ_AUTO_4        (4)
+#define IRQ_AUTO_5        (5)
+#define IRQ_AUTO_6        (6)
+#define IRQ_AUTO_7        (7)
 
 /* ST-MFP interrupts */
-#define IRQ_MFP_BUSY      (IRQ_MACHSPEC | 8)
-#define IRQ_MFP_DCD       (IRQ_MACHSPEC | 9)
-#define IRQ_MFP_CTS      (IRQ_MACHSPEC | 10)
-#define IRQ_MFP_GPU      (IRQ_MACHSPEC | 11)
-#define IRQ_MFP_TIMD      (IRQ_MACHSPEC | 12)
-#define IRQ_MFP_TIMC     (IRQ_MACHSPEC | 13)
-#define IRQ_MFP_ACIA     (IRQ_MACHSPEC | 14)
-#define IRQ_MFP_FDC       (IRQ_MACHSPEC | 15)
+#define IRQ_MFP_BUSY      (8)
+#define IRQ_MFP_DCD       (9)
+#define IRQ_MFP_CTS      (10)
+#define IRQ_MFP_GPU      (11)
+#define IRQ_MFP_TIMD      (12)
+#define IRQ_MFP_TIMC     (13)
+#define IRQ_MFP_ACIA     (14)
+#define IRQ_MFP_FDC       (15)
 #define IRQ_MFP_ACSI      IRQ_MFP_FDC
 #define IRQ_MFP_FSCSI     IRQ_MFP_FDC
 #define IRQ_MFP_IDE       IRQ_MFP_FDC
-#define IRQ_MFP_TIMB      (IRQ_MACHSPEC | 16)
-#define IRQ_MFP_SERERR    (IRQ_MACHSPEC | 17)
-#define IRQ_MFP_SEREMPT   (IRQ_MACHSPEC | 18)
-#define IRQ_MFP_RECERR    (IRQ_MACHSPEC | 19)
-#define IRQ_MFP_RECFULL   (IRQ_MACHSPEC | 20)
-#define IRQ_MFP_TIMA      (IRQ_MACHSPEC | 21)
-#define IRQ_MFP_RI        (IRQ_MACHSPEC | 22)
-#define IRQ_MFP_MMD       (IRQ_MACHSPEC | 23)
+#define IRQ_MFP_TIMB      (16)
+#define IRQ_MFP_SERERR    (17)
+#define IRQ_MFP_SEREMPT   (18)
+#define IRQ_MFP_RECERR    (19)
+#define IRQ_MFP_RECFULL   (20)
+#define IRQ_MFP_TIMA      (21)
+#define IRQ_MFP_RI        (22)
+#define IRQ_MFP_MMD       (23)
 
 /* TT-MFP interrupts */
-#define IRQ_TT_MFP_IO0       (IRQ_MACHSPEC | 24)
-#define IRQ_TT_MFP_IO1       (IRQ_MACHSPEC | 25)
-#define IRQ_TT_MFP_SCC      (IRQ_MACHSPEC | 26)
-#define IRQ_TT_MFP_RI       (IRQ_MACHSPEC | 27)
-#define IRQ_TT_MFP_TIMD      (IRQ_MACHSPEC | 28)
-#define IRQ_TT_MFP_TIMC             (IRQ_MACHSPEC | 29)
-#define IRQ_TT_MFP_DRVRDY    (IRQ_MACHSPEC | 30)
-#define IRQ_TT_MFP_SCSIDMA   (IRQ_MACHSPEC | 31)
-#define IRQ_TT_MFP_TIMB      (IRQ_MACHSPEC | 32)
-#define IRQ_TT_MFP_SERERR    (IRQ_MACHSPEC | 33)
-#define IRQ_TT_MFP_SEREMPT   (IRQ_MACHSPEC | 34)
-#define IRQ_TT_MFP_RECERR    (IRQ_MACHSPEC | 35)
-#define IRQ_TT_MFP_RECFULL   (IRQ_MACHSPEC | 36)
-#define IRQ_TT_MFP_TIMA      (IRQ_MACHSPEC | 37)
-#define IRQ_TT_MFP_RTC       (IRQ_MACHSPEC | 38)
-#define IRQ_TT_MFP_SCSI      (IRQ_MACHSPEC | 39)
+#define IRQ_TT_MFP_IO0       (24)
+#define IRQ_TT_MFP_IO1       (25)
+#define IRQ_TT_MFP_SCC      (26)
+#define IRQ_TT_MFP_RI       (27)
+#define IRQ_TT_MFP_TIMD      (28)
+#define IRQ_TT_MFP_TIMC             (29)
+#define IRQ_TT_MFP_DRVRDY    (30)
+#define IRQ_TT_MFP_SCSIDMA   (31)
+#define IRQ_TT_MFP_TIMB      (32)
+#define IRQ_TT_MFP_SERERR    (33)
+#define IRQ_TT_MFP_SEREMPT   (34)
+#define IRQ_TT_MFP_RECERR    (35)
+#define IRQ_TT_MFP_RECFULL   (36)
+#define IRQ_TT_MFP_TIMA      (37)
+#define IRQ_TT_MFP_RTC       (38)
+#define IRQ_TT_MFP_SCSI      (39)
 
 /* SCC interrupts */
-#define IRQ_SCCB_TX         (IRQ_MACHSPEC | 40)
-#define IRQ_SCCB_STAT       (IRQ_MACHSPEC | 42)
-#define IRQ_SCCB_RX         (IRQ_MACHSPEC | 44)
-#define IRQ_SCCB_SPCOND             (IRQ_MACHSPEC | 46)
-#define IRQ_SCCA_TX         (IRQ_MACHSPEC | 48)
-#define IRQ_SCCA_STAT       (IRQ_MACHSPEC | 50)
-#define IRQ_SCCA_RX         (IRQ_MACHSPEC | 52)
-#define IRQ_SCCA_SPCOND             (IRQ_MACHSPEC | 54)
+#define IRQ_SCCB_TX         (40)
+#define IRQ_SCCB_STAT       (42)
+#define IRQ_SCCB_RX         (44)
+#define IRQ_SCCB_SPCOND             (46)
+#define IRQ_SCCA_TX         (48)
+#define IRQ_SCCA_STAT       (50)
+#define IRQ_SCCA_RX         (52)
+#define IRQ_SCCA_SPCOND             (54)
 
 
 #define INT_CLK   24576            /* CLK while int_clk =2.456MHz and divide = 100 */
@@ -164,7 +164,6 @@ static inline void clear_mfp_bit( unsigned irq, int type )
 static inline void atari_enable_irq( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
        set_mfp_bit( irq, MFP_MASK );
 }
@@ -172,7 +171,6 @@ static inline void atari_enable_irq( unsigned irq )
 static inline void atari_disable_irq( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
        clear_mfp_bit( irq, MFP_MASK );
 }
@@ -185,7 +183,6 @@ static inline void atari_disable_irq( unsigned irq )
 extern inline void atari_turnon_irq( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
        set_mfp_bit( irq, MFP_ENABLE );
 }
@@ -193,7 +190,6 @@ extern inline void atari_turnon_irq( unsigned irq )
 extern inline void atari_turnoff_irq( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
        clear_mfp_bit( irq, MFP_ENABLE );
        clear_mfp_bit( irq, MFP_PENDING );
@@ -202,7 +198,6 @@ extern inline void atari_turnoff_irq( unsigned irq )
 extern inline void atari_clear_pending_irq( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
        clear_mfp_bit( irq, MFP_PENDING );
 }
@@ -210,7 +205,6 @@ extern inline void atari_clear_pending_irq( unsigned irq )
 extern inline int atari_irq_pending( unsigned irq )
 
 {
-       irq &= ~IRQ_MACHSPEC;
        if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 );
        return( get_mfp_bit( irq, MFP_PENDING ) );
 }
index ee275e3cc106ee20db59690ede16bedc7aaf4bc8..b57cc9cb077838f50e11e2a2f3ef3979bea1910a 100644 (file)
@@ -14,7 +14,7 @@ typedef struct { int counter; } atomic_t;
 #define ATOMIC_INIT    { 0 }
 
 #define atomic_read(v)         ((v)->counter)
-#define atomic_set(v)          (((v)->counter) = i)
+#define atomic_set(v, i)       (((v)->counter) = i)
 
 static __inline__ void atomic_add(int i, atomic_t *v)
 {
@@ -26,21 +26,27 @@ static __inline__ void atomic_sub(int i, atomic_t *v)
        __asm__ __volatile__("subl %1,%0" : : "m" (*v), "id" (i));
 }
 
-static __inline__ void atomic_inc(atomic_t *v)
+static __inline__ void atomic_inc(volatile atomic_t *v)
 {
        __asm__ __volatile__("addql #1,%0" : : "m" (*v));
 }
 
-static __inline__ void atomic_dec(atomic_t *v)
+static __inline__ void atomic_dec(volatile atomic_t *v)
 {
        __asm__ __volatile__("subql #1,%0" : : "m" (*v));
 }
 
-static __inline__ int atomic_dec_and_test(atomic_t *v)
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
 {
        char c;
        __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c) : "m" (*v));
        return c != 0;
 }
 
+#define atomic_clear_mask(mask, v) \
+       __asm__ __volatile__("andl %1,%0" : : "m" (*v), "id" (~(mask)))
+
+#define atomic_set_mask(mask, v) \
+       __asm__ __volatile__("orl %1,%0" : : "m" (*v), "id" (mask));
+
 #endif /* __ARCH_M68K_ATOMIC __ */
index b715804cad45f172f93206da24b297c1a0ebd912..5c1f215a9cd8a9572b92a7df205500b5919aa726 100644 (file)
@@ -141,8 +141,7 @@ struct bootversion {
 #define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
 #define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
 
-#include <linux/config.h>
-#include <asm/zorro.h>
+#include <linux/zorro.h>
 
 #define COMPAT_NUM_AUTO    16
 
index 75045fe1b669de80202408cc14c27053148e69e6..cbc560777828e2ae96151f69e30ab5c43094f7c9 100644 (file)
@@ -10,7 +10,6 @@
 #endif
 
 #ifdef __KERNEL__
-#include <linux/config.h>
 #include <asm/types.h>
 
 /*
index 25bd276878579f6ff898c44bb620a5abfac4445f..1be5435223f6f04ce9f4a6ebc399e102d4e2b7b2 100644 (file)
@@ -5,7 +5,7 @@
 #define __ARCH_M68K_CACHE_H
 
 /* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  32      /* a guess */
+#define        L1_CACHE_BYTES  16
 
 #define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
index 93debce9f4224d985df6f83f543b02488edc4aeb..64adc2a4e359929b8b8d48dd8a9108efc0a4f22b 100644 (file)
@@ -35,6 +35,9 @@ unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum);
 
 unsigned int csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum);
 
+extern unsigned int
+csum_partial_copy_from_user ( const char *src, char *dst,
+                             int len, int sum, int *csum_err);
 
 /*
  *     This is a version of ip_compute_csum() optimized for IP headers,
index 0f5954b137f1026f031ba0c1f57c484440b0f4c0..2567392cd30926717d09fa88d73fcc368fbff074 100644 (file)
@@ -40,6 +40,7 @@
 #endif /* CONFIG_AMIGA */
 
 #ifdef CONFIG_ATARI
+#include <linux/interrupt.h>   /* intr_count */
 #include <asm/atarihw.h>
 #include <asm/atarihdreg.h>
 #include <asm/atariints.h>
index 385aa8c7f6ccc8a38e983d530be8e248bbce8c3a..fd68914ab2927e110941c066f114092886485f16 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ioctl.h,v 1.1 1996/08/24 12:43:44 root Exp $
+/* $Id: ioctl.h,v 1.3 1997/04/16 15:10:07 jes Exp $
  *
  * linux/ioctl.h for Linux by H.H. Bergman.
  */
index 7789be42f9fbfca3884b1b8ad16ae11cf2630b6d..46ad9206278a7a68f42563e1357c8ffcfcac28a2 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef _M68K_IRQ_H_
 #define _M68K_IRQ_H_
 
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
 #include <linux/config.h>
 
 /*
@@ -54,10 +51,24 @@ extern void enable_irq(unsigned int);
  * Adding an interrupt service routine for a source with this bit
  * set indicates a special machine specific interrupt source.
  * The machine specific files define these sources.
+ *
+ * The IRQ_MACHSPEC bit is now gone - the only thing it did was to
+ * introduce unnecessary overhead.
+ *
+ * All interrupt handling is actually machine specific so it is better
+ * to use function pointers, as used by the Sparc port, and select the
+ * interrupt handling functions when initializing the kernel. This way
+ * we save some unnecessary overhead at run-time. 
+ *                                                      01/11/97 - Jes
  */
 
-#define IRQ_MACHSPEC   (0x10000000L)
-#define IRQ_IDX(irq)   ((irq) & ~IRQ_MACHSPEC)
+extern void (*enable_irq)(unsigned int);
+extern void (*disable_irq)(unsigned int);
+
+extern int sys_request_irq(unsigned int, 
+       void (*)(int, void *, struct pt_regs *), 
+       unsigned long, const char *, void *);
+extern void sys_free_irq(unsigned int, void *);
 
 /*
  * various flags for request_irq()
index 9bbd635b08b9125b75ce2ac650b341fdaaeff2b5..c6a4b8b33a3f642d7716e9412c00faa8631de69b 100644 (file)
@@ -18,9 +18,7 @@ extern void (*mach_init_IRQ) (void);
 extern void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *);
 extern int (*mach_request_irq) (unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                                 unsigned long flags, const char *devname, void *dev_id);
-extern int (*mach_free_irq) (unsigned int irq, void *dev_id);
-extern void (*mach_enable_irq) (unsigned int irq);
-extern void (*mach_disable_irq) (unsigned int irq);
+extern void (*mach_free_irq) (unsigned int irq, void *dev_id);
 extern void (*mach_get_model) (char *model);
 extern int (*mach_get_hardware_list) (char *buffer);
 extern int (*mach_get_irq_list) (char *buf);
@@ -31,18 +29,14 @@ extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
                           int *min, int *sec);
 extern int (*mach_hwclk)(int, struct hwclk_time*);
 extern int (*mach_set_clock_mmss)(unsigned long);
-extern void (*mach_mksound)( unsigned int count, unsigned int ticks );
 extern void (*mach_reset)( void );
 extern int (*mach_floppy_init) (void);
 extern unsigned long (*mach_hd_init) (unsigned long, unsigned long);
 extern void (*mach_hd_setup)(char *, int *);
-extern void (*waitbut)(void);
 extern struct fb_info *(*mach_fb_init)(long *);
 extern long mach_max_dma_address;
-extern void (*mach_debug_init)(void);
 extern void (*mach_video_setup)(char *, int *);
 extern void (*mach_floppy_setup)(char *, int *);
 extern void (*mach_floppy_eject)(void);
-extern void (*mach_syms_export)(void);
 
 #endif /* _M68K_MACHDEP_H */
index 82dbe59c34f15b5d626e5cfaefaff031e258d8e9..d8d0beafe5b56c2e54507b7ba70a2c150dab6efd 100644 (file)
@@ -8,10 +8,58 @@
 
 #ifdef __KERNEL__
 
+#include<linux/config.h>
+
 #define STRICT_MM_TYPECHECKS
 
+/*
+ * We don't need to check for alignment etc.
+ */
+#if defined(CONFIG_OPTIMIZE_040) || defined(CONFIG_OPTIMIZE_060)
+static inline void copy_page(unsigned long to, unsigned long from)
+{
+  unsigned long tmp;
+
+  __asm__ __volatile__("1:\t"
+                      ".chip 68040\n\t"
+                      "move16 %1@+,%0@+\n\t"
+                      "move16 %1@+,%0@+\n\t"
+                      ".chip 68k\n\t"
+                      "dbra  %2,1b\n\t"
+                      : "=a" (to), "=a" (from), "=d" (tmp)
+                      : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1)
+                      );
+}
+
+static inline void clear_page(unsigned long page)
+{
+       unsigned long data, sp, tmp;
+
+       sp = page;
+
+       data = 0;
+
+       *((unsigned long *)(page))++ = 0;
+       *((unsigned long *)(page))++ = 0;
+       *((unsigned long *)(page))++ = 0;
+       *((unsigned long *)(page))++ = 0;
+
+       __asm__ __volatile__("1:\t"
+                            ".chip 68040\n\t"
+                            "move16 %2@+,%0@+\n\t"
+                            ".chip 68k\n\t"
+                            "subqw  #8,%2\n\t"
+                            "subqw  #8,%2\n\t"
+                            "dbra   %1,1b\n\t"
+                            : "=a" (page), "=d" (tmp)
+                            : "a" (sp), "0" (page),
+                              "1" ((PAGE_SIZE - 16) / 16 - 1));
+}
+
+#else
 #define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
 #define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#endif
 
 #ifdef STRICT_MM_TYPECHECKS
 /*
index 87a1ec63d55c2724e8283b44db372dd158d636dd..cd5cef191313360a3ce12e1743ecb2f109017139 100644 (file)
  * the m68k page table tree.
  */
 
+/* For virtual address to physical address conversion */
+extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
+extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
+#define VTOP(addr)  (mm_vtop((unsigned long)(addr)))
+#define PTOV(addr)  (mm_ptov((unsigned long)(addr)))
+
+/*
+ * Cache handling functions
+ */
+
+#define flush_icache()                                 \
+do {                                                   \
+       if (CPU_IS_040_OR_060)                          \
+               asm __volatile__ ("nop\n\t"             \
+                                 ".chip 68040\n\t"     \
+                                 "cinva %%ic\n\t"      \
+                                 ".chip 68k");         \
+       else {                                          \
+               unsigned long _tmp;                     \
+               asm __volatile__ ("movec %%cacr,%0\n\t" \
+                    "orw %1,%0\n\t"                    \
+                    "movec %0,%%cacr"                  \
+                    : "=&d" (_tmp)                     \
+                    : "id" (FLUSH_I));                 \
+       }                                               \
+} while (0)
+
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear (unsigned long paddr, int len);
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push (unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v (unsigned long vaddr, int len);
+
+/* cache code */
+#define FLUSH_I_AND_D  (0x00000808)
+#define FLUSH_I        (0x00000008)
+
+/* This is needed whenever the virtual mapping of the current
+   process changes.  */
+#define __flush_cache_all()                                            \
+    do {                                                               \
+       if (CPU_IS_040_OR_060)                                          \
+               __asm__ __volatile__ ("nop\n\t"                         \
+                                     ".chip 68040\n\t"                 \
+                                     "cpusha %dc\n\t"                  \
+                                     ".chip 68k");                     \
+       else {                                                          \
+               unsigned long _tmp;                                     \
+               __asm__ __volatile__ ("movec %%cacr,%0\n\t"             \
+                                     "orw %1,%0\n\t"                   \
+                                     "movec %0,%%cacr"                 \
+                                     : "=&d" (_tmp)                    \
+                                     : "di" (FLUSH_I_AND_D));          \
+       }                                                               \
+    } while (0)
+
+#define __flush_cache_030()                                            \
+    do {                                                               \
+       if (CPU_IS_020_OR_030) {                                        \
+               unsigned long _tmp;                                     \
+               __asm__ __volatile__ ("movec %%cacr,%0\n\t"             \
+                                     "orw %1,%0\n\t"                   \
+                                     "movec %0,%%cacr"                 \
+                                     : "=&d" (_tmp)                    \
+                                     : "di" (FLUSH_I_AND_D));          \
+       }                                                               \
+    } while (0)
+
+#define flush_cache_all() __flush_cache_all()
+
+extern inline void flush_cache_mm(struct mm_struct *mm)
+{
+#if FLUSH_VIRTUAL_CACHE_040
+       if (mm == current->mm) __flush_cache_all();
+#else
+       if (mm == current->mm) __flush_cache_030();
+#endif
+}
+
+extern inline void flush_cache_range(struct mm_struct *mm,
+                                    unsigned long start,
+                                    unsigned long end)
+{
+       if (mm == current->mm){
+#if FLUSH_VIRTUAL_CACHE_040
+           if (CPU_IS_040_OR_060)
+               cache_push_v(start, end-start);
+           else
+#endif
+               __flush_cache_030();
+       }
+}
+
+extern inline void flush_cache_page(struct vm_area_struct *vma,
+                                   unsigned long vmaddr)
+{
+       if (vma->vm_mm == current->mm){
+#if FLUSH_VIRTUAL_CACHE_040
+           if (CPU_IS_040_OR_060)
+               cache_push_v(vmaddr, PAGE_SIZE);
+           else
+#endif
+               __flush_cache_030();
+       }
+}
+
+/* Push the page at kernel virtual address and clear the icache */
+extern inline void flush_page_to_ram (unsigned long address)
+{
+    if (CPU_IS_040_OR_060) {
+       __asm__ __volatile__ ("nop\n\t"
+                             ".chip 68040\n\t"
+                             "cpushp %%dc,(%0)\n\t"
+                             "cinvp %%ic,(%0)\n\t"
+                             ".chip 68k"
+                             : : "a" (VTOP(address)));
+    }
+    else {
+       unsigned long _tmp;
+       __asm volatile ("movec %%cacr,%0\n\t"
+                       "orw %1,%0\n\t"
+                       "movec %0,%%cacr"
+                       : "=&d" (_tmp)
+                       : "di" (FLUSH_I));
+    }
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+extern inline void flush_pages_to_ram (unsigned long address, int n)
+{
+    if (CPU_IS_040_OR_060) {
+       while (n--) {
+           __asm__ __volatile__ ("nop\n\t"
+                                 ".chip 68040\n\t"
+                                 "cpushp %%dc,(%0)\n\t"
+                                 "cinvp %%ic,(%0)\n\t"
+                                 ".chip 68k"
+                                 : : "a" (VTOP(address)));
+           address += PAGE_SIZE;
+       }
+    }
+    else {
+       unsigned long _tmp;
+       __asm volatile ("movec %%cacr,%0\n\t"
+                       "orw %1,%0\n\t"
+                       "movec %0,%%cacr"
+                       : "=&d" (_tmp)
+                       : "di" (FLUSH_I));
+    }
+}
+
 /*
  * flush all atc entries (user-space entries only for the 680[46]0).
  */
@@ -31,7 +195,7 @@ static inline void __flush_tlb_one(unsigned long addr)
                                     ".chip 68k"
                                     : : "a" (addr));
        } else
-               __asm__ __volatile__("pflush #0,#0,(%0)" : : "a" (addr));
+               __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
 }
 
 #define flush_tlb() __flush_tlb()
@@ -69,17 +233,27 @@ static inline void flush_tlb_range(struct mm_struct *mm,
                __flush_tlb();
 }
 
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+       if (CPU_IS_040_OR_060) {
+               unsigned long old_fs = get_fs();
+               set_fs(KERNEL_DS);
+               __asm__ __volatile__(".chip 68040\n\t"
+                                    "pflush (%0)\n\t"
+                                    ".chip 68k"
+                                    : : "a" (addr));
+               set_fs(old_fs);
+       } else
+               __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
  */
 #define set_pte(pteptr, pteval)                                        \
        do{                                                     \
-       *(pteptr) = (pteval);                                   \
-       if (CPU_IS_060)                                         \
-               __asm__ __volatile__(".chip 68060\n\t"          \
-                                    "pflusha\n\t"              \
-                                    ".chip 68k");              \
+               *(pteptr) = (pteval);                           \
        } while(0)
 
 
@@ -160,9 +334,9 @@ typedef pte_table pte_tablepage[PTE_TABLES_PER_PAGE];
  * and initialized in head.S */
 extern int m68k_pgtable_cachemode;
 
-#if defined(CONFIG_M68040_OR_M68060_ONLY)
+#if defined(CPU_M68040_OR_M68060_ONLY)
 #define mm_cachebits _PAGE_CACHE040
-#elif defined(CONFIG_M68020_OR_M68030_ONLY)
+#elif defined(CPU_M68020_OR_M68030_ONLY)
 #define mm_cachebits 0
 #else
 extern unsigned long mm_cachebits;
@@ -234,12 +408,6 @@ extern pte_t * __bad_pagetable(void);
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-/* For virtual address to physical address conversion */
-extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
-extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
-#define VTOP(addr)  (mm_vtop((unsigned long)(addr)))
-#define PTOV(addr)  (mm_ptov((unsigned long)(addr)))
-
 /*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
@@ -393,19 +561,17 @@ extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
  * if any.
  */
 
-extern inline void nocache_page (unsigned long vaddr)
+/* Prior to calling these routines, the page should have been flushed
+ * from both the cache and ATC, or the CPU might not notice that the
+ * cache setting for the page has been changed. -jskov
+ */
+static inline void nocache_page (unsigned long vaddr)
 {
        if (CPU_IS_040_OR_060) {
                pgd_t *dir;
                pmd_t *pmdp;
                pte_t *ptep;
 
-               if(CPU_IS_060)
-                       __asm__ __volatile__ (".chip 68060\n\t"
-                                             "cpushp (%0)\n\t"
-                                             ".chip 68k"
-                                             : : "a" (VTOP(vaddr)));
-
                dir = pgd_offset_k(vaddr);
                pmdp = pmd_offset(dir,vaddr);
                ptep = pte_offset(pmdp,vaddr);
@@ -447,6 +613,8 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
                if (pmd_none(*pmd)) {
                        if (page) {
                                memset((void *) page, 0, PAGE_SIZE);
+                               flush_page_to_ram((unsigned long)page);
+                               flush_tlb_kernel_page((unsigned long)page);
                                nocache_page((unsigned long)page);
                                pmd_set(pmd,page);
                                return page + address;
@@ -510,6 +678,7 @@ extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
                pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
                if (pmd_none(*pmd)) {
                        if (page) {
+                               flush_tlb_kernel_page((unsigned long)page);
                                nocache_page((unsigned long)page);
                                pmd_set(pmd, page);
                                return page + address;
@@ -565,160 +734,6 @@ extern inline pgd_t * pgd_alloc(void)
        return (pgd_t *)get_pointer_table ();
 }
 
-#define flush_icache()                                 \
-do {                                                   \
-       if (CPU_IS_040_OR_060)                          \
-               asm __volatile__ ("nop\n\t"             \
-                                 ".chip 68040\n\t"     \
-                                 "cinva %%ic\n\t"      \
-                                 ".chip 68k");         \
-       else {                                          \
-               unsigned long _tmp;                     \
-               asm __volatile__ ("movec %%cacr,%0\n\t" \
-                    "orw %1,%0\n\t"                    \
-                    "movec %0,%%cacr"                  \
-                    : "=&d" (_tmp)                     \
-                    : "id" (FLUSH_I));                 \
-       }                                               \
-} while (0)
-
-/*
- * invalidate the cache for the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_clear (unsigned long paddr, int len);
-/*
- * push any dirty cache in the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_push (unsigned long paddr, int len);
-
-/*
- * push and invalidate pages in the specified user virtual
- * memory range.
- */
-extern void cache_push_v (unsigned long vaddr, int len);
-
-/* cache code */
-#define FLUSH_I_AND_D  (0x00000808)
-#define FLUSH_I        (0x00000008)
-
-/* This is needed whenever the virtual mapping of the current
-   process changes.  */
-#define __flush_cache_all()                                            \
-    do {                                                               \
-       if (CPU_IS_040_OR_060)                                          \
-               __asm__ __volatile__ ("nop\n\t"                         \
-                                     ".chip 68040\n\t"                 \
-                                     "cpusha %dc\n\t"                  \
-                                     ".chip 68k");                     \
-       else {                                                          \
-               unsigned long _tmp;                                     \
-               __asm__ __volatile__ ("movec %%cacr,%0\n\t"             \
-                                     "orw %1,%0\n\t"                   \
-                                     "movec %0,%%cacr"                 \
-                                     : "=&d" (_tmp)                    \
-                                     : "di" (FLUSH_I_AND_D));          \
-       }                                                               \
-    } while (0)
-
-#define __flush_cache_030()                                            \
-    do {                                                               \
-       if (CPU_IS_020_OR_030) {                                        \
-               unsigned long _tmp;                                     \
-               __asm__ __volatile__ ("movec %%cacr,%0\n\t"             \
-                                     "orw %1,%0\n\t"                   \
-                                     "movec %0,%%cacr"                 \
-                                     : "=&d" (_tmp)                    \
-                                     : "di" (FLUSH_I_AND_D));          \
-       }                                                               \
-    } while (0)
-
-#define flush_cache_all() __flush_cache_all()
-
-extern inline void flush_cache_mm(struct mm_struct *mm)
-{
-#if FLUSH_VIRTUAL_CACHE_040
-       if (mm == current->mm) __flush_cache_all();
-#else
-       if (mm == current->mm) __flush_cache_030();
-#endif
-}
-
-extern inline void flush_cache_range(struct mm_struct *mm,
-                                    unsigned long start,
-                                    unsigned long end)
-{
-       if (mm == current->mm){
-#if FLUSH_VIRTUAL_CACHE_040
-           if (CPU_IS_040_OR_060)
-               cache_push_v(start, end-start);
-           else
-#endif
-               __flush_cache_030();
-       }
-}
-
-extern inline void flush_cache_page(struct vm_area_struct *vma,
-                                   unsigned long vmaddr)
-{
-       if (vma->vm_mm == current->mm){
-#if FLUSH_VIRTUAL_CACHE_040
-           if (CPU_IS_040_OR_060)
-               cache_push_v(vmaddr, PAGE_SIZE);
-           else
-#endif
-               __flush_cache_030();
-       }
-}
-
-/* Push the page at kernel virtual address and clear the icache */
-extern inline void flush_page_to_ram (unsigned long address)
-{
-    if (CPU_IS_040_OR_060) {
-       __asm__ __volatile__ ("nop\n\t"
-                             ".chip 68040\n\t"
-                             "cpushp %%dc,(%0)\n\t"
-                             "cinvp %%ic,(%0)\n\t"
-                             ".chip 68k"
-                             : : "a" (VTOP(address)));
-    }
-    else {
-       unsigned long _tmp;
-       __asm volatile ("movec %%cacr,%0\n\t"
-                       "orw %1,%0\n\t"
-                       "movec %0,%%cacr"
-                       : "=&d" (_tmp)
-                       : "di" (FLUSH_I));
-    }
-}
-
-/* Push n pages at kernel virtual address and clear the icache */
-extern inline void flush_pages_to_ram (unsigned long address, int n)
-{
-    if (CPU_IS_040_OR_060) {
-       while (n--) {
-           __asm__ __volatile__ ("nop\n\t"
-                                 ".chip 68040\n\t"
-                                 "cpushp %%dc,(%0)\n\t"
-                                 "cinvp %%ic,(%0)\n\t"
-                                 ".chip 68k"
-                                 : : "a" (VTOP(address)));
-           address += PAGE_SIZE;
-       }
-    }
-    else {
-       unsigned long _tmp;
-       __asm volatile ("movec %%cacr,%0\n\t"
-                       "orw %1,%0\n\t"
-                       "movec %0,%%cacr"
-                       : "=&d" (_tmp)
-                       : "di" (FLUSH_I));
-    }
-}
-
 /*
  * Check if the addr/len goes up to the end of a physical
  * memory chunk.  Used for DMA functions.
index d96f693d4e0bcaa78aae93f83157390d0c994fe1..627e36501ada7637e69575ef5788e27472f1cf18 100644 (file)
@@ -8,6 +8,7 @@
 #define __ASM_M68K_PROCESSOR_H
 
 #include <asm/segment.h>
+#include <asm/fpu.h>
 
 /*
  * User space process size: 3.75GB. This is hardcoded into a few places,
@@ -18,7 +19,7 @@
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
+#define TASK_UNMAPPED_BASE     0xC0000000UL
 
 /*
  * Bus types
@@ -26,9 +27,6 @@
 #define EISA_bus 0
 #define MCA_bus 0
 
-/* MAX floating point unit state size (FSAVE/FRESTORE) */
-#define FPSTATESIZE   (216/sizeof(unsigned char))
-
 /* 
  * if you change this structure, you must change the code and offsets
  * in m68k/machasm.S
index 420bedaf0803d21236c4904ff5f4d7dc4ac1b484..885ca61468b7902d86c5e428e67edc8c130ca167 100644 (file)
@@ -6,12 +6,9 @@ struct scatterlist {
     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
 };
 
+/* This is bogus and should go away. */
 #define ISA_DMA_THRESHOLD (0x00ffffff)
 
 #endif /* !(_M68K_SCATTERLIST_H) */
index 2b87bfc12094529ce8586a8738b9abe46085be84..c4e3068fa83a6eff0929158f51569c82f205be1d 100644 (file)
@@ -2,6 +2,8 @@
 #define _M68K_SEMAPHORE_H
 
 #include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
 
 /*
  * SMP- and interrupt-safe semaphores..
  */
 
 struct semaphore {
-       int count;
-       int waiting;
+       atomic_t count;
+       atomic_t waking;
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { 1, 0, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL })
+#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL })
+#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL })
 
 asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
 asmlinkage void __up_wakeup(void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
 
-#define sema_init(sem, val)    ((sem)->count = val)
+#define sema_init(sem, val)    atomic_set(&((sem)->count), val)
+
+static inline void wake_one_more(struct semaphore * sem)
+{
+       atomic_inc(&sem->waking);
+}
 
 static inline int waking_non_zero(struct semaphore *sem)
 {
@@ -54,14 +62,36 @@ extern inline void down(struct semaphore * sem)
        __asm__ __volatile__(
                "| atomic down operation\n\t"
                "lea %%pc@(1f),%%a0\n\t"
-               "subql #1,%0\n\t"
+               "subql #1,%0@\n\t"
                "jmi " SYMBOL_NAME_STR(__down_failed) "\n"
                "1:"
                : /* no outputs */
-               : "m" (sem->count), "a" (sem1)
+               : "a" (sem1)
                : "%a0", "memory");
 }
 
+/*
+ * This version waits in interruptible state so that the waiting
+ * process can be killed.  The down_failed_interruptible routine
+ * returns negative for signalled and zero for semaphore acquired.
+ */
+extern inline int down_interruptible(struct semaphore * sem)
+{
+       register int ret __asm__ ("%d0");
+       register struct semaphore *sem1 __asm__ ("%a1") = sem;
+       __asm__ __volatile__(
+               "| atomic interruptible down operation\n\t"
+               "lea %%pc@(1f),%%a0\n\t"
+               "subql #1,%1@\n\t"
+               "jmi " SYMBOL_NAME_STR(__down_failed_interruptible) "\n\t"
+               "clrl %0\n"
+               "1:"
+               : "=d" (ret)
+               : "a" (sem1)
+               : "%d0", "%a0", "memory");
+       return ret;
+}
+
 /*
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
index cefaa2dea5e8cf7b9fd9082cdac18e5632986da5..7c873c34176b22b6fd182d33fd038ba4dd51b7b2 100644 (file)
@@ -171,7 +171,10 @@ typedef struct {
  */
 struct serial_icounter_struct {
        int cts, dsr, rng, dcd;
-       int reserved[16];
+       int rx, tx;
+       int frame, overrun, parity, brk;
+       int buf_overrun;
+       int reserved[9];
 };
 
 
@@ -192,7 +195,9 @@ struct serial_icounter_struct {
  * Counters of the input lines (CTS, DSR, RI, CD) interrupts
  */
 struct async_icount {
-       __u32   cts, dsr, rng, dcd;     
+       __u32   cts, dsr, rng, dcd, tx, rx;
+       __u32   frame, parity, overrun, brk;
+       __u32   buf_overrun;
 };
 
 struct async_struct {
@@ -281,7 +286,7 @@ extern task_queue tq_serial;
 static __inline__ void rs_sched_event(struct async_struct *info, int event)
 {
        info->event |= 1 << event;
-       queue_task_irq(&info->tqueue, &tq_serial);
+       queue_task(&info->tqueue, &tq_serial);
        mark_bh(SERIAL_BH);
 }
 
@@ -299,7 +304,8 @@ static __inline__ void rs_receive_char( struct async_struct *info,
        }
        *tty->flip.flag_buf_ptr++ = err;
        *tty->flip.char_buf_ptr++ = ch;
-       queue_task_irq(&tty->flip.tqueue, &tq_timer);
+       info->icount.rx++;
+       queue_task(&tty->flip.tqueue, &tq_timer);
 }
 
 static __inline__ int rs_get_tx_char( struct async_struct *info )
@@ -308,6 +314,7 @@ static __inline__ int rs_get_tx_char( struct async_struct *info )
        
        if (info->x_char) {
                ch = info->x_char;
+               info->icount.tx++;
                info->x_char = 0;
                return( ch );
        }
@@ -317,6 +324,7 @@ static __inline__ int rs_get_tx_char( struct async_struct *info )
 
        ch = info->xmit_buf[info->xmit_tail++];
        info->xmit_tail &= SERIAL_XMIT_SIZE - 1;
+       info->icount.tx++;
        if (--info->xmit_cnt < WAKEUP_CHARS)
                rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
        return( ch );
@@ -348,8 +356,7 @@ static __inline__ void rs_dcd_changed( struct async_struct *info, int dcd )
 #ifdef SERIAL_DEBUG_OPEN
                        printk("scheduling hangup...");
 #endif
-                       queue_task_irq(&info->tqueue_hangup,
-                                      &tq_scheduler);
+                       queue_task(&info->tqueue_hangup, &tq_scheduler);
                }
        }
 }
index b945f3cfa83b28dbf5e9d056f6e5e0b0870d9cdb..c95bdfc0127ad5d6194b210eaec1c7c891a004d2 100644 (file)
@@ -48,7 +48,7 @@ extern u_long m68k_machtype;
 #elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
 #  define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
 #else
-#  define CONFIG_AMIGA_ONLY
+#  define MACH_AMIGA_ONLY
 #  define MACH_IS_AMIGA (1)
 #  define MACH_TYPE (MACH_AMIGA)
 #endif
@@ -58,7 +58,7 @@ extern u_long m68k_machtype;
 #elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC)
 #  define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
 #else
-#  define CONFIG_ATARI_ONLY
+#  define MACH_ATARI_ONLY
 #  define MACH_IS_ATARI (1)
 #  define MACH_TYPE (MACH_ATARI)
 #endif
@@ -149,7 +149,7 @@ extern int m68k_is040or060;
 #elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
 #  define CPU_IS_020 (m68k_cputype & CPU_68020)
 #else
-#  define CONFIG_M68020_ONLY
+#  define CPU_M68020_ONLY
 #  define CPU_IS_020 (1)
 #endif
 
@@ -158,7 +158,7 @@ extern int m68k_is040or060;
 #elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
 #  define CPU_IS_030 (m68k_cputype & CPU_68030)
 #else
-#  define CONFIG_M68030_ONLY
+#  define CPU_M68030_ONLY
 #  define CPU_IS_030 (1)
 #endif
 
@@ -167,7 +167,7 @@ extern int m68k_is040or060;
 #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060)
 #  define CPU_IS_040 (m68k_cputype & CPU_68040)
 #else
-#  define CONFIG_M68040_ONLY
+#  define CPU_M68040_ONLY
 #  define CPU_IS_040 (1)
 #endif
 
@@ -176,18 +176,18 @@ extern int m68k_is040or060;
 #elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040)
 #  define CPU_IS_060 (m68k_cputype & CPU_68060)
 #else
-#  define CONFIG_M68060_ONLY
+#  define CPU_M68060_ONLY
 #  define CPU_IS_060 (1)
 #endif
 
 #if !defined(CONFIG_M68020) && !defined(CONFIG_M68030)
 #  define CPU_IS_020_OR_030 (0)
 #else
-#  define CONFIG_M68020_OR_M68030
+#  define CPU_M68020_OR_M68030
 #  if defined(CONFIG_M68040) || defined(CONFIG_M68060)
 #    define CPU_IS_020_OR_030 (!m68k_is040or060)
 #  else
-#    define CONFIG_M68020_OR_M68030_ONLY
+#    define CPU_M68020_OR_M68030_ONLY
 #    define CPU_IS_020_OR_030 (1)
 #  endif
 #endif
@@ -195,11 +195,11 @@ extern int m68k_is040or060;
 #if !defined(CONFIG_M68040) && !defined(CONFIG_M68060)
 #  define CPU_IS_040_OR_060 (0)
 #else
-#  define CONFIG_M68040_OR_M68060
+#  define CPU_M68040_OR_M68060
 #  if defined(CONFIG_M68020) || defined(CONFIG_M68030)
 #    define CPU_IS_040_OR_060 (m68k_is040or060)
 #  else
-#    define CONFIG_M68040_OR_M68060_ONLY
+#    define CPU_M68040_OR_M68060_ONLY
 #    define CPU_IS_040_OR_060 (1)
 #  endif
 #endif
index a2d28c218a4ec37bb1ddcf439643e611194e2c3f..9c13b0951c14604263e68ec7fd22b64a20988cf0 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _ASM_M68k_SIGCONTEXT_H
 #define _ASM_M68k_SIGCONTEXT_H
 
+#include<asm/fpu.h>
+
 struct sigcontext {
        unsigned long  sc_mask;         /* old sigmask */
        unsigned long  sc_usp;          /* old user stack pointer */
@@ -13,7 +15,7 @@ struct sigcontext {
        unsigned short sc_formatvec;
        unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
        unsigned long  sc_fpcntl[3];
-       unsigned char  sc_fpstate[216];
+       unsigned char  sc_fpstate[FPSTATESIZE];
 };
 
 #endif
index 58c8d3905585373703e6f40751c6c4e6affa1466..dc9024b734cf0645be330cb7d5e3ba3b0dc42151 100644 (file)
@@ -65,21 +65,24 @@ struct __xchg_dummy { unsigned long a[100]; };
 
 #if defined(CONFIG_ATARI) && !defined(CONFIG_AMIGA) && !defined(CONFIG_MAC)
 /* block out HSYNC on the atari */
-#define sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory")
+#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory")
 #else /* portable version */
-#define sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory")
+#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory")
 #endif /* machine compilation types */ 
-#define cli() __asm__ __volatile__ ("oriw  #0x0700,%/sr": : : "memory")
+#define __cli() __asm__ __volatile__ ("oriw  #0x0700,%/sr": : : "memory")
 #define nop() __asm__ __volatile__ ("nop"::)
 #define mb()  __asm__ __volatile__ (""   : : :"memory")
 
-#define save_flags(x) \
+#define __save_flags(x) \
 __asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory")
 
-#define restore_flags(x) \
+#define __restore_flags(x) \
 __asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory")
 
-#define iret() __asm__ __volatile__ ("rte": : :"memory", "sp", "cc")
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define restore_flags(x) __restore_flags(x)
 
 #ifndef CONFIG_RMW_INSNS
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
index 78494acc0a57a5d428b453d39bd727e800810586..0a3080a7699f2019c417ac3a2b19460d3322a913 100644 (file)
@@ -123,6 +123,7 @@ struct termios {
 #define  B230400 0010003
 #define  B460800 0010004
 #define CIBAUD   002003600000  /* input baud rate (not used) */
+#define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
 
 /* c_lflag bits */
index 134623f86e8142a41422cab693beeff1114459bb..3c022c3c8413188b1130427ed636d26e0f79d386 100644 (file)
@@ -53,6 +53,7 @@ struct termio {
 #define N_PPP          3
 #define N_STRIP                4
 #define N_AX25         5
+#define N_X25          6       /* X.25 async */
 
 #ifdef __KERNEL__
 
index 1b28727f0ec4ea2f91da3d2abdfb04a06c1ba243..864c49657ab9823f83958550e3d145aa161eaa6d 100644 (file)
@@ -714,6 +714,9 @@ __constant_copy_to_user(void *to, const void *from, unsigned long n)
  __constant_copy_to_user(to, from, n) :                \
  __generic_copy_to_user(to, from, n))
 
+#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
+
 /*
  * Copy a null terminated string from userspace.
  */
index d960779db72bdea50adebcdc6b79cdc03d685ef1..c526da9efe49a26528e44ecc4439cd0df6f8df32 100644 (file)
 #define __NR_mremap            163
 #define __NR_setresuid         164
 #define __NR_getresuid         165
-#define __NR_nfsservctl                166
+#define __NR_query_module      167
+#define __NR_poll              168
+#define __NR_nfsservctl                169
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
 #define __syscall_return(type, res) \
 do { \
        if ((unsigned long)(res) >= (unsigned long)(-125)) { \
-               errno = -(res); \
+       /* avoid using res which is declared to be in register d0; \
+          errno might expand to a function call and clobber it.  */ \
+               int __err = -(res); \
+               errno = __err; \
                res = -1; \
        } \
        return (type) (res); \
index 126e2354898b6c2d6181983769d2a0e1fa2e5a14..7ba0f8f1e246071d9bf2436f455f5597c5782638 100644 (file)
@@ -2,7 +2,7 @@
 #define _M68K_USER_H
 
 #include <asm/page.h>
-#include <linux/ptrace.h>
+
 /* Core file format: The core file is written in such a way that gdb
    can understand it and provide useful information to the user (under
    linux we use the 'trad-core' bfd).  There are quite a number of
@@ -74,7 +74,8 @@ struct user{
                                   esp register.  */
   long int signal;                     /* Signal that caused the core dump. */
   int reserved;                        /* No longer used */
-  struct pt_regs * u_ar0;      /* Used by gdb to help find the values for */
+  struct user_regs_struct *u_ar0;
+                               /* Used by gdb to help find the values for */
                                /* the registers. */
   struct user_m68kfp_struct* u_fpstate;        /* Math Co-processor pointer. */
   unsigned long magic;         /* To uniquely identify a core file */
index ca5a24331c65ea7c28a0451c35f0036ecb92dd87..c34bc36ef99a0ce7885488cdef7b3b007f44ad44 100644 (file)
@@ -6,7 +6,7 @@
 #define _ASM_PPC_ATOMIC_H_
 
 typedef struct { int counter; } atomic_t;
-#define ATOMIC_INIT    { 0 }
+#define ATOMIC_INIT(i) { (i) }
 
 /*
  * Make sure gcc doesn't try to be clever and move things around
index 077d0681edcf7cb5999d0357134f4c5b717e33d4..4d1f91372b3476a0aa81200118858d2e9e9a0b29 100644 (file)
@@ -9,8 +9,8 @@ struct semaphore {
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { 1, 0, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
 
 extern void __down(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
index e10cfbdfc60b7a5cadd7ca718857d1d57914b192..b74eebb461dbbb5fd4a24aa1603b02f257225774 100644 (file)
@@ -13,7 +13,7 @@ typedef struct { volatile int counter; } atomic_t;
 typedef struct { int counter; } atomic_t;
 #endif
 
-#define ATOMIC_INIT    { 0 }
+#define ATOMIC_INIT(i) { (i << 8) }
 
 #ifdef __KERNEL__
 #include <asm/system.h>
index 3348a3833f054db319128da1204cfe515735d821..6e47578f3463822a36784629560d33164221bd54 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errno.h,v 1.5 1996/07/13 02:05:13 tridge Exp $ */
+/* $Id: errno.h,v 1.6 1997/04/15 09:03:38 davem Exp $ */
 #ifndef _SPARC_ERRNO_H
 #define _SPARC_ERRNO_H
 
 #define        ELIBMAX         123     /* Atmpt to link in too many shared libs */
 #define        ELIBSCN         124     /* .lib section in a.out corrupted */
 
+#define        ENOMEDIUM       125     /* No medium found */
+#define        EMEDIUMTYPE     126     /* Wrong medium type */
+
 #endif
index b7eb21003d1e7e3d231571b4887250da52517602..7c4ba26e4ac36284d652e01db5f43f791f4d58df 100644 (file)
@@ -33,6 +33,9 @@
 
 #define FBTYPE_LASTPLUSONE      21     /* This is not last + 1 in fact... */
 
+/* Does not seem to be listed in the Sun file either */
+#define FBTYPE_CREATOR          22
+
 /* fbio ioctls */
 /* Returned by FBIOGTYPE */
 struct  fbtype {
index d45b33a5499c4d806c2de9c2c1fccbf4e62fe633..eddd82ca8a0df1d8fabed23cfd101ad62ec8b4de 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _SPARC_INIT_H
 #define _SPARC_INIT_H
 
-#ifndef __init
-#if (defined (__svr4__) || defined (__ELF__)) && !defined (MODULE)
+#if (defined (__svr4__) || defined (__ELF__))
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initdata __attribute__ ((__section__ (".data.init")))
 #define __initfunc(__arginit) \
@@ -21,6 +20,5 @@
 #define __FINIT
 #define __INITDATA
 #endif
-#endif
 
 #endif
index f0316d4b44deb6370d22892e261a6b4f5bf26c3c..87da9512682a8daa2314e30b8820cb0abe3f656f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: irq.h,v 1.15 1997/04/14 05:39:28 davem Exp $
+/* $Id: irq.h,v 1.16 1997/04/15 09:03:40 davem Exp $
  * irq.h: IRQ registers on the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -22,9 +22,9 @@ extern void (*disable_irq)(unsigned int);
 extern void (*enable_irq)(unsigned int);
 extern void (*disable_pil_irq)(unsigned int);
 extern void (*enable_pil_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 (*clear_clock_irq)(void);
+extern void (*clear_profile_irq)(int);
+extern void (*load_profile_irq)(int cpu, 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,
index 1b0ff36f654ee4b3c7bb10432eca20a067aab036..8b84e1dce12ada3b83ad9fa76775ec6b539b61e5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.59 1997/04/10 05:13:23 davem Exp $ */
+/* $Id: pgtable.h,v 1.60 1997/04/14 17:05:16 jj Exp $ */
 #ifndef _SPARC_PGTABLE_H
 #define _SPARC_PGTABLE_H
 
@@ -368,4 +368,30 @@ extern __inline__ void add_to_ctx_list(struct ctx_list *head, struct ctx_list *e
 #define add_to_free_ctxlist(entry) add_to_ctx_list(&ctx_free, entry)
 #define add_to_used_ctxlist(entry) add_to_ctx_list(&ctx_used, entry)
 
+extern __inline__ unsigned int
+__get_phys (unsigned long addr)
+{
+       switch (sparc_cpu_model){
+       case sun4c:
+               return sun4c_get_pte (addr) << PAGE_SHIFT;
+       case sun4m:
+               return ((srmmu_get_pte (addr) & 0xffffff00) << 4);
+       default:
+               return 0;
+       }
+}
+
+extern __inline__ int
+__get_iospace (unsigned long addr)
+{
+       switch (sparc_cpu_model){
+       case sun4c:
+               return -1; /* Don't check iospace on sun4c */
+       case sun4m:
+               return (srmmu_get_pte (addr) >> 28);
+       default:
+               return -1;
+       }
+}
+
 #endif /* !(_SPARC_PGTABLE_H) */
index 8ae3fd4d61762e4a153254eaa2046fdb819f2aae..48da860e45eb722b95ab7d7e0f8d1527cb670ed1 100644 (file)
@@ -13,8 +13,8 @@ struct semaphore {
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { { (1 << 8) }, { 0 }, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
 
 extern void __down(struct semaphore * sem);
 extern int __down_interruptible(struct semaphore * sem);
@@ -22,6 +22,12 @@ extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)    atomic_set(&((sem)->count), val)
 
+#define wake_one_more(sem)     atomic_inc(&sem->waking);
+
+/* XXX Put this in raw assembler for SMP case so that the atomic_t
+ * XXX spinlock can allow this to be done without grabbing the IRQ
+ * XXX global lock.
+ */
 static inline int waking_non_zero(struct semaphore *sem)
 {
        unsigned long flags;
index 4d5896c919318b8e39c5f5c4d7517407da27dc8d..7d4106b03a9eddd457968c2e54e1e5e6d92f92a2 100644 (file)
@@ -96,48 +96,6 @@ extern __inline__ int smp_processor_id(void)
        return cpuid;
 }
 
-extern __volatile__ int smp_process_available;
-
-extern __inline__ int smp_swap(volatile int *addr, int value)
-{
-       __asm__ __volatile__("swap [%2], %0\n\t" :
-                            "=&r" (value) :
-                            "0" (value), "r" (addr));
-       return value;
-}
-
-extern __inline__ __volatile__ void inc_smp_counter(volatile int *ctr)
-{
-       int tmp;
-
-       while((tmp = smp_swap(ctr, -1)) == -1)
-               while(*ctr == -1)
-                       ;
-
-       *ctr = (tmp + 1);
-}
-
-extern __inline__ __volatile__ void dec_smp_counter(volatile int *ctr)
-{
-       int tmp;
-
-       while((tmp = smp_swap(ctr, -1)) == -1)
-               while(*ctr == -1)
-                       ;
-
-       *ctr = (tmp - 1);
-}
-
-extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
-{
-       int value;
-
-       while((value = *ctr) == -1)
-               ;
-
-       return value;
-}
-
 #endif /* !(__ASSEMBLY__) */
 
 /* Sparc specific messages. */
@@ -154,8 +112,6 @@ extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
 #define MBOX_IDLECPU2         0xFD
 #define MBOX_STOPCPU2         0xFE
 
-#define NO_PROC_ID            0xFF
-
 #define PROC_CHANGE_PENALTY     20
 
 #define SMP_FROM_INT           1
@@ -163,4 +119,6 @@ extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
 
 #endif /* !(__SMP__) */
 
+#define NO_PROC_ID            0xFF
+
 #endif /* !(_SPARC_SMP_H) */
index 04d1abb70a7fcc08302aac62cb27cfee94540f7a..70860c40471523abf17857240e43a27cd6aee562 100644 (file)
@@ -14,7 +14,7 @@
 #define lock_kernel()                          do { } while(0)
 #define unlock_kernel()                                do { } while(0)
 #define release_kernel_lock(task, cpu, depth)  ((depth) = 1)
-#define reaquire_kernel_lock(task, cpu, depth) do { } while(0)
+#define reacquire_kernel_lock(task, cpu, depth)        do { } while(0)
 
 #else
 
@@ -34,7 +34,7 @@ do {                                                  \
 } while(0)
 
 /* Do not fuck with this without consulting arch/sparc/lib/locks.S first! */
-#define reaquire_kernel_lock(task, cpu, depth)                                 \
+#define reacquire_kernel_lock(task, cpu, depth)                                        \
 do {                                                                           \
        if(depth) {                                                             \
                register struct klock_info *klip asm("g1");                     \
@@ -42,7 +42,7 @@ do {                                                                          \
                klip = &klock_info;                                             \
                proc = cpu;                                                     \
                __asm__ __volatile__("mov       %%o7, %%g4\n\t"                 \
-                                    "call      ___lock_reaquire_kernel\n\t"    \
+                                    "call      ___lock_reacquire_kernel\n\t"   \
                                     " mov      %2, %%g2"                       \
                                     : /* No outputs. */                        \
                                     : "r" (klip), "r" (proc), "r" (depth)      \
index 7db15313e89a7871f42aa9b4013686a8ba40b78f..af6c5163f20effae4d7276985d819752a88d959f 100644 (file)
@@ -23,6 +23,33 @@ typedef struct { } spinlock_t;
 #define spin_lock_irqsave(lock, flags)         save_and_cli(flags)
 #define spin_unlock_irqrestore(lock, flags)    restore_flags(flags)
 
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct { } rwlock_t;
+#define RW_LOCK_UNLOCKED { }
+
+#define read_lock(lock)                do { } while(0)
+#define read_unlock(lock)      do { } while(0)
+#define write_lock(lock)       do { } while(0)
+#define write_unlock(lock)     do { } while(0)
+#define read_lock_irq(lock)    cli()
+#define read_unlock_irq(lock)  sti()
+#define write_lock_irq(lock)   cli()
+#define write_unlock_irq(lock) sti()
+
+#define read_lock_irqsave(lock, flags)         save_and_cli(flags)
+#define read_unlock_irqrestore(lock, flags)    restore_flags(flags)
+#define write_lock_irqsave(lock, flags)                save_and_cli(flags)
+#define write_unlock_irqrestore(lock, flags)   restore_flags(flags)
+
 #else /* !(__SMP__) */
 
 #include <asm/psr.h>
@@ -30,6 +57,8 @@ typedef struct { } spinlock_t;
 typedef unsigned char spinlock_t;
 #define SPIN_LOCK_UNLOCKED     0
 
+#define spin_lock_init(lock)   (*(lock) = 0)
+
 extern __inline__ void spin_lock(spinlock_t *lock)
 {
        register spinlock_t *lp asm("g1");
@@ -125,6 +154,92 @@ extern __inline__ void spin_unlock_irqrestore(spinlock_t *lock, unsigned long fl
        : "memory", "cc");
 }
 
+/* Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ *
+ * XXX This might create some problems with my dual spinlock
+ * XXX scheme, deadlocks etc. -DaveM
+ */
+typedef struct { volatile unsigned int lock; } rwlock_t;
+
+#define RW_LOCK_UNLOCKED { 0 }
+
+/* Sort of like atomic_t's on Sparc, but even more clever.
+ *
+ *     ------------------------------------
+ *     | 16-bit counter   | clock | wlock |  rwlock_t
+ *     ------------------------------------
+ *      31              16 15    8 7     0
+ *
+ * wlock signifies the one writer is in, the clock protects
+ * counter bumping, however a reader must acquire wlock
+ * before he can bump the counter on a read_lock().
+ * Similarly a writer, once he has the wlock, must await
+ * for the top 24 bits to all clear before he can finish
+ * going in (this includes the clock of course).
+ *
+ * Unfortunately this scheme limits us to ~65,000 cpus.
+ */
+extern __inline__ void read_lock(rwlock_t *rw)
+{
+       register rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__("
+       mov     %%o7, %%g4
+       call    ___rw_read_enter
+        ldstub [%%g1 + 3], %%g2
+"      : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "g7", "memory", "cc");
+}
+
+extern __inline__ void read_unlock(rwlock_t *rw)
+{
+       register rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__("
+       mov     %%o7, %%g4
+       call    ___rw_read_exit
+        ldstub [%%g1 + 2], %%g2
+"      : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "g7", "memory", "cc");
+}
+
+extern __inline__ void write_lock(rwlock_t *rw)
+{
+       register rwlock_t *lp asm("g1");
+       lp = rw;
+       __asm__ __volatile__("
+       mov     %%o7, %%g4
+       call    ___rw_write_enter
+        ldstub [%%g1 + 3], %%g2
+"      : /* no outputs */
+       : "r" (lp)
+       : "g2", "g4", "g7", "memory", "cc");
+}
+
+#define write_unlock(rw)       do { (rw)->lock = 0; } while(0)
+#define read_lock_irq(lock)    do { __cli(); read_lock(lock); } while (0)
+#define read_unlock_irq(lock)  do { read_unlock(lock); __sti(); } while (0)
+#define write_lock_irq(lock)   do { __cli(); write_lock(lock); } while (0)
+#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0)
+
+#define read_lock_irqsave(lock, flags) \
+       do { __save_and_cli(flags); read_lock(lock); } while (0)
+#define read_unlock_irqrestore(lock, flags) \
+       do { read_unlock(lock); __restore_flags(flags); } while (0)
+#define write_lock_irqsave(lock, flags)        \
+       do { __save_and_cli(flags); write_lock(lock); } while (0)
+#define write_unlock_irqrestore(lock, flags) \
+       do { write_unlock(lock); __restore_flags(flags); } while (0)
+
 #endif /* __SMP__ */
 
 #endif /* !(__ASSEMBLY__) */
index bcdd093b5821cec21e0c849aa7b06d557cc37065..e4ecd60465838a0041509878f446a9fae67df930 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.56 1997/04/14 05:39:30 davem Exp $ */
+/* $Id: system.h,v 1.57 1997/04/15 09:03:45 davem Exp $ */
 #ifndef __SPARC_SYSTEM_H
 #define __SPARC_SYSTEM_H
 
@@ -93,9 +93,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
        "rd     %%wim, %%g5\n\t"                                                        \
        "wr     %%g4, 0x20, %%psr\n\t"                                                  \
        "nop\n\t"                                                                       \
-       "mov    %5, %%g7\n\t"                                                           \
        "std    %%g4, [%%g6 + %2]\n\t"                                                  \
-       "st     %%g7, [%%g6 + %6]\n\t"                                                  \
        "ldd    [%1 + %2], %%g4\n\t"                                                    \
        "mov    %1, %%g6\n\t"                                                           \
        "st     %1, [%0]\n\t"                                                           \
@@ -113,8 +111,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
        " 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), "i" (255),                                                     \
-         "i" ((const unsigned long)(&((struct task_struct *)0)->processor))            \
+         "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");                                                                          \
index 875d0a9f5a4e187bbe50e04afee542f51a8e6897..ec496fa17db5a702549a71a137e80388dc439a1e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: atomic.h,v 1.13 1997/04/14 06:56:57 davem Exp $
+/* $Id: atomic.h,v 1.14 1997/04/16 05:57:06 davem Exp $
  * atomic.h: Thankfully the V9 is at least reasonable for this
  *           stuff.
  *
@@ -15,7 +15,7 @@
 #define __atomic_fool_gcc(x) ((struct { int a[100]; } *)x)
 
 typedef struct { int counter; } atomic_t;
-#define ATOMIC_INIT    { 0 }
+#define ATOMIC_INIT(i) { (i) }
 
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
index 7a4d69f5c069f53d4e365ac19d9f5c48bc4a5f6b..9da8553dbd38853a5eb88804cd74e4e60b2d967b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: errno.h,v 1.1 1996/11/20 15:27:39 davem Exp $ */
+/* $Id: errno.h,v 1.2 1997/04/15 12:46:11 jj Exp $ */
 #ifndef _SPARC64_ERRNO_H
 #define _SPARC64_ERRNO_H
 
 #define        ELIBMAX         123     /* Atmpt to link in too many shared libs */
 #define        ELIBSCN         124     /* .lib section in a.out corrupted */
 
+#define ENOMEDIUM       125     /* No medium found */
+#define EMEDIUMTYPE     126     /* Wrong medium type */
+
 #endif /* !(_SPARC64_ERRNO_H) */
index 628a3b27dfb8f697992ad53d0b6b2a4ca9d5bd01..3d8713468b34d31f4549591b8ca123839d4b7340 100644 (file)
@@ -33,6 +33,9 @@
 
 #define FBTYPE_LASTPLUSONE      21     /* This is not last + 1 in fact... */
 
+/* Does not seem to be listed in the Sun file either */
+#define FBTYPE_CREATOR          22
+
 /* fbio ioctls */
 /* Returned by FBIOGTYPE */
 struct  fbtype {
index 13c00f1afc0ec4fa781083044c157a612a37a444..33044df82d6e4b45520e6a713f2f2a5e5eacb14c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fcntl.h,v 1.2 1997/04/04 00:50:15 davem Exp $ */
+/* $Id: fcntl.h,v 1.3 1997/04/14 17:05:20 jj Exp $ */
 #ifndef _SPARC64_FCNTL_H
 #define _SPARC64_FCNTL_H
 
@@ -48,7 +48,6 @@
                                   blocking */
 #define LOCK_UN                8       /* remove lock */
 
-/* XXX 32-bit binary compatability item... -DaveM */
 struct flock {
        short l_type;
        short l_whence;
@@ -58,4 +57,15 @@ struct flock {
        short __unused;
 };
 
+#ifdef __KERNEL__
+struct flock32 {
+       short l_type;
+       short l_whence;
+       __kernel_off_t32 l_start;
+       __kernel_off_t32 l_len;
+       __kernel_pid_t32 l_pid;
+       short __unused;
+};
+#endif
+
 #endif /* !(_SPARC64_FCNTL_H) */
index 766caee60cc613f9b8162ca266ca90fea62b5f74..8076e88f70b44ace9da3380b0a3e2fff7d1e3328 100644 (file)
@@ -1,9 +1,6 @@
-#ifndef _SPARC64_INIT_H
-#define _SPARC64_INIT_H
+#ifndef _SPARC_INIT_H
+#define _SPARC_INIT_H
 
-#ifndef __init
-/* 'cause of buggy linker, we don't use this for now... */
-#if 0 && !defined (MODULE)
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initdata __attribute__ ((__section__ (".data.init")))
 #define __initfunc(__arginit) \
 #define __INIT         .section        ".text.init",#alloc,#execinstr
 #define __FINIT        .previous
 #define __INITDATA     .section        ".data.init",#alloc,#write
-#else
-#define        __init
-#define __initdata
-#define __initfunc(__arginit) __arginit
-/* For assembly routines */
-#define __INIT
-#define __FINIT
-#define __INITDATA
-#endif
-#endif
 
 #endif
index 16dda67844aa8f57d91af131b1595bb98996062d..3e14f7c9fc33ab1dc137fcd8762cf0f0e9c6d746 100644 (file)
@@ -4,12 +4,11 @@
 /* 
  * These are used to wrap system calls on the sparc.
  *
- * See arch/sparc64/kernel/sys_sparc.c for ugly details..
+ * See arch/sparc64/kernel/sys_sparc32.c for ugly details..
  */
-/* XXX 32-bit binary compatability... */
 struct ipc_kludge {
-       struct msgbuf *msgp;
-       long msgtyp;
+       u32 msgp;
+       s32 msgtyp;
 };
 
 #define SEMOP           1
@@ -24,6 +23,7 @@ struct ipc_kludge {
 #define SHMGET         23
 #define SHMCTL         24
 
-#define IPCCALL(version,op)    ((version)<<16 | (op))
+/* We don't need to maintain backward compatibility on 64bit, we've started fresh */
+#define IPCCALL(version,op)    (op)
 
 #endif
index d812e295b8ce8b7f11febf4040b06c8362679802..600ac163237346dcd31174a0249799a43bd2b26c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.27 1997/04/10 23:32:46 davem Exp $
+/* $Id: pgtable.h,v 1.28 1997/04/14 17:05:19 jj Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -673,6 +673,31 @@ extern inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
 #define SWP_OFFSET(entry)      ((entry) >> (PAGE_SHIFT+8))
 #define SWP_ENTRY(type,offset) pte_val(mk_swap_pte((type),(offset)))
 
+extern __inline__ unsigned long
+sun4u_get_pte (unsigned long addr)
+{
+       pgd_t *pgdp;
+       pmd_t *pmdp;
+       pte_t *ptep;
+       
+       pgdp = pgd_offset (current->mm, addr);
+       pmdp = pmd_offset (pgdp, addr);
+       ptep = pte_offset (pmdp, addr);
+       return pte_val (*ptep) & _PAGE_PADDR;
+}
+
+extern __inline__ unsigned int
+__get_phys (unsigned long addr)
+{
+       return (sun4u_get_pte (addr) & 0x0fffffff);
+}
+
+extern __inline__ int
+__get_iospace (unsigned long addr)
+{
+       return ((sun4u_get_pte (addr) & 0xf0000000) >> 28);
+}
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(_SPARC64_PGTABLE_H) */
index 424e850b04925103e5bdd81ffb3dcefaf16917dc..6bf51c96aa2686d205914b1ef99a8c2b4f2fea66 100644 (file)
@@ -34,6 +34,27 @@ typedef struct {
        int     val[2];
 } __kernel_fsid_t;
 
+/* Now 32bit compatibility types */
+typedef unsigned int           __kernel_size_t32;
+typedef int                    __kernel_ssize_t32;
+typedef int                    __kernel_ptrdiff_t32;
+typedef int                    __kernel_time_t32;
+typedef int                    __kernel_clock_t32;
+typedef int                    __kernel_pid_t32;
+typedef unsigned short         __kernel_ipc_pid_t32;
+typedef unsigned short         __kernel_uid_t32;
+typedef unsigned short         __kernel_gid_t32;
+typedef unsigned short         __kernel_dev_t32;
+typedef unsigned int           __kernel_ino_t32;
+typedef unsigned short         __kernel_mode_t32;
+typedef unsigned short         __kernel_umode_t32;
+typedef short                  __kernel_nlink_t32;
+typedef int                    __kernel_daddr_t32;
+typedef int                    __kernel_off_t32;
+typedef unsigned int           __kernel_caddr_t32;
+typedef long                  __kernel_loff_t32;
+typedef __kernel_fsid_t        __kernel_fsid_t32;
+
 #undef __FD_SET
 static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 {
index 28deedf31ba265abe076815ed9d1acb244c65696..25c907ddbd0fd63423cc2d43a3cdbff1fad1bc32 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.20 1997/04/11 22:34:54 davem Exp $
+/* $Id: processor.h,v 1.21 1997/04/14 17:05:18 jj Exp $
  * include/asm-sparc64/processor.h
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -132,6 +132,7 @@ do { \
        "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
        "stx            %1,   [%0 + %2 + 0x70]\n\t" \
        "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
+       "wrpr           %%g0, 1, %%wstate\n\t" \
        : \
        : "r" (regs), "r" (sp - REGWIN_SZ), \
          "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0]))); \
@@ -167,6 +168,7 @@ do { \
        "stx            %%g0, [%0 + %2 + 0x68]\n\t" \
        "stx            %1,   [%0 + %2 + 0x70]\n\t" \
        "stx            %%g0, [%0 + %2 + 0x78]\n\t" \
+       "wrpr           %%g0, 2, %%wstate\n\t" \
        : \
        : "r" (regs), "r" (sp - REGWIN32_SZ), \
          "i" ((const unsigned long)(&((struct pt_regs *)0)->u_regs[0])), \
index 7f5066c4ab8ee13ccf1b0a8ffa0914ef897041e5..57dc42260299c7c6d7021a77b60b658ef5774506 100644 (file)
@@ -2,8 +2,10 @@
 #define _SPARC64_SEMAPHORE_H
 
 /* These are actually reasonable on the V9. */
+#ifdef __KERNEL__
 
 #include <asm/atomic.h>
+#include <asm/system.h>
 
 struct semaphore {
        atomic_t count;
@@ -11,8 +13,8 @@ struct semaphore {
        struct wait_queue * wait;
 };
 
-#define MUTEX ((struct semaphore) { { 1 }, { 0 }, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { { 0 }, { 0 }, NULL })
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
 
 extern void __down(struct semaphore * sem);
 extern int  __down_interruptible(struct semaphore * sem);
@@ -20,6 +22,23 @@ extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)    atomic_set(&((sem)->count), val)
 
+#define wake_one_more(sem)      atomic_inc(&sem->waking);
+
+extern __inline__ int waking_non_zero(struct semaphore *sem)
+{
+        unsigned long flags;
+        int ret = 0;
+
+        save_flags(flags);
+        cli();
+        if (atomic_read(&sem->waking) > 0) {
+                atomic_dec(&sem->waking);
+                ret = 1;
+        }
+        restore_flags(flags);
+        return ret;
+}
+
 extern __inline__ void down(struct semaphore * sem)
 {
        if (atomic_dec_return(&sem->count) < 0)
@@ -40,4 +59,6 @@ extern __inline__ void up(struct semaphore * sem)
                __up(sem);
 }      
 
+#endif /* __KERNEL__ */
+
 #endif /* !(_SPARC64_SEMAPHORE_H) */
index 70cfa56039c06a9c3cb3f6a4b4e7ee9c56abe7df..73fc7178088115bc651980bd10c2bd2b6a0c6d5d 100644 (file)
@@ -106,51 +106,6 @@ extern __inline__ int smp_processor_id(void)
 
 
 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)
-       : "cc");
-}
-
-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)
-       : "cc");
-}
-
-extern __inline__ __volatile__ int read_smp_counter(volatile int *ctr)
-{
-       return *ctr;
-}
-
 #endif /* !(__ASSEMBLY__) */
 
 /* Sparc specific messages. */
index 8d500d51a5a05db24165c858dabb2b934ac99f3d..12821b21557b5d96ca762be43fb0c62ad628b374 100644 (file)
@@ -15,7 +15,7 @@
 #define lock_kernel()                          do { } while(0)
 #define unlock_kernel()                                do { } while(0)
 #define release_kernel_lock(task, cpu, depth)  ((depth) = 1)
-#define reaquire_kernel_lock(task, cpu, depth) do { } while(0)
+#define reacquire_kernel_lock(task, cpu, depth)        do { } while(0)
 
 #else
 #error SMP on sparc64 not supported yet
index dd9a4a78861f5703374fc392a125f13e5a8a4e59..470f6f8e205598b17f8e21909b5477d1511796f0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: stat.h,v 1.1 1996/12/26 14:22:31 davem Exp $ */
+/* $Id: stat.h,v 1.2 1997/04/16 14:52:34 jj Exp $ */
 #ifndef _SPARC64_STAT_H
 #define _SPARC64_STAT_H
 
@@ -18,24 +18,23 @@ struct __old_kernel_stat {
        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;
+       __kernel_dev_t32   st_dev;
+       __kernel_ino_t32   st_ino;
+       __kernel_mode_t32  st_mode;
+       short              st_nlink;
+       __kernel_uid_t32   st_uid;
+       __kernel_gid_t32   st_gid;
+       __kernel_dev_t32   st_rdev;
+       __kernel_off_t32   st_size;
+       __kernel_time_t32  st_atime;
+       unsigned int       __unused1;
+       __kernel_time_t32  st_mtime;
+       unsigned int       __unused2;
+       __kernel_time_t32  st_ctime;
+       unsigned int       __unused3;
+       __kernel_off_t32   st_blksize;
+       __kernel_off_t32   st_blocks;
        unsigned int  __unused4[2];
 };
 
index 1e976b72571440404a29b0b61cd006fd6773e781..5aee11569fbd0a8624b793a7eb7493956ee1a048 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: statfs.h,v 1.1 1996/12/26 14:22:40 davem Exp $ */
+/* $Id: statfs.h,v 1.2 1997/04/14 17:05:22 jj Exp $ */
 #ifndef _SPARC64_STATFS_H
 #define _SPARC64_STATFS_H
 
@@ -10,7 +10,6 @@ typedef __kernel_fsid_t       fsid_t;
 
 #endif
 
-/* XXX Fix this for full backwards 32-bit compat. */
 struct statfs32 {
        int f_type;
        int f_bsize;
@@ -19,7 +18,7 @@ struct statfs32 {
        int f_bavail;
        int f_files;
        int f_ffree;
-       __kernel_fsid_t f_fsid;
+       __kernel_fsid_t32 f_fsid;
        int f_namelen;  /* SunOS ignores this field. */
        int f_spare[6];
 };
index 4c9a8495bd955cf531f4307ca3aa41aadd033b4d..67a3caaacd2682c8444449dd12bb8b8bb89d24d2 100644 (file)
  * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
  */
 
+/*
+ * Disable the __initfunc macros if a file that is a part of a
+ * module attempts to use them. We do not want to interfere
+ * with module linking.
+ */
+
+#ifndef MODULE
 #include <asm/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+#endif
 
 #endif
index 3c3c26c2dd7269e9b31d290b5cbf2781f694f712..93cc5bd511a2603c22ee315b1e6b8fc8cd973a68 100644 (file)
@@ -1,14 +1,20 @@
-/* $Id: parport.h,v 1.1.2.5 1997/03/29 21:08:31 phil Exp $ */
+/* $Id: parport.h,v 1.2.6.3 1997/04/16 21:21:03 phil Exp $ */
 
 #ifndef _PARPORT_H_
 #define _PARPORT_H_
 
 #include <asm/system.h>
 #include <asm/ptrace.h>
+#include <linux/proc_fs.h>
 
 /* Maximum of 8 ports per machine */
 #define PARPORT_MAX  8 
 
+/* Magic numbers */
+#define PARPORT_IRQ_NONE  -1
+#define PARPORT_DMA_NONE  -1
+#define PARPORT_DISABLE   -2
+
 /* Type classes for Plug-and-Play probe */
 
 typedef enum {
@@ -78,6 +84,14 @@ struct ppd {
        struct ppd *prev;
 };
 
+struct parport_dir{
+       struct proc_dir_entry *entry;    /* Directory /proc/parport/X     */
+       struct proc_dir_entry *irq;      /* IRQ entry /proc/parport/X/irq */
+       struct proc_dir_entry *devices;  /* /proc/parport/X/devices       */
+       struct proc_dir_entry *hardware; /* /proc/parport/X/hardware      */
+    char name[4]; /* /proc/parport/"XXXX" */
+};
+
 /* A parallel port */
 struct parport {
        unsigned int base;      /* base address */
@@ -93,8 +107,9 @@ struct parport {
        unsigned int ecr;       /* ECP ECR register */
        struct parport *next;
         unsigned int flags; 
-       struct proc_dir_entry *proc_dir;
+       struct parport_dir pdir;
        struct parport_device_info probe_info; 
+       int speed;  /* Max Write in Bytes/s */
 };
 
 /* parport_register_port registers a new parallel port at the given address (if
@@ -174,8 +189,10 @@ extern int parport_wait_peripheral(struct parport *, unsigned char, unsigned
                                   char);
 
 /* Prototypes from parport_procfs */
+extern int parport_proc_init(void);
+extern int parport_proc_cleanup(void);
 extern int parport_proc_register(struct parport *pp);
-extern void parport_proc_unregister(struct parport *pp);
+extern int parport_proc_unregister(struct parport *pp);
 
 /* Prototypes from parport_ksyms.c */
 extern void dec_parport_count(void);
index d0304398464e5cdf6c4e3daa127ed98b6e3d73cc..c8ec07ab4a47542ca50e4e673d3ef8e8be3b34da 100644 (file)
@@ -112,8 +112,8 @@ struct sched_param {
  * _adding_ to the beginning of the run-queue has
  * a separate lock).
  */
+extern rwlock_t tasklist_lock;
 extern spinlock_t scheduler_lock;
-extern spinlock_t tasklist_lock;
 
 extern void sched_init(void);
 extern void show_state(void);
@@ -174,14 +174,16 @@ struct mm_struct {
                &init_mmap, &init_mmap, MUTEX }
 
 struct signal_struct {
-       int count;
-       struct sigaction action[32];
+       atomic_t                count;
+       struct sigaction        action[32];
+       spinlock_t              siglock;
 };
 
 
 #define INIT_SIGNALS { \
-               1, \
-               { {0,}, } }
+               ATOMIC_INIT(1), \
+               { {0,}, }, \
+               SPIN_LOCK_UNLOCKED }
 
 struct task_struct {
 /* these are hardcoded - don't touch */
@@ -261,6 +263,8 @@ struct task_struct {
        int processor;
        int last_processor;
        int lock_depth;         /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */  
+       /* Spinlocks for various pieces or per-task state. */
+       spinlock_t sigmask_lock;        /* Protects signal and blocked */
 };
 
 /*
@@ -471,11 +475,11 @@ extern inline void poll_wait(struct wait_queue ** wait_address, poll_table * p)
        p->nr++;
 }
 
-#define REMOVE_LINKS(p) do { \
-       spin_lock(&tasklist_lock); \
+#define REMOVE_LINKS(p) do { unsigned long flags; \
+       write_lock_irqsave(&tasklist_lock, flags); \
        (p)->next_task->prev_task = (p)->prev_task; \
        (p)->prev_task->next_task = (p)->next_task; \
-       spin_unlock(&tasklist_lock); \
+       write_unlock_irqrestore(&tasklist_lock, flags); \
        if ((p)->p_osptr) \
                (p)->p_osptr->p_ysptr = (p)->p_ysptr; \
        if ((p)->p_ysptr) \
@@ -484,13 +488,13 @@ extern inline void poll_wait(struct wait_queue ** wait_address, poll_table * p)
                (p)->p_pptr->p_cptr = (p)->p_osptr; \
        } while (0)
 
-#define SET_LINKS(p) do { \
-       spin_lock(&tasklist_lock); \
+#define SET_LINKS(p) do { unsigned long flags; \
+       write_lock_irqsave(&tasklist_lock, flags); \
        (p)->next_task = &init_task; \
        (p)->prev_task = init_task.prev_task; \
        init_task.prev_task->next_task = (p); \
        init_task.prev_task = (p); \
-       spin_unlock(&tasklist_lock); \
+       write_unlock_irqrestore(&tasklist_lock, flags); \
        (p)->p_ysptr = NULL; \
        if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
                (p)->p_osptr->p_ysptr = p; \
index 0bc29b7f05335926d3aa32fbe72ed6b5e491669c..b15f2a0db02f3f14bc03e600c77ae98f843c19db 100644 (file)
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT   4
+#define WIRELESS_EXT   5
 
 /*
  * Changes :
  *
  * V2 to V3
  * --------
- *     Alan Cox start some imcompatibles changes. I've integrated a bit more.
+ *     Alan Cox start some incompatibles changes. I've integrated a bit more.
  *     - Encryption renamed to Encode to avoid US regulation problems
  *     - Frequency changed from float to struct to avoid problems on old 386
  *
  * V3 to V4
  * --------
  *     - Add sensitivity
+ *
+ * V4 to V5
+ * --------
+ *     - Missing encoding definitions in range
+ *     - Access points stuff
  */
 
 /* -------------------------- IOCTL LIST -------------------------- */
 #define SIOCSIWSPY     0x8B10          /* set spy addresses */
 #define SIOCGIWSPY     0x8B11          /* get spy info (quality of link) */
 
+/* Access Point manipulation */
+#define SIOCSIWAP      0x8B14          /* set access point hardware addresses */
+#define SIOCGIWAP      0x8B15          /* get access point hardware addresses */
+#define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
+
 /* ------------------------- IOCTL STUFF ------------------------- */
 
 /* The first and the last (range) */
 #define SIOCIWFIRST    0x8B00
-#define SIOCIWLAST     0x8B13
+#define SIOCIWLAST     0x8B17
 
 /* Even : get (world access), odd : set (root access) */
 #define IW_IS_SET(cmd) (!((cmd) & 0x1))
@@ -185,6 +195,17 @@ struct     iw_discarded
        __u32           misc;           /* Others cases */
 };
 
+/*
+ *     Encoding information (setting and so on)
+ *     Encoding might be hardware encryption, scrambing or others
+ */
+struct iw_encoding
+{
+  __u8 method;                 /* Algorithm number / key used */
+  __u64        code;                   /* Data/key used for algorithm */
+};
+
+
 /* ------------------------ WIRELESS STATS ------------------------ */
 /*
  * Wireless statistics (used for /proc/net/wireless)
@@ -234,13 +255,11 @@ struct    iwreq
                                         * 0-1000 = channel
                                         * > 1000 = frequency in Hz */
 
-               struct          /* Encoding stuff */
-               {
-                       __u8    method;         /* Algorithm number / off */
-                       __u64   code;           /* Data used for algorithm */
-               }       encoding;
+               struct iw_encoding      encoding;       /* Encoding stuff */
 
-               __u32   sensitivity;    /* signal level threshold */
+               __u32   sensitivity;            /* signal level threshold */
+
+               struct sockaddr ap_addr;        /* Access point address */
 
                struct          /* For all data bigger than 16 octets */
                {
@@ -275,16 +294,16 @@ struct    iw_range
        __u16           num_channels;   /* Number of channels [0; num - 1] */
        __u8            num_frequency;  /* Number of entry in the list */
        struct iw_freq  freq[IW_MAX_FREQUENCIES];       /* list */
-
        /* Note : this frequency list doesn't need to fit channel numbers */
 
-       /* Encoder stuff */
-
        /* signal level threshold range */
        __u32   sensitivity;
 
        /* Quality of link & SNR stuff */
        struct iw_quality       max_qual;       /* Quality of the link */
+
+       /* Encoder stuff */
+       struct iw_encoding      max_encoding;   /* Encoding max range */
 };
 
 /*
index 390aa51dff547aa450438317f59b48108d8eae4c..7e6c57f4c99de0b55677df1f6a2b80b92afa2005 100644 (file)
@@ -389,7 +389,7 @@ struct sock
 
        unsigned short          cong_window;
        unsigned short          cong_count;
-       atomic_t                packets_out;
+       int                     packets_out;
        unsigned short          shutdown;
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
index add1f30c82c58d38e81211a94b5f7dfed8ff0873..00b29260609b4eb55164ce3438cf5d31bd7353c6 100644 (file)
@@ -948,7 +948,7 @@ __initfunc(asmlinkage void start_kernel(void))
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
-__initfunc(static int do_linuxrc(void * shell))
+static int do_linuxrc(void * shell)
 {
        static char *argv[] = { "linuxrc", NULL, };
 
index 85ea2b26f62a30a987fb670b50d36679b2fb1cbb..51e9de867b0d3098723092235fca85edb76d658c 100644 (file)
@@ -41,18 +41,23 @@ static inline void generate(unsigned long sig, struct task_struct * p)
         * be handled immediately (ie non-blocked and untraced)
         * and that is ignored (either explicitly or by default)
         */
+       spin_lock_irq(&p->sig->siglock);
        if (!(mask & p->blocked) && !(p->flags & PF_PTRACED)) {
                /* don't bother with ignored signals (but SIGCHLD is special) */
                if (sa->sa_handler == SIG_IGN && sig != SIGCHLD)
-                       return;
+                       goto out;
                /* some signals are ignored by default.. (but SIGCONT already did its deed) */
                if ((sa->sa_handler == SIG_DFL) &&
                    (sig == SIGCONT || sig == SIGCHLD || sig == SIGWINCH || sig == SIGURG))
-                       return;
+                       goto out;
        }
+       spin_lock(&p->sigmask_lock);
        p->signal |= mask;
+       spin_unlock(&p->sigmask_lock);
        if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked))
                wake_up_process(p);
+out:
+       spin_unlock_irq(&p->sig->siglock);
 }
 
 /*
@@ -65,16 +70,23 @@ void force_sig(unsigned long sig, struct task_struct * p)
        if (p->sig) {
                unsigned long mask = 1UL << sig;
                struct sigaction *sa = p->sig->action + sig;
+
+               spin_lock_irq(&p->sig->siglock);
+
+               spin_lock(&p->sigmask_lock);
                p->signal |= mask;
                p->blocked &= ~mask;
+               spin_unlock(&p->sigmask_lock);
+
                if (sa->sa_handler == SIG_IGN)
                        sa->sa_handler = SIG_DFL;
                if (p->state == TASK_INTERRUPTIBLE)
                        wake_up_process(p);
+
+               spin_unlock_irq(&p->sig->siglock);
        }
 }
 
-
 int send_sig(unsigned long sig,struct task_struct * p,int priv)
 {
        if (!p || sig > 32)
@@ -84,24 +96,23 @@ int send_sig(unsigned long sig,struct task_struct * p,int priv)
            (current->uid ^ p->suid) && (current->uid ^ p->uid) &&
            !suser())
                return -EPERM;
-       if (!sig)
-               return 0;
-       /*
-        * Forget it if the process is already zombie'd.
-        */
-       if (!p->sig)
-               return 0;
-       if ((sig == SIGKILL) || (sig == SIGCONT)) {
-               if (p->state == TASK_STOPPED)
-                       wake_up_process(p);
-               p->exit_code = 0;
-               p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
-                               (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
+
+       if (sig && p->sig) {
+               spin_lock_irq(&p->sigmask_lock);
+               if ((sig == SIGKILL) || (sig == SIGCONT)) {
+                       if (p->state == TASK_STOPPED)
+                               wake_up_process(p);
+                       p->exit_code = 0;
+                       p->signal &= ~( (1<<(SIGSTOP-1)) | (1<<(SIGTSTP-1)) |
+                                       (1<<(SIGTTIN-1)) | (1<<(SIGTTOU-1)) );
+               }
+               if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
+                       p->signal &= ~(1<<(SIGCONT-1));
+               spin_unlock_irq(&p->sigmask_lock);
+
+               /* Actually generate the signal */
+               generate(sig,p);
        }
-       if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
-               p->signal &= ~(1<<(SIGCONT-1));
-       /* Actually generate the signal */
-       generate(sig,p);
        return 0;
 }
 
@@ -245,14 +256,18 @@ int session_of_pgrp(int pgrp)
        int fallback;
 
        fallback = -1;
+       read_lock(&tasklist_lock);
        for_each_task(p) {
                if (p->session <= 0)
                        continue;
-               if (p->pgrp == pgrp)
-                       return p->session;
+               if (p->pgrp == pgrp) {
+                       fallback = p->session;
+                       break;
+               }
                if (p->pid == pgrp)
                        fallback = p->session;
        }
+       read_unlock(&tasklist_lock);
        return fallback;
 }
 
@@ -262,21 +277,29 @@ int session_of_pgrp(int pgrp)
  */
 int kill_pg(int pgrp, int sig, int priv)
 {
-       struct task_struct *p;
-       int err,retval = -ESRCH;
-       int found = 0;
+       int retval;
 
-       if (sig<0 || sig>32 || pgrp<=0)
-               return -EINVAL;
-       for_each_task(p) {
-               if (p->pgrp == pgrp) {
-                       if ((err = send_sig(sig,p,priv)) != 0)
-                               retval = err;
-                       else
-                               found++;
+       retval = -EINVAL;
+       if (sig >= 0 && sig <= 32 && pgrp > 0) {
+               struct task_struct *p;
+               int found = 0;
+
+               retval = -ESRCH;
+               read_lock(&tasklist_lock);
+               for_each_task(p) {
+                       if (p->pgrp == pgrp) {
+                               int err = send_sig(sig,p,priv);
+                               if (err != 0)
+                                       retval = err;
+                               else
+                                       found++;
+                       }
                }
+               read_unlock(&tasklist_lock);
+               if (found)
+                       retval = 0;
        }
-       return(found ? 0 : retval);
+       return retval;
 }
 
 /*
@@ -286,34 +309,51 @@ int kill_pg(int pgrp, int sig, int priv)
  */
 int kill_sl(int sess, int sig, int priv)
 {
-       struct task_struct *p;
-       int err,retval = -ESRCH;
-       int found = 0;
+       int retval;
 
-       if (sig<0 || sig>32 || sess<=0)
-               return -EINVAL;
-       for_each_task(p) {
-               if (p->session == sess && p->leader) {
-                       if ((err = send_sig(sig,p,priv)) != 0)
-                               retval = err;
-                       else
-                               found++;
+       retval = -EINVAL;
+       if (sig >= 0 && sig <= 32 && sess > 0) {
+               struct task_struct *p;
+               int found = 0;
+
+               retval = -ESRCH;
+               read_lock(&tasklist_lock);
+               for_each_task(p) {
+                       if (p->leader && p->session == sess) {
+                               int err = send_sig(sig,p,priv);
+
+                               if (err)
+                                       retval = err;
+                               else
+                                       found++;
+                       }
                }
+               read_unlock(&tasklist_lock);
+               if (found)
+                       retval = 0;
        }
-       return(found ? 0 : retval);
+       return retval;
 }
 
 int kill_proc(int pid, int sig, int priv)
 {
-       struct task_struct *p;
+       int retval;
 
-       if (sig<0 || sig>32)
-               return -EINVAL;
-       for_each_task(p) {
-               if (p && p->pid == pid)
-                       return send_sig(sig,p,priv);
+       retval = -EINVAL;
+       if (sig >= 0 && sig <= 32) {
+               struct task_struct *p;
+               
+               retval = -ESRCH;
+               read_lock(&tasklist_lock);
+               for_each_task(p) {
+                       if (p->pid != pid)
+                               continue;
+                       retval = send_sig(sig,p,priv);
+                       break;
+               }
+               read_unlock(&tasklist_lock);
        }
-       return(-ESRCH);
+       return retval;
 }
 
 /*
@@ -322,34 +362,30 @@ int kill_proc(int pid, int sig, int priv)
  */
 asmlinkage int sys_kill(int pid,int sig)
 {
-       int err, retval = 0, count = 0;
+       if (!pid)
+               return kill_pg(current->pgrp,sig,0);
 
-       lock_kernel();
-       if (!pid) {
-               err = kill_pg(current->pgrp,sig,0);
-               goto out;
-       }
        if (pid == -1) {
+               int retval = 0, count = 0;
                struct task_struct * p;
+
+               read_lock(&tasklist_lock);
                for_each_task(p) {
                        if (p->pid > 1 && p != current) {
+                               int err;
                                ++count;
                                if ((err = send_sig(sig,p,0)) != -EPERM)
                                        retval = err;
                        }
                }
-               err = count ? retval : -ESRCH;
-               goto out;
-       }
-       if (pid < 0) {
-               err = kill_pg(-pid,sig,0);
-               goto out;
+               read_unlock(&tasklist_lock);
+               return count ? retval : -ESRCH;
        }
+       if (pid < 0)
+               return kill_pg(-pid,sig,0);
+
        /* Normal kill */
-       err = kill_proc(pid,sig,0);
-out:
-       unlock_kernel();
-       return err;
+       return kill_proc(pid,sig,0);
 }
 
 /*
@@ -364,16 +400,20 @@ static int will_become_orphaned_pgrp(int pgrp, struct task_struct * ignored_task
 {
        struct task_struct *p;
 
+       read_lock(&tasklist_lock);
        for_each_task(p) {
                if ((p == ignored_task) || (p->pgrp != pgrp) ||
                    (p->state == TASK_ZOMBIE) ||
                    (p->p_pptr->pid == 1))
                        continue;
                if ((p->p_pptr->pgrp != pgrp) &&
-                   (p->p_pptr->session == p->session))
-                       return 0;
+                   (p->p_pptr->session == p->session)) {
+                       read_unlock(&tasklist_lock);
+                       return 0;
+               }
        }
-       return(1);      /* (sighing) "Often!" */
+       read_unlock(&tasklist_lock);
+       return 1;       /* (sighing) "Often!" */
 }
 
 int is_orphaned_pgrp(int pgrp)
@@ -383,21 +423,27 @@ int is_orphaned_pgrp(int pgrp)
 
 static inline int has_stopped_jobs(int pgrp)
 {
+       int retval = 0;
        struct task_struct * p;
 
+       read_lock(&tasklist_lock);
        for_each_task(p) {
                if (p->pgrp != pgrp)
                        continue;
-               if (p->state == TASK_STOPPED)
-                       return(1);
+               if (p->state != TASK_STOPPED)
+                       continue;
+               retval = 1;
+               break;
        }
-       return(0);
+       read_unlock(&tasklist_lock);
+       return retval;
 }
 
 static inline void forget_original_parent(struct task_struct * father)
 {
        struct task_struct * p;
 
+       read_lock(&tasklist_lock);
        for_each_task(p) {
                if (p->p_opptr == father)
                        if (task[smp_num_cpus]) /* init */
@@ -405,6 +451,7 @@ static inline void forget_original_parent(struct task_struct * father)
                        else
                                p->p_opptr = task[0];
        }
+       read_unlock(&tasklist_lock);
 }
 
 static inline void close_files(struct files_struct * files)
@@ -470,9 +517,8 @@ static inline void __exit_sighand(struct task_struct *tsk)
 
        if (sig) {
                tsk->sig = NULL;
-               if (!--sig->count) {
+               if (atomic_dec_and_test(&sig->count))
                        kfree(sig);
-               }
        }
 }
 
@@ -635,24 +681,22 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
        struct wait_queue wait = { current, NULL };
        struct task_struct *p;
 
-       lock_kernel();
        if (stat_addr) {
-               retval = verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr));
-               if (retval)
-                       goto out;
+               if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)))
+                       return -EFAULT;
        }
        if (ru) {
-               retval = verify_area(VERIFY_WRITE, ru, sizeof(*ru));
-               if (retval)
-                       goto out;
+               if(verify_area(VERIFY_WRITE, ru, sizeof(*ru)))
+                       return -EFAULT;
        }
-       retval = -EINVAL;
+
        if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
-           goto out;
+               return -EINVAL;
 
+       lock_kernel();
        add_wait_queue(&current->wait_chldexit,&wait);
 repeat:
-       flag=0;
+       flag = retval = 0;
        for (p = current->p_cptr ; p ; p = p->p_osptr) {
                if (pid>0) {
                        if (p->pid != pid)
@@ -719,7 +763,6 @@ repeat:
        retval = -ECHILD;
 end_wait4:
        remove_wait_queue(&current->wait_chldexit,&wait);
-out:
        unlock_kernel();
        return retval;
 }
@@ -732,12 +775,7 @@ out:
  */
 asmlinkage int sys_waitpid(pid_t pid,unsigned int * stat_addr, int options)
 {
-       int ret;
-
-       lock_kernel();
-       ret = sys_wait4(pid, stat_addr, options, NULL);
-       unlock_kernel();
-       return ret;
+       return sys_wait4(pid, stat_addr, options, NULL);
 }
 
 #endif
index c1c944b23a804cb736a0c4157c468da7e5168336..7136a4eb9456f361b793d6e7fe8be28b6319286c 100644 (file)
@@ -203,13 +203,14 @@ static inline int copy_files(unsigned long clone_flags, struct task_struct * tsk
 static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
 {
        if (clone_flags & CLONE_SIGHAND) {
-               current->sig->count++;
+               atomic_inc(&current->sig->count);
                return 0;
        }
        tsk->sig = kmalloc(sizeof(*tsk->sig), GFP_KERNEL);
        if (!tsk->sig)
                return -1;
-       tsk->sig->count = 1;
+       spin_lock_init(&tsk->sig->siglock);
+       atomic_set(&tsk->sig->count, 1);
        memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action));
        return 0;
 }
index fb422f63852a35dc16dfc58244fe1754ff832b89..3bade85fb4d18594394f5cacc1b9edc0aff1bc9c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/ptrace.h>
 #include <linux/sys.h>
@@ -130,6 +131,10 @@ EXPORT_SYMBOL(max_mapnr);
 EXPORT_SYMBOL(num_physpages);
 EXPORT_SYMBOL(high_memory);
 EXPORT_SYMBOL(update_vm_cache);
+EXPORT_SYMBOL(kmem_cache_create);
+EXPORT_SYMBOL(kmem_cache_destroy);
+EXPORT_SYMBOL(kmem_cache_alloc);
+EXPORT_SYMBOL(kmem_cache_free);
 
 /* filesystem internal functions */
 EXPORT_SYMBOL(getname);
@@ -258,7 +263,10 @@ EXPORT_SYMBOL(tq_immediate);
 EXPORT_SYMBOL(tq_scheduler);
 EXPORT_SYMBOL(timer_active);
 EXPORT_SYMBOL(timer_table);
+
 #ifdef __SMP__
+/* Various random spinlocks we want to export */
+EXPORT_SYMBOL(tqueue_lock);
 EXPORT_SYMBOL(waitqueue_lock);
 #endif
 
index b07bf7522c8dfc350a7bafb95428babc81be8c48..fcf52c63779d5e5e368840e56b239265683b25a6 100644 (file)
@@ -126,22 +126,6 @@ static inline void add_to_runqueue(struct task_struct * p)
        (p->prev_run = init_task.prev_run)->next_run = p;
        p->next_run = &init_task;
        init_task.prev_run = p;
-#if 0 /* def __SMP__ */
-       /* this is safe only if called with cli()*/
-       inc_smp_counter(&smp_process_available);
-       if ((0!=p->pid) && smp_threads_ready)
-       {
-               int i;
-               for (i=0;i<smp_num_cpus;i++)
-               {
-                       if (0==current_set[cpu_logical_map[i]]->pid) 
-                       {
-                               smp_message_pass(cpu_logical_map[i], MSG_RESCHEDULE, 0L, 0);
-                               break;
-                       }
-               }
-       }
-#endif
 }
 
 static inline void del_from_runqueue(struct task_struct * p)
@@ -187,9 +171,7 @@ static inline void move_last_runqueue(struct task_struct * p)
 }
 
 /*
- * The tasklist_lock protects the linked list of processes
- * and doesn't need to be interrupt-safe as interrupts never
- * use the task-list.
+ * The tasklist_lock protects the linked list of processes.
  *
  * The scheduler lock is protecting against multiple entry
  * into the scheduling code, and doesn't need to worry
@@ -199,7 +181,7 @@ static inline void move_last_runqueue(struct task_struct * p)
  * The run-queue lock locks the parts that actually access
  * and change the run-queues, and have to be interrupt-safe.
  */
-spinlock_t tasklist_lock = SPIN_LOCK_UNLOCKED;
+rwlock_t tasklist_lock = RW_LOCK_UNLOCKED;
 spinlock_t scheduler_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t runqueue_lock = SPIN_LOCK_UNLOCKED;
 
@@ -391,10 +373,10 @@ asmlinkage void schedule(void)
                        /* Do we need to re-calculate counters? */
                        if (!c) {
                                struct task_struct *p;
-                               spin_lock(&tasklist_lock);
+                               read_lock(&tasklist_lock);
                                for_each_task(p)
                                        p->counter = (p->counter >> 1) + p->priority;
-                               spin_unlock(&tasklist_lock);
+                               read_unlock(&tasklist_lock);
                        }
                }
        }
@@ -421,7 +403,7 @@ asmlinkage void schedule(void)
        }
        spin_unlock(&scheduler_lock);
 
-       reaquire_kernel_lock(prev, smp_processor_id(), lock_depth);
+       reacquire_kernel_lock(prev, smp_processor_id(), lock_depth);
 }
 
 #ifndef __alpha__
index 9a8915391559f0cc86f203fef76abfc41036ea67..e657381cff4b03c0696a31a0436cb0f48e44a6fd 100644 (file)
@@ -31,6 +31,9 @@
  * We don't need to get the kernel lock - this is all local to this
  * particular thread.. (and that's good, because this is _heavily_
  * used by various programs)
+ *
+ * No SMP locking would prevent the inherent races present in this
+ * routine, thus we do not perform any locking at all.
  */
 asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
 {
@@ -38,9 +41,10 @@ asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
 
        if (set) {
                sigset_t new_set;
-               int error = get_user(new_set, set);
-               if (error)
-                       return error;
+
+               if(get_user(new_set, set))
+                       return -EFAULT;
+
                new_set &= _BLOCKABLE;
                switch (how) {
                default:
@@ -57,9 +61,8 @@ asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
                current->blocked = new_set;
        }
        if (oset) {
-               int error = put_user(old_set, oset);
-               if (error)
-                       return error;
+               if(put_user(old_set, oset))
+                       return -EFAULT;
        }
        return 0;
 }
@@ -69,21 +72,19 @@ asmlinkage int sys_sigprocmask(int how, sigset_t *set, sigset_t *oset)
  */
 asmlinkage int sys_sgetmask(void)
 {
-       int ret;
-
        /* SMP safe */
-       ret = current->blocked;
-       return ret;
+       return current->blocked;
 }
 
 asmlinkage int sys_ssetmask(int newmask)
 {
        int old;
 
-       lock_kernel();
+       spin_lock_irq(&current->sigmask_lock);
        old = current->blocked;
        current->blocked = newmask & _BLOCKABLE;
-       unlock_kernel();
+       spin_unlock_irq(&current->sigmask_lock);
+
        return old;
 }
 
@@ -114,22 +115,24 @@ asmlinkage int sys_sigpending(sigset_t *set)
  * Note the silly behaviour of SIGCHLD: SIG_IGN means that the signal
  * isn't actually ignored, but does automatic child reaping, while
  * SIG_DFL is explicitly said by POSIX to force the signal to be ignored..
+ *
+ * All callers of check_pending must be holding current->sig->siglock.
  */
 inline void check_pending(int signum)
 {
        struct sigaction *p;
 
        p = signum - 1 + current->sig->action;
+       spin_lock(&current->sigmask_lock);
        if (p->sa_handler == SIG_IGN) {
                current->signal &= ~_S(signum);
-               return;
-       }
-       if (p->sa_handler == SIG_DFL) {
-               if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH)
-                       return;
-               current->signal &= ~_S(signum);
-               return;
+       } else if (p->sa_handler == SIG_DFL) {
+               if (signum == SIGCONT ||
+                   signum == SIGCHLD ||
+                   signum != SIGWINCH)
+                       current->signal &= ~_S(signum);
        }       
+       spin_unlock(&current->sigmask_lock);
 }
 
 #ifndef __alpha__
@@ -138,30 +141,28 @@ inline void check_pending(int signum)
  */
 asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
 {
-       unsigned long err;
        struct sigaction tmp;
 
-       lock_kernel();
-       err = -EINVAL;
        if (signum<1 || signum>32)
-               goto out;
+               return -EINVAL;
        if (signum==SIGKILL || signum==SIGSTOP)
-               goto out;
+               return -EINVAL;
        if (handler != SIG_DFL && handler != SIG_IGN) {
-               err = verify_area(VERIFY_READ, handler, 1);
-               if (err)
-                       goto out;
+               if(verify_area(VERIFY_READ, handler, 1))
+                       return -EFAULT;
        }
+
        memset(&tmp, 0, sizeof(tmp));
        tmp.sa_handler = handler;
        tmp.sa_flags = SA_ONESHOT | SA_NOMASK;
+
+       spin_lock_irq(&current->sig->siglock);
        handler = current->sig->action[signum-1].sa_handler;
        current->sig->action[signum-1] = tmp;
        check_pending(signum);
-       err = (unsigned long) handler;
-out:
-       unlock_kernel();
-       return err;
+       spin_unlock_irq(&current->sig->siglock);
+
+       return (unsigned long) handler;
 }
 #endif
 
@@ -171,22 +172,33 @@ asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
 {
        struct sigaction new_sa, *p;
 
-       if (signum<1 || signum>32)
+       if (signum < 1 || signum > 32)
                return -EINVAL;
+
        p = signum - 1 + current->sig->action;
+
        if (action) {
                if (copy_from_user(&new_sa, action, sizeof(struct sigaction)))
                        return -EFAULT;
                if (signum==SIGKILL || signum==SIGSTOP)
                        return -EINVAL;
        }
+
        if (oldaction) {
+               /* In the clone() case we could copy half consistant
+                * state to the user, however this could sleep and
+                * deadlock us if we held the signal lock on SMP.  So for
+                * now I take the easy way out and do no locking.
+                */
                if (copy_to_user(oldaction, p, sizeof(struct sigaction)))
                        return -EFAULT;
        }
+
        if (action) {
+               spin_lock_irq(&current->sig->siglock);
                *p = new_sa;
                check_pending(signum);
+               spin_unlock_irq(&current->sig->siglock);
        }
        return 0;
 }
index 7bf33d64ef391b724b8d08144cbf6ab8fe9c333b..2d55d19d9dd1b290271189360d4f0b4b62300977 100644 (file)
@@ -810,8 +810,7 @@ asmlinkage int sys_getsid(pid_t pid)
        if (!pid) {
                ret = current->session;
        } else {
-               /* Walking the process table needs locks */
-               lock_kernel();
+               read_lock(&tasklist_lock);
                for_each_task(p) {
                        if (p->pid == pid) {
                                ret = p->session;
@@ -820,7 +819,7 @@ asmlinkage int sys_getsid(pid_t pid)
                }
                ret = -ESRCH;
 out:
-               unlock_kernel();
+               read_unlock(&tasklist_lock);
        }
        return ret;
 }
@@ -830,7 +829,7 @@ asmlinkage int sys_setsid(void)
        struct task_struct * p;
        int err = -EPERM;
 
-       lock_kernel();
+       read_lock(&tasklist_lock);
        for_each_task(p) {
                if (p->pgrp == current->pid)
                        goto out;
@@ -842,7 +841,7 @@ asmlinkage int sys_setsid(void)
        current->tty_old_pgrp = 0;
        err = current->pgrp;
 out:
-       unlock_kernel();
+       read_unlock(&tasklist_lock);
        return err;
 }
 
index d3dcf7f79ea999901f8cc6414c01a9b2f0a06330..645cf09c19b367569eb0de879ec671011a6a37e6 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -44,7 +44,7 @@ int free_pages_high = 40;
 
 /* We track the number of pages currently being asynchronously swapped
    out, so that we don't try to swap TOO many pages out at once */
-atomic_t nr_async_pages = ATOMIC_INIT;
+atomic_t nr_async_pages = ATOMIC_INIT(0);
 
 /*
  * Constants for the page aging mechanism: the maximum age (actually,
index 22d0aec008772dd89410bd38eb12e642f8d7cfb9..c6d84a0af4dcc4a6b55a501d5732052812043202 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/stat.h>
 #include <net/br.h>
 #include <linux/net_alias.h>
+#include <linux/init.h>
 #ifdef CONFIG_KERNELD
 #include <linux/kerneld.h>
 #endif
@@ -122,7 +123,7 @@ struct packet_type *ptype_all = NULL;               /* Taps */
  *     Device list lock
  */
  
-atomic_t dev_lockct = ATOMIC_INIT;
+atomic_t dev_lockct = ATOMIC_INIT(0);
  
 /*
  *     Our notifier list
@@ -1578,7 +1579,7 @@ static struct proc_dir_entry proc_net_wireless = {
 #endif /* CONFIG_PROC_FS */
 #endif /* CONFIG_NET_RADIO */
 
-int net_dev_init(void)
+__initfunc(int net_dev_init(void))
 {
        struct device *dev, **dp;
 
index b34893cc2365875b5d0e4b5a26b652b71a61ba0f..8ebdb0bb5429e0b981dee24e3f4c8e13756c485e 100644 (file)
@@ -20,7 +20,7 @@
 #include <net/dst.h>
 
 struct dst_entry * dst_garbage_list;
-atomic_t       dst_total = ATOMIC_INIT;
+atomic_t       dst_total = ATOMIC_INIT(0);
 
 static unsigned long dst_gc_timer_expires;
 static unsigned long dst_gc_timer_inc = DST_GC_MAX;
index cba062cf766de67decba92f94104a8d0a7141b69..936e03c03fcc6b103d538cd0eba6ed455d8ed671 100644 (file)
@@ -60,9 +60,9 @@
  *     Resource tracking variables
  */
 
-static atomic_t net_skbcount = ATOMIC_INIT;
-static atomic_t net_allocs = ATOMIC_INIT;
-static atomic_t net_fails  = ATOMIC_INIT;
+static atomic_t net_skbcount = ATOMIC_INIT(0);
+static atomic_t net_allocs = ATOMIC_INIT(0);
+static atomic_t net_fails  = ATOMIC_INIT(0);
 
 extern atomic_t ip_frag_mem;
 
index fa9d63534ac3dce2b1b781af3d24e4fec47509c7..b512cd459e39dcc091bb99028535c67f2756e3d9 100644 (file)
@@ -189,7 +189,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                         *      is best
                         */
                         
-                       if(val > SK_WMEM_MAX*2 || val < 2048)
+                       if(val > SK_WMEM_MAX*2)
                                return -EINVAL;
                        /*
                         *      Once this is all 32bit values we can
@@ -197,7 +197,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                         */
                        if(val > 65535)
                                return -EINVAL;
-                       sk->sndbuf = val;
+                       sk->sndbuf = max(val,2048);
                        /*
                         *      Wake up sending tasks if we
                         *      upped the value.
@@ -206,12 +206,12 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                        break;
 
                case SO_RCVBUF:
-                       if(val > SK_RMEM_MAX*2 || val < 256)
+                       if(val > SK_RMEM_MAX*2)
                                return -EINVAL;
                        /* Can go soon: FIXME */
                        if(val > 65535)
                                return -EINVAL;
-                       sk->rcvbuf = val;
+                       sk->rcvbuf = max(val,256);
                        break;
 
                case SO_KEEPALIVE:
index 3ff19d484124ac968a756dc8e913ba4209b5a85a..8ef0be2aff97b8d84aceb80944329bdd21bd5bca 100644 (file)
@@ -230,13 +230,6 @@ int sysctl_arp_max_pings = ARP_MAX_PINGS;
 
 int sysctl_arp_dead_res_time = ARP_DEAD_RES_TIME;
 
-/* This should be completely nuked... -DaveM */
-#if RT_CACHE_DEBUG >= 1
-#define ASSERT_BH() if (!in_interrupt()) printk(KERN_CRIT __FUNCTION__ " called from SPL=0\n");
-#else
-#define ASSERT_BH()
-#endif
-
 static void arp_neigh_destroy(struct neighbour *neigh);
 
 /*
@@ -251,8 +244,8 @@ struct neigh_ops arp_neigh_ops = {
 };
 
 
-static atomic_t arp_size = ATOMIC_INIT;
-static atomic_t arp_unres_size = ATOMIC_INIT;
+static atomic_t arp_size = ATOMIC_INIT(0);
+static atomic_t arp_unres_size = ATOMIC_INIT(0);
 
 #ifdef CONFIG_ARPD
 static int arpd_not_running;
@@ -340,12 +333,9 @@ static void arp_purge_send_q(struct arp_table *entry)
 {
        struct sk_buff *skb;
 
-       ASSERT_BH();
-
        /* Release the list of `skb' pointers. */
        while ((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL)
                kfree_skb(skb, FREE_WRITE);
-       return;
 }
 
 static void arp_free(struct arp_table **entryp)
@@ -353,8 +343,6 @@ static void arp_free(struct arp_table **entryp)
        struct arp_table *entry = *entryp;
        *entryp = entry->u.next;
 
-       ASSERT_BH();
-
        if (!(entry->flags&ATF_PUBL)) {
                atomic_dec(&arp_size);
                if (!(entry->flags&ATF_COM))
@@ -373,8 +361,6 @@ static void arp_neigh_destroy(struct neighbour *neigh)
        struct arp_table *entry = (struct arp_table*)neigh;
        struct hh_cache *hh, *next;
 
-       ASSERT_BH();
-
        del_timer(&entry->timer);
        arp_purge_send_q(entry);
 
@@ -877,11 +863,8 @@ static void arp_send_q(struct arp_table *entry)
 {
        struct sk_buff *skb;
 
-       ASSERT_BH();
-
-       while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL) {
+       while((skb = skb_dequeue(&entry->u.neigh.arp_queue)) != NULL)
                dev_queue_xmit(skb);
-       }
 }
 
 
index bfcf06a2023de1893a23b12154a327f70cd8bcac..c2182728c1e3db8aa600d555558f8493c2ee0294 100644 (file)
@@ -117,7 +117,7 @@ static void rtmsg_dev(unsigned long type, struct device *dev, struct nlmsghdr *n
  */
 
 static struct wait_queue *fib_wait;
-static atomic_t fib_users = ATOMIC_INIT;
+static atomic_t fib_users = ATOMIC_INIT(0);
 
 static void fib_lock(void)
 {
index c9864e2374d313b855c9c189d954bbdf9f530af2..33c139663605cb08becc58de91b6e10a24676061 100644 (file)
@@ -46,7 +46,7 @@
 
 static struct ipq *ipqueue = NULL;             /* IP fragment queue    */
 
-atomic_t ip_frag_mem = ATOMIC_INIT;            /* Memory used for fragments */
+atomic_t ip_frag_mem = ATOMIC_INIT(0);         /* Memory used for fragments */
 
 char *in_ntoa(unsigned long in);
 
index d89974ba537e1a9398aeb5db2ca765ee0735cbd1..5ba6467d93a2ab06c002f826c230b0d25792aede 100644 (file)
@@ -111,7 +111,7 @@ struct dst_ops ipv4_dst_ops =
  * Route cache.
  */
 
-static atomic_t                 rt_cache_size = ATOMIC_INIT;
+static atomic_t                 rt_cache_size = ATOMIC_INIT(0);
 static struct rtable   *rt_hash_table[RT_HASH_DIVISOR];
 
 static struct rtable * rt_intern_hash(unsigned hash, struct rtable * rth, u16 protocol);
index 593b4fb43ef900b3c9a08a72d257c8b8945b34f6..8a48dff8da77dc11e85c463e617297d14a3bb827 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp.c,v 1.55 1997/04/13 10:31:45 davem Exp $
+ * Version:    $Id: tcp.c,v 1.56 1997/04/16 09:18:42 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -949,7 +949,7 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, int flags)
                        tmp = MAX_HEADER + sk->prot->max_header + 
                                sizeof(struct sk_buff) + 15;
                        if (copy < min(sk->mss, sk->max_window >> 1) && 
-                           !(flags & MSG_OOB) && atomic_read(&sk->packets_out))
+                           !(flags & MSG_OOB) && sk->packets_out)
                        {
                                tmp += min(sk->mss, sk->max_window);
                        }
index 559863be3a7358a9b921f691226a0e8be5bc680e..9b584326829f49198be57fa1ff6ae844433fa410 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_input.c,v 1.42 1997/04/12 04:32:24 davem Exp $
+ * Version:    $Id: tcp_input.c,v 1.43 1997/04/16 09:18:47 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -332,7 +332,7 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
         *     The packet acked data after high_seq;
         */
 
-       if (ack == tp->snd_una && atomic_read(&sk->packets_out) && (not_dup == 0))
+       if (ack == tp->snd_una && sk->packets_out && (not_dup == 0))
        {
                /*
                 * 1. When the third duplicate ack is received, set ssthresh 
@@ -591,7 +591,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq,
                 * do packet "repackaging" for stacks that don't
                 * like overlapping packets.
                 */
-               atomic_dec(&sk->packets_out);
+               sk->packets_out--;
 
                *seq = skb->seq;
                *seq_rtt = now - skb->when;
@@ -744,7 +744,7 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
 
        if (atomic_read(&sk->retransmits))
        {
-               if (atomic_read(&sk->packets_out) == 0)
+               if (sk->packets_out == 0)
                        atomic_set(&sk->retransmits, 0);
        }
        else
@@ -769,7 +769,7 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th,
                }
        }
 
-       if (atomic_read(&sk->packets_out))
+       if (sk->packets_out)
        {
                if (flag & FLAG_DATA_ACKED)
                {
@@ -1152,7 +1152,7 @@ static void tcp_data_snd_check(struct sock *sk)
        if ((skb = tp->send_head))
        {
                if (!after(skb->end_seq, tp->snd_una + tp->snd_wnd) &&
-                   atomic_read(&sk->packets_out) < tp->snd_cwnd )
+                   sk->packets_out < tp->snd_cwnd )
                {
                        /*
                         *      Add more data to the send queue.
@@ -1165,7 +1165,7 @@ static void tcp_data_snd_check(struct sock *sk)
                        if(!sk->dead)
                                sk->write_space(sk);
                }
-               else if (atomic_read(&sk->packets_out) == 0 && !tp->pending)
+               else if (sk->packets_out == 0 && !tp->pending)
                {
                        /*
                         *      Data to queue but no room.
index aea585df90d9260e2577d56c7ff14204d8356f61..7934dc69dcbed8c4f052a5764d843270200a7fa9 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.30 1997/04/13 10:31:44 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.31 1997/04/16 09:18:50 davem Exp $
  *
  *             IPv4 specific functions
  *
@@ -585,7 +585,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 
        skb_queue_tail(&sk->write_queue, buff);
 
-       atomic_inc(&sk->packets_out);
+       sk->packets_out++;
        buff->when = jiffies;
 
        skb1 = skb_clone(buff, GFP_KERNEL);
@@ -816,7 +816,7 @@ static void tcp_v4_send_synack(struct sock *sk, struct open_request *req)
                return;
        }
 
-       mss = (skb->dst->pmtu - sizeof(struct iphdr) + sizeof(struct tcphdr));
+       mss = (skb->dst->pmtu - sizeof(struct iphdr) - sizeof(struct tcphdr));
        if (sk->user_mss)
                mss = min(mss, sk->user_mss);
        skb->h.th = th = (struct tcphdr *) skb_put(skb, sizeof(struct tcphdr));
@@ -1020,7 +1020,7 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        newtp->snd_nxt = newsk->write_seq;
 
        newsk->urg_data = 0;
-       atomic_set(&newsk->packets_out, 0);
+       newsk->packets_out = 0;
        atomic_set(&newsk->retransmits, 0);
        newsk->linger=0;
        newsk->destroy = 0;
index 5b9cd78d6475025753a65f0b30a492a397b3555e..57dac01cad5be1bb1bcf8d81b4b9e94203c71656 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_output.c,v 1.34 1997/04/12 04:32:33 davem Exp $
+ * Version:    $Id: tcp_output.c,v 1.35 1997/04/16 09:18:53 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -79,12 +79,12 @@ static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb)
                
        len = skb->end_seq - skb->seq;
 
-       if (!sk->nonagle && len < (sk->mss >> 1) && atomic_read(&sk->packets_out))
+       if (!sk->nonagle && len < (sk->mss >> 1) && sk->packets_out)
        {
                nagle_check = 0;
        }
 
-       return (nagle_check && atomic_read(&sk->packets_out) < tp->snd_cwnd &&
+       return (nagle_check && sk->packets_out < tp->snd_cwnd &&
                !after(skb->end_seq, tp->snd_una + tp->snd_wnd) &&
                atomic_read(&sk->retransmits) == 0);
 }
@@ -168,7 +168,7 @@ int tcp_send_skb(struct sock *sk, struct sk_buff *skb)
                skb_set_owner_w(buff, sk);
 
                tp->snd_nxt = skb->end_seq;
-               atomic_inc(&sk->packets_out);
+               sk->packets_out++;
 
                skb->when = jiffies;
 
@@ -189,7 +189,7 @@ queue:
        if (tp->send_head == NULL)
                tp->send_head = skb;
 
-       if (atomic_read(&sk->packets_out) == 0 && !tp->pending)
+       if (sk->packets_out == 0 && !tp->pending)
        {
                tp->pending = TIME_PROBE0;
                tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
@@ -333,7 +333,7 @@ static int tcp_wrxmit_frag(struct sock *sk, struct sk_buff *skb, int size)
        {
                /* !tcp_frament Failed! */
                tp->send_head = skb;
-               atomic_dec(&sk->packets_out);
+               sk->packets_out--;
                return -1;
        }
        else
@@ -441,7 +441,7 @@ void tcp_write_xmit(struct sock *sk)
                update_send_head(sk);
                clear_delayed_acks(sk);
 
-               atomic_inc(&sk->packets_out);
+               sk->packets_out++;
                skb_set_owner_w(buff, sk);
 
                tp->snd_nxt = skb->end_seq;
@@ -610,7 +610,7 @@ static int tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb)
         */
 
        kfree_skb(buff, FREE_WRITE);
-       atomic_dec(&sk->packets_out);
+       sk->packets_out--;
 
        /* 
         *      Header checksum will be set by the retransmit procedure
@@ -672,7 +672,7 @@ void tcp_do_retransmit(struct sock *sk, int all)
                                printk(KERN_DEBUG "tcp_fragment failed\n");
                                return;
                        }
-                       atomic_inc(&sk->packets_out);
+                       sk->packets_out++;
                }
 
                if (!th->syn &&
@@ -833,7 +833,7 @@ void tcp_send_fin(struct sock *sk)
        {
                struct sk_buff *skb1;
 
-               atomic_inc(&sk->packets_out);
+               sk->packets_out++;
                tp->snd_nxt = sk->write_seq;
                buff->when = jiffies;
 
@@ -910,7 +910,7 @@ int tcp_send_synack(struct sock *sk)
        {
                skb_set_owner_w(buff, sk);
 
-               atomic_inc(&sk->packets_out);
+               sk->packets_out++;
                skb->when = jiffies;
 
                tp->af_specific->queue_xmit(buff);
@@ -1107,7 +1107,7 @@ void tcp_write_wakeup(struct sock *sk)
                        return;
                }
                skb_set_owner_w(buff, sk);
-               atomic_inc(&sk->packets_out);
+               sk->packets_out++;
 
                clear_delayed_acks(sk);
 
index 65f02d04b7a4acd46de6c8ad488719f3d7c9b5f5..76f821d1dd7b466a25997dd50298d68b5b8e4617 100644 (file)
@@ -34,8 +34,8 @@ struct timer_list     tcp_slow_timer = {
 
 
 struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = {
-       {ATOMIC_INIT, TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK       */
-       {ATOMIC_INIT, TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive}   /* KEEPALIVE    */
+       {ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK    */
+       {ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive}   /* KEEPALIVE */
 };
 
 /*
index bd06ed0158c6333e462b7743379cc6c330da9b7e..9173a77600df2b1d716f7f28b4852b755a58270e 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: addrconf.c,v 1.16 1997/04/12 04:32:44 davem Exp $
+ *     $Id: addrconf.c,v 1.18 1997/04/16 05:58:03 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -69,7 +69,7 @@ struct ifmcaddr6              *inet6_mcast_lst[IN6_ADDR_HSIZE];
  */
 struct inet6_dev               *inet6_dev_lst[IN6_ADDR_HSIZE];
 
-static atomic_t                        addr_list_lock = ATOMIC_INIT;
+static atomic_t                        addr_list_lock = ATOMIC_INIT(0);
 
 void addrconf_verify(unsigned long);
 
index c492ccc7a165575bbe0850a8755863f98cc94c87..95b320f0fdc94c0731093b3daf1a3e924b2cd9b4 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Based on linux/net/ipv4/ip_sockglue.c
  *
- *     $Id: ipv6_sockglue.c,v 1.9 1997/04/07 06:55:51 davem Exp $
+ *     $Id: ipv6_sockglue.c,v 1.10 1997/04/15 09:06:33 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
index 7f4362a8bcaf9472b376dbac923fb56ab4800ad7..d04464e2606043409322934483bb2ee474b865b8 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: route.c,v 1.10 1997/04/12 04:32:57 davem Exp $
+ *     $Id: route.c,v 1.11 1997/04/16 05:58:05 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -62,7 +62,7 @@ struct dst_ops ip6_dst_ops = {
 };
 
 struct rt6_info ip6_null_entry = {
-       {{NULL, ATOMIC_INIT, ATOMIC_INIT, NULL,
+       {{NULL, ATOMIC_INIT(0), ATOMIC_INIT(0), NULL,
          0, 0, 0, 0, 0, 0, 0, 0, -ENETUNREACH, NULL, NULL,
          ip6_pkt_discard, ip6_pkt_discard, &ip6_dst_ops}},
        NULL, {{{0}}}, 256, RTF_REJECT|RTF_NONEXTHOP, ~0UL,
@@ -93,7 +93,7 @@ static struct rt6_info        *rt6_flow_lookup(struct rt6_info *rt,
 #define ip6_rt_policy (0)
 #endif
 
-static atomic_t        rt6_tbl_lock    = ATOMIC_INIT;
+static atomic_t        rt6_tbl_lock    = ATOMIC_INIT(0);
 static int     rt6_bh_mask     = 0;
 
 #define RT_BH_REQUEST          1
index 9d56f6e7f82443b324025002026ceff7b39af083..21a874ee33cc5e6c1e6f90a79226cfd9b63060e7 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: tcp_ipv6.c,v 1.20 1997/04/13 10:31:48 davem Exp $
+ *     $Id: tcp_ipv6.c,v 1.21 1997/04/16 09:19:01 davem Exp $
  *
  *     Based on: 
  *     linux/net/ipv4/tcp.c
@@ -448,7 +448,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        atomic_set(&sk->retransmits, 0);
 
        skb_queue_tail(&sk->write_queue, buff);
-       atomic_inc(&sk->packets_out);
+       sk->packets_out++;
        buff->when = jiffies;
        skb1 = skb_clone(buff, GFP_KERNEL);
        skb_set_owner_w(skb1, sk);
@@ -821,7 +821,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        newtp->snd_nxt = newsk->write_seq;
 
        newsk->urg_data = 0;
-       atomic_set(&newsk->packets_out, 0);
+       newsk->packets_out = 0;
        atomic_set(&newsk->retransmits, 0);
        newsk->linger=0;
        newsk->destroy = 0;
index 77e4ea5e94ce80ec4abedab7532092b91f896494..7c4d4679d9e1d1979a97de973c0bc26bac62cfec 100644 (file)
@@ -936,6 +936,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, int len,
        if (scm->fp)
                unix_attach_fds(scm, skb);
 
+       skb->h.raw = skb->data;
        memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
 
        other = unix_peer(sk);