]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.12 2.1.12
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:41 +0000 (15:12 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:12:41 +0000 (15:12 -0500)
114 files changed:
CREDITS
Documentation/Configure.help
Documentation/java.txt
MAINTAINERS
Makefile
arch/m68k/Makefile
arch/m68k/amiga/amifb.c
arch/m68k/amiga/amiints.c
arch/m68k/amiga/cia.c
arch/m68k/amiga/config.c
arch/m68k/amiga/cyberfb.c
arch/m68k/amiga/ksyms.c
arch/m68k/amiga/zorro.c
arch/m68k/atari/atafb.c
arch/m68k/atari/ataints.c
arch/m68k/atari/config.c
arch/m68k/atari/joystick.c
arch/m68k/atari/ksyms.c
arch/m68k/config.in
arch/m68k/console/fbcon.c
arch/m68k/defconfig
arch/m68k/kernel/console.c
arch/m68k/kernel/entry.S
arch/m68k/kernel/head.S
arch/m68k/kernel/ksyms.c
arch/m68k/kernel/process.c
arch/m68k/kernel/ptrace.c
arch/m68k/kernel/signal.c
arch/m68k/kernel/sys_m68k.c
arch/m68k/kernel/time.c
arch/m68k/kernel/traps.c
arch/m68k/lib/checksum.c
arch/m68k/lib/semaphore.S
arch/m68k/mm/Makefile
arch/m68k/mm/extable.c [new file with mode: 0644]
arch/m68k/mm/fault.c
arch/m68k/mm/init.c
arch/m68k/tools/amiga/Makefile
drivers/block/ide-probe.c
drivers/block/linear.c
drivers/block/linear.h [new file with mode: 0644]
drivers/char/Makefile
drivers/net/tulip.c
drivers/pci/pci.c
drivers/scsi/Config.in
drivers/scsi/eata.c
drivers/scsi/eata.h
drivers/scsi/g_NCR5380.c
drivers/scsi/sr_ioctl.c
drivers/scsi/u14-34f.c
drivers/scsi/u14-34f.h
fs/binfmt_java.c
fs/binfmt_script.c
fs/exec.c
fs/nfs/nfsroot.c
fs/nfs/proc.c
include/asm-i386/uaccess.h
include/asm-m68k/atari_SLM.h [new file with mode: 0644]
include/asm-m68k/byteorder.h
include/asm-m68k/elf.h
include/asm-m68k/io.h
include/asm-m68k/ipc.h [new file with mode: 0644]
include/asm-m68k/mman.h
include/asm-m68k/page.h
include/asm-m68k/pgtable.h
include/asm-m68k/posix_types.h
include/asm-m68k/processor.h
include/asm-m68k/segment.h
include/asm-m68k/semaphore.h
include/asm-m68k/sigcontext.h
include/asm-m68k/stat.h
include/asm-m68k/uaccess.h [new file with mode: 0644]
include/asm-m68k/unistd.h
include/asm-m68k/user.h
include/asm-m68k/zorro.h
include/linux/binfmts.h
include/linux/linear.h [deleted file]
include/linux/mm.h
include/linux/nfs_fs.h
include/linux/pci.h
include/linux/sched.h
include/linux/socket.h
include/linux/sysctl.h
include/linux/ucdrom.h
include/net/sock.h
include/net/transp_v6.h
include/net/x25call.h [new file with mode: 0644]
ipc/shm.c
kernel/module.c
kernel/sys.c
kernel/sysctl.c
mm/mmap.c
mm/mremap.c
net/Config.in
net/ax25/af_ax25.c
net/ax25/ax25_in.c
net/ax25/ax25_out.c
net/ax25/ax25_route.c
net/ax25/ax25_timer.c
net/ipv4/ip_output.c
net/ipv4/tcp_timer.c
net/ipv6/addrconf.c
net/ipv6/ipv6_route.c
net/ipv6/sit.c
net/ipv6/udp.c
net/netrom/af_netrom.c
net/netrom/nr_in.c
net/netrom/nr_out.c
net/netrom/nr_timer.c
net/netsyms.c
net/protocols.c
net/rose/af_rose.c
net/rose/rose_in.c
net/rose/rose_timer.c

diff --git a/CREDITS b/CREDITS
index 44992a6a41a72eadbe53214618be88853f64e074..8ac4663ca483637abad43a9429faf1ad1faf5324 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -68,7 +68,7 @@ D: Wrote SYS V IPC (part of standard kernel since 0.99.10)
 N: Dario Ballabio
 E: dario@milano.europe.dg.com
 D: Author and maintainer of the Ultrastor 14F/34F SCSI driver
-D: Author and maintainer of the EATA ISA/EISA SCSI driver
+D: Author and maintainer of the EATA ISA/EISA/PCI SCSI driver
 S: Data General Corporation
 S: Milano
 S: Italy
index 3833edf3a66cf738e2bc638043e2a2ba83fb1c84..b0cb3b523230ffb2058548e27fa075d6be274a79 100644 (file)
@@ -1395,14 +1395,14 @@ CONFIG_SCSI_EATA_PIO
 
 UltraStor 14F/34F support
 CONFIG_SCSI_U14_34F
-  This is support for the UltraStor 14F, 24F and 34F SCSI-2 host
-  adaptor family. The source at drivers/scsi/u14-34f.c contains some
-  information about this hardware. If the driver doesn't work out of
-  the box, you may have to change some settings in
-  drivers/scsi/u14-34f.h. Read the SCSI-HOWTO, available via ftp
-  (user: anonymous) at sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note
-  that there is also another driver for the same hardware: "UltraStor
-  SCSI support", below. You should only enable one of them. This
+  This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
+  The source at drivers/scsi/u14-34f.c contains some information about 
+  this hardware. If the driver doesn't work out of the box, you may have 
+  to change some settings in drivers/scsi/u14-34f.c.
+  Read the SCSI-HOWTO, available via ftp (user: anonymous) at 
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that there is also another
+  driver for the same hardware: "UltraStor SCSI support", below.
+  You should enable both only if you want 24F support as well. This
   driver is also available as a module ( = code which can be inserted
   in and removed from the running kernel whenever you want). If you
   want to compile it as a module, say M here and read
@@ -1649,9 +1649,8 @@ CONFIG_SCSI_ULTRASTOR
   drivers/scsi/ultrastor.h. If you want to compile this as a module (
   = code which can be inserted in and removed from the running kernel
   whenever you want), say M here and read Documentation/modules.txt.
-  Note that there is also another driver for the same hardware:
-  "UltraStor 14F/34F support", above. You should only enable one of
-  them.
+  Note that there is also another driver for UltraStor hardware:
+  "UltraStor 14F/34F support", above.
  
 7000FASST SCSI support
 CONFIG_SCSI_7000FASST
@@ -1662,12 +1661,16 @@ CONFIG_SCSI_7000FASST
   want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
-EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support
+EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support
 CONFIG_SCSI_EATA
-  This driver supports all the DPT SCSI host adapters, such as
-  PM2011B/9X, PM2021A/9X, PM2012A, PM1012B, PM2022A/9X, PM2122A/9X and
-  PM2322A/9X. Note that the PM2001 is not supported by this
-  driver. You want to read the start of drivers/scsi/eata.c and the
+  This driver supports all the EATA/DMA-compliant SCSI host adapters
+  and does not need any BIOS32 or PCI BIOS service.
+  Only ISA (0x1F0, 0x170, 0x230, 0x330) and EISA (0x1C88 through 0xFC88)
+  addresses are probed. In order to detect a generic EATA PCI board you
+  can force on it any unused EISA address.
+  Note that there is also another driver for the same hardware:
+  "EATA-DMA support". You should enable only one of them.
+  You want to read the start of drivers/scsi/eata.c and the
   SCSI-HOWTO, available via ftp (user: anonymous) at
   sunsite.unc.edu:/pub/Linux/docs/HOWTO.  If you want to compile this
   as a module ( = code which can be inserted in and removed from the
index 624fcc560439a0061da2ef2a77bc116c15012df6..f5205b1a477cbe7bb07aa48da562b30eb6a4f6e6 100644 (file)
@@ -1,4 +1,4 @@
-               Java(tm) Binary Kernel Support for Linux v1.01
+               Java(tm) Binary Kernel Support for Linux v1.02
                ----------------------------------------------
 
 Linux beats them ALL! While all other OS's are TALKING about direct
@@ -13,9 +13,9 @@ small details:
 
                ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/Java-HOWTO
 
-          If you install the JDK in a location other than the suggested
-          directory of /usr/local/java, then you will need to tell the
-          kernel where you put the Java interpreter.  
+          If you install the JDK in a location other than /usr/bin/java,
+          then you will need to tell the kernel where you put the Java
+          interpreter.  
            There are two ways to do this.
            One, edit fs/binfmt_java.c file and make the needed change to 
           the _PATH_JAVA definition at the top of that file.  
@@ -36,6 +36,14 @@ small details:
           as a loadable module. If a module, load it with insmod or
           kerneld.
 
+       5) A caveat.  When executing a java file, the java interpreter is
+          invoked only with the class name, not with the complete file path.
+          Therefore it is possible that the file the shell finds with PATH
+          is not the same file the java interpreter finds with CLASSPATH.
+          The recommended solution is to make symbolic links from a directory
+          in PATH to the actual class file in CLASSPATH, e.g.,
+          /usr/local/bin/myapp -> /usr/local/java/classes/myapp.class.
+
 To test your new setup, enter in the following simple Java app, and name
 it "HelloWorld.java":
 
@@ -79,8 +87,8 @@ demo/Blink/example1.html file), and:
           Java Applet support, so the modified file can still be used
           with all known browsers.
 
-       2) If you install the JDK in a location other than the suggested
-          directory of /usr/local/java, then you will need to tell the
+       2) If you install the applet viewer in a location other than
+          /usr/bin/appletviewer, then you will need to tell the
           kernel where you put the Java appletviewer.  
            There are two ways to do this.
            One, edit fs/binfmt_java.c file and make the needed change to 
index f6af504bd6f6711f3090d95e0db95042a9070938..2dfa21685ef9d3a6a7cfcacc04c804a2a755e61d 100644 (file)
@@ -147,16 +147,16 @@ M:        Marcio Saito <marcio@cyclades.com>
 W:     http://www.cyclades.com/
 S:     Supported
 
-EATA ISA/EISA SCSI DRIVER
+EATA ISA/EISA/PCI SCSI DRIVER
 P:     Dario Ballabio
 M:     dario@milano.europe.dg.com
-L:     linux-kernel@vger.rutgers.edu
+L:     linux-scsi@vger.rutgers.edu
 S:     Maintained
 
 U14-34F SCSI DRIVER
 P:     Dario Ballabio
 M:     dario@milano.europe.dg.com
-L:     linux-kernel@vger.rutgers.edu
+L:     linux-scsi@vger.rutgers.edu
 S:     Maintained
 
 EATA-DMA SCSI DRIVER
index cdf0fd8d71675234eb23a7058609cfd2f317b0f0..dd25f9b2ddb07eb4fa936143f66fba41451ed6bf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 11
+SUBLEVEL = 12
 
 ARCH = i386
 
index 296437c5ec407cd96616289fd7534463ceada607..c1dd3072c214398f0660ac9bfc6ccf698f6fbb5a 100644 (file)
 # Copyright (C) 1994 by Hamish Macdonald
 #
 
+# test for cross compiling
+COMPILE_ARCH = $(shell uname -m)
+
 # override top level makefile
+AS += -m68020
 ifdef CONFIG_KERNEL_ELF
-AS     = as -m68020
-LD     = ld -m m68kelf
-CC     := $(CC)
-# set up for cross compiling
-COMPILE_ARCH = $(shell uname -m)
+LD += -m m68kelf
 ifneq ($(COMPILE_ARCH),$(ARCH))
-       CROSSDIR=/usr/$(ARCH)-linux/bin
-       CC := $(CROSSDIR)/$(CC)
-       AS := $(CROSSDIR)/$(AS)
-       LD := $(CROSSDIR)/$(LD)
-       AR := $(CROSSDIR)/$(AR)
-       NM := $(CROSSDIR)/$(NM)
-       STRIP := $(CROSSDIR)/$(STRIP)
+       # prefix for cross-compiling binaries
+       CROSS_COMPILE = m68k-linux-
 endif
 else
-AS     = /usr/m68k-linuxaout/bin/as -m68020 
-CC     := $(CC) -pipe -b m68k-linuxaout
-LD     = ld -m m68klinux
+LD += -m m68klinux
+ifneq ($(COMPILE_ARCH),$(ARCH))
+       # prefix for cross-compiling binaries
+       CROSS_COMPILE = m68k-linuxaout-
+endif
 endif
 
 #
@@ -57,6 +54,10 @@ ifdef CONFIG_OPTIMIZE_040
 CFLAGS := $(CFLAGS) -m68040
 endif
 
+ifdef CONFIG_OPTIMIZE_060
+CFLAGS := $(CFLAGS) -m68020-40 -Wa,-m68060
+endif
+
 HEAD := arch/m68k/kernel/head.o
 
 SUBDIRS += arch/m68k/kernel arch/m68k/mm arch/m68k/console arch/m68k/lib
index bd5a79ea04ec379e58e84e86e2bf456ae697c22a..b05e314d2e036fcec4bafc8c5de0527aeef944a4 100644 (file)
@@ -51,7 +51,7 @@
 #include <linux/config.h>
 #include <linux/interrupt.h>
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/amigahw.h>
       - hsstop:   End of horizontal synchronization pulse
       - htotal:   Last value on the line (i.e. line length = htotal+1)
       - vsstrt:   Start of vertical synchronization pulse
-      - vsstop:   Start of vertical synchronization pulse
+      - vsstop:   End of vertical synchronization pulse
       - vtotal:   Last line value (i.e. number of lines = vtotal+1)
       - hcenter:  Start of vertical retrace for interlace
 
       - hbstrt:   Start of horizontal blank
       - hbstop:   End of horizontal blank
       - vbstrt:   Start of vertical blank
-      - vbstop:   Start of vertical blank
+      - vbstop:   End of vertical blank
 
    Horizontal values are in color clock cycles (280 ns), vertical values are in
    scanlines.
@@ -1679,7 +1679,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
                        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrfix));
                        if (!i) {
                                i = amiga_fb_get_fix_cursorinfo(&crsrfix, con);
-                               memcpy_tofs((void *)arg, &crsrfix, sizeof(crsrfix));
+                               copy_to_user((void *)arg, &crsrfix, sizeof(crsrfix));
                        }
                        return i;
                }
@@ -1690,7 +1690,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
                        if (!i) {
                                i = amiga_fb_get_var_cursorinfo(&crsrvar,
                                        ((struct fb_var_cursorinfo *)arg)->data, con);
-                               memcpy_tofs((void *)arg, &crsrvar, sizeof(crsrvar));
+                               copy_to_user((void *)arg, &crsrvar, sizeof(crsrvar));
                        }
                        return i;
                }
@@ -1699,7 +1699,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
 
                        i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrvar));
                        if (!i) {
-                               memcpy_fromfs(&crsrvar, (void *)arg, sizeof(crsrvar));
+                               copy_from_user(&crsrvar, (void *)arg, sizeof(crsrvar));
                                i = amiga_fb_set_var_cursorinfo(&crsrvar,
                                        ((struct fb_var_cursorinfo *)arg)->data, con);
                        }
@@ -1711,7 +1711,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
                        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(crsrstate));
                        if (!i) {
                                i = amiga_fb_get_cursorstate(&crsrstate, con);
-                               memcpy_tofs((void *)arg, &crsrstate, sizeof(crsrstate));
+                               copy_to_user((void *)arg, &crsrstate, sizeof(crsrstate));
                        }
                        return i;
                }
@@ -1720,7 +1720,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
 
                        i = verify_area(VERIFY_READ, (void *)arg, sizeof(crsrstate));
                        if (!i) {
-                               memcpy_fromfs(&crsrstate, (void *)arg, sizeof(crsrstate));
+                               copy_from_user(&crsrstate, (void *)arg, sizeof(crsrstate));
                                i = amiga_fb_set_cursorstate(&crsrstate, con);
                        }
                        return i;
@@ -1732,7 +1732,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
                        i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct amiga_fb_par));
                        if (!i) {
                                ami_get_par(&par);
-                               memcpy_tofs((void *)arg, &par, sizeof(struct amiga_fb_par));
+                               copy_to_user((void *)arg, &par, sizeof(struct amiga_fb_par));
                        }
                        return i;
                }
@@ -1741,7 +1741,7 @@ static int amiga_fb_ioctl(struct inode *inode, struct file *file,
 
                        i = verify_area(VERIFY_READ, (void *)arg, sizeof(struct amiga_fb_par));
                        if (!i) {
-                               memcpy_fromfs(&par, (void *)arg, sizeof(struct amiga_fb_par));
+                               copy_from_user(&par, (void *)arg, sizeof(struct amiga_fb_par));
                                ami_set_par(&par);
                        }
                        return i;
@@ -2044,11 +2044,11 @@ static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
                        if (transp)
                                *transp = htransp;
                } else {
-                       put_fs_word(hred, red);
-                       put_fs_word(hgreen, green);
-                       put_fs_word(hblue, blue);
+                       put_user(hred, red);
+                       put_user(hgreen, green);
+                       put_user(hblue, blue);
                        if (transp)
-                               put_fs_word(htransp, transp);
+                               put_user(htransp, transp);
                }
                red++;
                green++;
@@ -2081,10 +2081,13 @@ static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
                        hblue = *blue;
                        htransp = transp ? *transp : 0;
                } else {
-                       hred = get_fs_word(red);
-                       hgreen = get_fs_word(green);
-                       hblue = get_fs_word(blue);
-                       htransp = transp ? get_fs_word(transp) : 0;
+                       get_user(hred, red);
+                       get_user(hgreen, green);
+                       get_user(hblue, blue);
+                       if (transp)
+                               get_user(htransp, transp);
+                       else
+                               htransp = 0;
                }
                hred = CNVT_TOHW(hred, var->red.length);
                hgreen = CNVT_TOHW(hgreen, var->green.length);
@@ -2119,10 +2122,10 @@ static void memcpy_fs(int fsfromto, void *to, void *from, int len)
                        memcpy(to, from, len);
                        return;
                case 1:
-                       memcpy_fromfs(to, from, len);
+                       copy_from_user(to, from, len);
                        return;
                case 2:
-                       memcpy_tofs(to, from, len);
+                       copy_to_user(to, from, len);
                        return;
        }
 }
@@ -2256,7 +2259,7 @@ static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
 }
 
        /*
-        * Get a Video Modes
+        * Get a Video Mode
         */
 
 static void get_video_mode(const char *name)
@@ -3212,7 +3215,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, i
                                "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
                                "swap %1 ; lslw #1,%1 ; roxlb #1,%0"
                                : "=d" (color), "=d" (datawords) : "1" (datawords));
-                       put_fs_byte(color, data++);
+                       put_user(color, data++);
                }
                if (bits > 0) {
                        --words; ++lspr;
@@ -3269,10 +3272,14 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data, i
        for (height = (short)var->height-1; height >= 0; height--) {
                bits = 16; words = delta; datawords = 0;
                for (width = (short)var->width-1; width >= 0; width--) {
+                       unsigned long tdata = 0;
+                       get_user(tdata, (char *)data);
+                       data++;
                        asm volatile (
                                "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
                                "lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
-                               : "=d" (datawords) : "0" (datawords), "d" ((u_long)(get_fs_byte(data++))));
+                               : "=d" (datawords)
+                               : "0" (datawords), "d" (tdata));
                        if (--bits == 0) {
                                bits = 16; --words;
                                asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
index 857b0b99a7c34457875ee5b2ade265c02a2cc037..5fe90949e4abc47b40b34dfde8835cb5380c667c 100644 (file)
@@ -209,7 +209,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)
+       if (irq < IRQ_IDX(IRQ_AMIGA_PORTS) && !ami_ablecount[irq])
                custom.intena = IF_SETCLR | ami_intena_vals[irq];
 
        return 0;
@@ -264,7 +264,7 @@ void amiga_enable_irq(unsigned int irq)
                return;
        }
 
-       if (ami_ablecount[irq]++)
+       if (--ami_ablecount[irq])
                return;
 
        if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
@@ -290,7 +290,7 @@ void amiga_disable_irq(unsigned int irq)
                return;
        }
 
-       if (--ami_ablecount[irq])
+       if (ami_ablecount[irq]++)
                return;
 
        if (irq >= IRQ_IDX(IRQ_AMIGA_CIAB)) {
index 6c9a01c0ce1cd7ade5efc8a87b1bbc9956a24b33..7bf579f39cb4948ca78cddce7ca91b4917f04ce5 100644 (file)
@@ -55,7 +55,7 @@ unsigned char cia_set_irq(struct ciabase *base, unsigned char mask)
                base->icr_data &= ~mask;
        if (base->icr_data & base->icr_mask)
                custom.intreq = IF_SETCLR | base->int_mask;
-       return (old & base->icr_mask);
+       return old & base->icr_mask;
 }
 
 /*
@@ -77,12 +77,14 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask)
                base->icr_mask &= ~mask;
        base->icr_mask &= CIA_ICR_ALL;
        for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
-               if ((tmp & base->icr_mask) && !base->irq_list[i].handler)
+               if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
                        base->icr_mask &= ~tmp;
-       }
+                       base->cia->icr = tmp;
+               }
+       }
        if (base->icr_data & base->icr_mask)
                custom.intreq = IF_SETCLR | base->int_mask;
-       return (old);
+       return old;
 }
 
 int cia_request_irq(struct ciabase *base, unsigned int irq,
index 7026c488a9e84b119b8e5be7d49b495f7905119d..72e885d4d4fdb3eb54a3a04038d4550e326f8951 100644 (file)
@@ -271,23 +271,21 @@ void config_amiga(void)
   mach_gettimeoffset   = amiga_gettimeoffset;
   if (AMIGAHW_PRESENT(A3000_CLK)){
     mach_gettod  = a3000_gettod;
-    mach_max_dma_address = 0xffffffff; /*
-                                       * default MAX_DMA 0xffffffff
-                                       * on Z3 machines - we should
-                                       * consider adding something
-                                       * like a dma_mask in kmalloc
-                                       * later on, so people using Z2
-                                       * boards in Z3 machines won't
-                                       * get into trouble - Jes
-                                       */
   }
   else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
     mach_gettod  = a2000_gettod;
-    mach_max_dma_address = 0x00ffffff; /*
-                                       * default MAX_DMA 0x00ffffff
-                                       * on Z2 machines.
-                                       */
   }
+
+  mach_max_dma_address = 0xffffffff; /*
+                                     * default MAX_DMA=0xffffffff
+                                     * on all machines. If we don't
+                                     * do so, the SCSI code will not
+                                     * be able to allocate any mem
+                                     * for transfers, unless we are
+                                     * dealing with a Z2 mem only
+                                     * system.                  /Jes
+                                     */
+
   mach_hwclk           = amiga_hwclk;
   mach_set_clock_mmss  = amiga_set_clock_mmss;
   mach_mksound         = amiga_mksound;
@@ -421,7 +419,7 @@ void a2000_gettod (int *yearp, int *monp, int *dayp,
        *yearp = tod->year1       * 10 + tod->year2;
 
        if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
-               if ((!tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
+               if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
                        *hourp = 0;
                else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
                        *hourp += 12;
@@ -480,7 +478,7 @@ int amiga_hwclk(int op, struct hwclk_time *t)
                        t->year = tod->year1       * 10 + tod->year2;
 
                        if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
-                               if ((!tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
+                               if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
                                        t->hour = 0;
                                else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
                                        t->hour += 12;
index 0b8a0f8dfafecdc90048cc269416d10a34abf6d5..dc25153718d25017318543a9f9e7aea0d17e6d53 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/tty.h>
 #include <linux/malloc.h>
 #include <linux/delay.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/zorro.h>
@@ -815,11 +815,11 @@ static int do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
          if (transp)
             *transp = htransp;
       } else {
-         put_fs_word(hred, red);
-         put_fs_word(hgreen, green);
-         put_fs_word(hblue, blue);
+         put_user(hred, red);
+         put_user(hgreen, green);
+         put_user(hblue, blue);
          if (transp)
-            put_fs_word(htransp, transp);
+            put_user(htransp, transp);
       }
       red++;
       green++;
@@ -853,10 +853,13 @@ static int do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var,
          hblue = *blue;
          htransp = transp ? *transp : 0;
       } else {
-         hred = get_fs_word(red);
-         hgreen = get_fs_word(green);
-         hblue = get_fs_word(blue);
-         htransp = transp ? get_fs_word(transp) : 0;
+         get_user(hred, red);
+         get_user(hgreen, green);
+         get_user(hblue, blue);
+        if (transp)
+                get_user(htransp, transp);
+        else
+                htransp = 0;
       }
       hred = CNVT_TOHW(hred, var->red.length);
       hgreen = CNVT_TOHW(hgreen, var->green.length);
index 3c32ffacf601bdd5d8d3b1b2c628b72044b3f926..b306867c167b3c87b398132163523949733ed316 100644 (file)
@@ -2,6 +2,10 @@
 #include <asm/zorro.h>
 #include <asm/amigatypes.h>
 #include <asm/amigahw.h>
+#include <asm/amigatypes.h>
+
+extern volatile u_short amiga_audio_min_period;
+extern u_short amiga_audio_period;
 
 static struct symbol_table mach_amiga_symbol_table = {
 #include <linux/symtab_begin.h>
@@ -13,6 +17,8 @@ static struct symbol_table mach_amiga_symbol_table = {
   X(amiga_chip_alloc),
   X(amiga_chip_free),
   X(amiga_chip_avail),
+  X(amiga_audio_period),
+  X(amiga_audio_min_period),
 
   X(zorro_find),
   X(zorro_get_board),
index d27afe4b16c43e5301edaeecf6ba4029835e8019..ccc9c7249f5138eef4b6c698fa5994a9198892e9 100644 (file)
@@ -477,7 +477,7 @@ BEGIN_PROD(PHASE5)
    PROD("Blizzard 1230-III Turbo Board", BLIZZARD_1230_III)
    PROD("Blizzard 1230-IV/1260 Turbo Board", BLIZZARD_1230_IV)
    PROD("Blizzard 2060 SCSI Controller", BLIZZARD_2060SCSI)
-   PROD("CyberStorm", CYBERSTORM)
+   PROD("CyberStorm Mk II", CYBERSTORM_II)
    PROD("CyberVision64 Graphics Board", CYBERVISION)
 END
 
index 8156c61a4e49185a418a0fdc892b2c48c4546d86..488ecc3023f06c0e4801c518af3e1fc561571b91 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/delay.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 
@@ -86,7 +86,7 @@ int        ovsc_switchmode=0;
 
 static struct atari_fb_par {
        unsigned long screen_base;
-       int vyres;
+       int yres_virtual;
        union {
                struct {
                        int mode;
@@ -366,57 +366,60 @@ char **fb_var_names[] = {
 };
 
 struct fb_var_screeninfo atari_fb_predefined[] = {
+       /*
+        * yres_virtual==0 means use hw-scrolling if possible, else yres
+        */
        { /* autodetect */
          0, 0, 0, 0, 0, 0, 0, 0,               /* xres-grayscale */
          {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},   /* red green blue tran*/
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* st low */
-         320, 200, 320, 200, 0, 0, 4, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         320, 200, 320, 0, 0, 0, 4, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* st mid */
-         640, 200, 640, 200, 0, 0, 2, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 200, 640, 0, 0, 0, 2, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* st high */
-         640, 400, 640, 400, 0, 0, 1, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 400, 640, 0, 0, 0, 1, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* tt low */
-         320, 480, 320, 480, 0, 0, 8, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         320, 480, 320, 0, 0, 0, 8, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* tt mid */
-         640, 480, 640, 480, 0, 0, 4, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 480, 640, 0, 0, 0, 4, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* tt high */
-         1280, 960, 1280, 960, 0, 0, 1, 0,             /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         1280, 960, 1280, 0, 0, 0, 1, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* vga2 */
-         640, 480, 640, 480, 0, 0, 1, 0,               /* xres-grayscale */
-         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 480, 640, 0, 0, 0, 1, 0,
+         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* vga4 */
-         640, 480, 640, 480, 0, 0, 2, 0,               /* xres-grayscale */
-         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 480, 640, 0, 0, 0, 2, 0,
+         {0, 4, 0}, {0, 4, 0}, {0, 4, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* vga16 */
-         640, 480, 640, 480, 0, 0, 4, 0,               /* xres-grayscale */
-         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 480, 640, 0, 0, 0, 4, 0,
+         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* vga256 */
-         640, 480, 640, 480, 0, 0, 8, 0,               /* xres-grayscale */
-         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},   /* red green blue tran*/
+         640, 480, 640, 0, 0, 0, 8, 0,
+         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* falh2 */
-         896, 608, 896, 608, 0, 0, 1, 0,               /* xres-grayscale */
-         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},   /* red green blue tran*/
+         896, 608, 896, 0, 0, 0, 1, 0,
+         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        { /* falh16 */
-         896, 608, 896, 608, 0, 0, 4, 0,               /* xres-grayscale */
-         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},   /* red green blue tran*/
+         896, 608, 896, 0, 0, 0, 4, 0,
+         {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
          0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0 },
        /* Minor 14..23 free for more standard video modes */
        { 0, },
@@ -598,7 +601,7 @@ static int tt_decode_var( struct fb_var_screeninfo *var,
                return -EINVAL;
        if (var->yoffset + yres > yres_virtual && yres_virtual)
                return -EINVAL;
-       par->vyres = yres_virtual;
+       par->yres_virtual = yres_virtual;
        par->screen_base = screen_base + var->yoffset * linelen;
        return 0;
 }
@@ -675,10 +678,10 @@ static int tt_encode_var( struct fb_var_screeninfo *var,
        if (! use_hwscroll)
                var->yres_virtual=var->yres;
        else if (screen_len)
-               if (par->vyres)
-                       var->yres_virtual = par->vyres;
+               if (par->yres_virtual)
+                       var->yres_virtual = par->yres_virtual;
                else
-                       /* vyres==0 means use maximum */
+                       /* yres_virtual==0 means use maximum */
                        var->yres_virtual = screen_len / linelen;
        else {
                if (hwscroll < 0)
@@ -811,7 +814,7 @@ fext = {       0,     0, 18, 0, 42, 0x1, 0};
 static int vdl_prescale[4][3] = {{4,2,1}, {4,2,1}, {4,2,2}, {4,2,1}};
 
 /* Default hsync timing [mon_type] in picoseconds */
-static long h_syncs[4] = {3000000, 4700000, 4000000, 4700000};
+static long h_syncs[4] = {3000000, 4875000, 4000000, 4875000};
 
 
 static inline int hxx_prescale(struct falcon_hw *hw)
@@ -929,8 +932,8 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                return -EINVAL;
        par->hw.falcon.bpp = bpp;
 
-       if (mon_type != F_MON_VGA || DontCalcRes) {
-               /* Skip all calculations, VGA multisync only yet */
+       if (mon_type == F_MON_SM || DontCalcRes) {
+               /* Skip all calculations. VGA/TV/SC1224 only supported. */
                struct fb_var_screeninfo *myvar = &atari_fb_predefined[0];
                
                if (bpp > myvar->bits_per_pixel ||
@@ -941,7 +944,7 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                goto set_screen_base;   /* Don't forget this */
        }
 
-       /* Only some fixed resolutions < 640x480 */
+       /* Only some fixed resolutions < 640x400 */
        if (xres <= 320)
                xres = 320;
        else if (xres <= 640 && bpp != 16)
@@ -952,8 +955,6 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                yres = 240;
        else if (yres <= 400)
                yres = 400;
-       else if (yres <= 480)
-               yres = 480;
 
        /* 2 planes must use STE compatibility mode */
        par->hw.falcon.ste_mode = bpp==2;
@@ -962,6 +963,7 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
        /* Total and visible scanline length must be a multiple of one longword,
         * this and the console fontwidth yields the alignment for xres and
         * xres_virtual.
+        * TODO: this way "odd" fontheights are not supported
         *
         * Special case in STE mode: blank and graphic positions don't align,
         * avoid trash at right margin
@@ -997,9 +999,9 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
        par->hw.falcon.line_offset = bpp * (xres_virtual - xres) / 16;
 
        /* single or double pixel width */
-       xstretch = (xres == 320) ? 2 : 1;
+       xstretch = (xres < 640) ? 2 : 1;
 
-#if 0 /* currently unused */
+#if 0 /* SM124 supports only 640x400, this is rejected above */
        if (mon_type == F_MON_SM) {
                if (xres != 640 && yres != 400)
                        return -EINVAL;
@@ -1013,19 +1015,45 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                right_margin = 0;
                /* TODO set all margins */
        }
-       else if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
+       else
+#endif
+       if (mon_type == F_MON_SC || mon_type == F_MON_TV) {
                plen = 2 * xstretch;
+               if (var->pixclock > f32.t * plen)
+                       return -EINVAL;
                pclock = &f32;
-               hsync_len = 150 / plen;
                if (yres > 240)
                        interlace = 1;
-               /* TODO set margins */
+               if (var->pixclock == 0) {
+                       /* set some minimal margins which center the screen */
+                       left_margin = 32;
+                       right_margin = 18;
+                       hsync_len = pclock->hsync / plen;
+                       upper_margin = 31;
+                       lower_margin = 14;
+                       vsync_len = interlace ? 3 : 4;
+               } else {
+                       left_margin = var->left_margin;
+                       right_margin = var->right_margin;
+                       hsync_len = var->hsync_len;
+                       upper_margin = var->upper_margin;
+                       lower_margin = var->lower_margin;
+                       vsync_len = var->vsync_len;
+                       if (var->vmode & FB_VMODE_INTERLACED) {
+                               upper_margin = (upper_margin + 1) / 2;
+                               lower_margin = (lower_margin + 1) / 2;
+                               vsync_len = (vsync_len + 1) / 2;
+                       } else if (var->vmode & FB_VMODE_DOUBLE) {
+                               upper_margin *= 2;
+                               lower_margin *= 2;
+                               vsync_len *= 2;
+                       }
+               }
        }
        else
-#endif
        {       /* F_MON_VGA */
                if (bpp == 16)
-                       xstretch = 2; /* hicolor only double pixel width */
+                       xstretch = 2; /* Double pixel width only for hicolor */
                /* Default values are used for vert./hor. timing if no pixelclock given. */
                if (var->pixclock == 0) {
                        int linesize;
@@ -1079,12 +1107,20 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                        upper_margin = var->upper_margin;
                        lower_margin = var->lower_margin;
                        vsync_len = var->vsync_len;
+                       /* Internal unit is [single lines per (half-)frame] */
                        if (var->vmode & FB_VMODE_INTERLACED) {
                                /* # lines in half frame */
+                               /* External unit is [lines per full frame] */
                                upper_margin = (upper_margin + 1) / 2;
                                lower_margin = (lower_margin + 1) / 2;
                                vsync_len = (vsync_len + 1) / 2;
                        }
+                       else if (var->vmode & FB_VMODE_DOUBLE) {
+                               /* External unit is [double lines per frame] */
+                               upper_margin *= 2;
+                               lower_margin *= 2;
+                               vsync_len *= 2;
+                       }
                }
                if (pclock == &fext)
                        longoffset = 1; /* VIDEL doesn't synchronize on short offset */
@@ -1257,6 +1293,15 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                lower_margin += lines;
                goto again;
        }
+       else if (vfreq > vfmax && doubleline) {
+               /* Doubleline too high -> enlarge margins */
+               int lines;
+               for (lines=0; (hfreq*2)/(par->VFT+1+4*lines)>vfmax; lines+=2)
+                       ;
+               upper_margin += lines;
+               lower_margin += lines;
+               goto again;
+       }
        else if (vfreq > vfmax && interlace) {
                /* Interlace, too high -> enlarge margins */
                int lines;
@@ -1277,7 +1322,7 @@ static int falcon_decode_var( struct fb_var_screeninfo *var,
                return -EINVAL;
        if (var->yoffset + yres > yres_virtual && yres_virtual)
                return -EINVAL;
-       par->vyres = yres_virtual;
+       par->yres_virtual = yres_virtual;
        par->screen_base = screen_base + var->yoffset * linelen;
        par->hw.falcon.xoffset = 0;
 
@@ -1372,10 +1417,10 @@ static int falcon_encode_var( struct fb_var_screeninfo *var,
 
        linelen = var->xres_virtual * var->bits_per_pixel / 8;
        if (screen_len)
-               if (par->vyres)
-                       var->yres_virtual = par->vyres;
+               if (par->yres_virtual)
+                       var->yres_virtual = par->yres_virtual;
                else
-                       /* vyres==0 means use maximum */
+                       /* yres_virtual==0 means use maximum */
                        var->yres_virtual = screen_len / linelen;
        else {
                if (hwscroll < 0)
@@ -1422,6 +1467,11 @@ static int falcon_encode_var( struct fb_var_screeninfo *var,
                var->lower_margin *= 2;
                var->vsync_len *= 2;
        }
+       else if (var->vmode & FB_VMODE_DOUBLE) {
+               var->upper_margin = (var->upper_margin + 1) / 2;
+               var->lower_margin = (var->lower_margin + 1) / 2;
+               var->vsync_len = (var->vsync_len + 1) / 2;
+       }
 
        var->pixclock *= plen;
        var->left_margin /= plen;
@@ -1694,10 +1744,11 @@ static int falcon_detect( void )
                break;
        case F_MON_SC:
        case F_MON_TV:
-               vfmin = 50;
+               /* PAL...NTSC */
+               vfmin = 49; /* not 50, since TOS defaults to 49.9x Hz */
                vfmax = 60;
-               hfmin = 15624;
-               hfmax = 15626;
+               hfmin = 15620;
+               hfmax = 15755;
                break;
        }
        /* initialize hsync-len */
@@ -1805,7 +1856,7 @@ static int stste_decode_var( struct fb_var_screeninfo *var,
                return -EINVAL;
        if (var->yoffset + yres > yres_virtual && yres_virtual)
                return -EINVAL;
-       par->vyres = yres_virtual;
+       par->yres_virtual = yres_virtual;
        par->screen_base=screen_base+ var->yoffset*linelen;
        return 0;
 }
@@ -1863,10 +1914,10 @@ static int stste_encode_var( struct fb_var_screeninfo *var,
        if (! use_hwscroll)
                var->yres_virtual=var->yres;
        else if (screen_len)
-               if (par->vyres)
-                       var->yres_virtual = par->vyres;
+               if (par->yres_virtual)
+                       var->yres_virtual = par->yres_virtual;
                else
-                       /* vyres==0 means use maximum */
+                       /* yres_virtual==0 means use maximum */
                        var->yres_virtual = screen_len / linelen;
        else {
                if (hwscroll < 0)
@@ -2458,10 +2509,10 @@ do_fb_get_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc)
                        if (transp) *transp=htransp;
                }
                else {
-                       put_fs_word(hred, red);
-                       put_fs_word(hgreen, green);
-                       put_fs_word(hblue, blue);
-                       if (transp) put_fs_word(htransp, transp);
+                       put_user(hred, red);
+                       put_user(hgreen, green);
+                       put_user(hblue, blue);
+                       if (transp) put_user(htransp, transp);
                }
                red++;
                green++;
@@ -2494,10 +2545,13 @@ do_fb_set_cmap(struct fb_cmap *cmap, struct fb_var_screeninfo *var, int kspc)
                        htransp=(transp) ? *transp : 0;
                }
                else {
-                       hred=get_fs_word(red);
-                       hgreen=get_fs_word(green);
-                       hblue=get_fs_word(blue);
-                       htransp=(transp)?get_fs_word(transp):0;
+                       get_user(hred, red);
+                       get_user(hgreen, green);
+                       get_user(hblue, blue);
+                       if (transp)
+                               get_user(htransp, transp);
+                       else
+                               htransp = 0;
                }
                hred=CNVT_TOHW(hred,var->red.length);
                hgreen=CNVT_TOHW(hgreen,var->green.length);
@@ -2533,10 +2587,10 @@ memcpy_fs(int fsfromto, void *to, void *from, int len)
                memcpy(to,from,len);
                return;
        case 1:
-               memcpy_fromfs(to,from,len);
+               copy_from_user(to,from,len);
                return;
        case 2:
-               memcpy_tofs(to,from,len);
+               copy_to_user(to,from,len);
                return;
        }
 }
@@ -2738,25 +2792,19 @@ static int
 atari_fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
               unsigned long arg, int con)
 {
-       int i;
-
        switch (cmd) {
 #ifdef FBCMD_GET_CURRENTPAR
        case FBCMD_GET_CURRENTPAR:
-               if ((i = verify_area(VERIFY_WRITE, (void *)arg,
-                                                        sizeof(struct atari_fb_par))))
-                       return i;
-               memcpy_tofs((void *)arg, (void *)&current_par,
-                                       sizeof(struct atari_fb_par));
+               if (copy_to_user((void *)arg, (void *)&current_par,
+                                sizeof(struct atari_fb_par)))
+                       return -EFAULT;
                return 0;
 #endif
 #ifdef FBCMD_SET_CURRENTPAR
        case FBCMD_SET_CURRENTPAR:
-               if ((i = verify_area(VERIFY_READ, (void *)arg,
-                                                        sizeof(struct atari_fb_par))))
-                       return i;
-               memcpy_fromfs((void *)&current_par, (void *)arg,
-                                       sizeof(struct atari_fb_par));
+               if (copy_from_user((void *)&current_par, (void *)arg,
+                                  sizeof(struct atari_fb_par)))
+                       return -EFAULT;
                atari_fb_set_par(&current_par);
                return 0;
 #endif
index a5c685ef3c8036c98ca84ac202ba246c4f00bf3a..642ff027b85050fa6bc8c9ebc06f6c1baadbd3ae 100644 (file)
@@ -626,7 +626,7 @@ int atari_get_irq_list(char *buf)
                        for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {
                                len += sprintf(buf+len, "%s\n", p->devname);
                                if (p->next)
-                                       len += sprintf( buf+len, "                  " );
+                                       len += sprintf( buf+len, "                    " );
                        }
                }
        }
index b4460c46578ff476b117e20162ec3e124ef97493..f314fcbbd51c52a861bee58fc8e46be3c28c4294 100644 (file)
@@ -514,7 +514,7 @@ mste_write(struct MSTE_RTC *val)
 void atari_mste_gettod (int *yearp, int *monp, int *dayp,
                        int *hourp, int *minp, int *secp)
 {
-    int hr24=0;
+    int hr24=0, hour;
     struct MSTE_RTC val;
 
     mste_rtc.mode=(mste_rtc.mode | 1);
@@ -524,13 +524,14 @@ void atari_mste_gettod (int *yearp, int *monp, int *dayp,
     mste_read(&val);
     *secp = val.sec_ones + val.sec_tens * 10;
     *minp = val.min_ones + val.min_tens * 10;
-    if (hr24)
-        *hourp = val.hr_ones + val.hr_tens * 10;
-    else {
-        *hourp = val.hr_ones + (val.hr_tens & 1) * 10;
-        if (val.hr_tens & 2)
-            *hourp += 12;
+    hour = val.hr_ones + val.hr_tens * 10;
+    if (!hr24) {
+        if (hour == 12 || hour == 12 + 20)
+           hour -= 12;
+       if (hour >= 20)
+           hour += 12 - 20;
     }
+    *hourp = hour;
     *dayp = val.day_ones + val.day_tens * 10;
     *monp = val.mon_ones + val.mon_tens * 10;
     *yearp = val.year_ones + val.year_tens * 10 + 80;  
@@ -542,33 +543,38 @@ void atari_gettod (int *yearp, int *monp, int *dayp,
 {
     unsigned char      ctrl;
     unsigned short tos_version;
-               
+    int hour, pm;
+
     while (!(RTC_READ(RTC_FREQ_SELECT) & RTC_UIP)) ;
     while (RTC_READ(RTC_FREQ_SELECT) & RTC_UIP) ;
 
     *secp  = RTC_READ(RTC_SECONDS);
     *minp  = RTC_READ(RTC_MINUTES);
-    *hourp = RTC_READ(RTC_HOURS);
+    hour = RTC_READ(RTC_HOURS);
     *dayp  = RTC_READ(RTC_DAY_OF_MONTH);
     *monp  = RTC_READ(RTC_MONTH);
     *yearp = RTC_READ(RTC_YEAR);
+    pm = hour & 0x80;
+    hour &= ~0x80;
 
     ctrl = RTC_READ(RTC_CONTROL); 
 
     if (!(ctrl & RTC_DM_BINARY)) {
         BCD_TO_BIN(*secp);
         BCD_TO_BIN(*minp);
-        BCD_TO_BIN(*hourp);
+        BCD_TO_BIN(hour);
         BCD_TO_BIN(*dayp);
         BCD_TO_BIN(*monp);
         BCD_TO_BIN(*yearp);
     }
     if (!(ctrl & RTC_24H)) {
-        if (*hourp & 0x80) {
-            *hourp &= ~0x80;
-            *hourp += 12;
-        }
+       if (!pm && hour == 12)
+           hour = 0;
+       else if (pm && hour != 12)
+            hour += 12;
     }
+    *hourp = hour;
+
     /* Adjust values (let the setup valid) */
 
     /* Fetch tos version at Physical 2 */
@@ -603,13 +609,14 @@ int atari_mste_hwclk( int op, struct hwclk_time *t )
         val.min_ones = t->min % 10;
         val.min_tens = t->min / 10;
         hour = t->hour;
+        if (!hr24) {
+           if (hour > 11)
+               hour += 20 - 12;
+           if (hour == 0 || hour == 20)
+               hour += 12;
+        }
         val.hr_ones = hour % 10;
         val.hr_tens = hour / 10;
-        if (!hr24  && hour > 11) {
-            hour -= 12;
-            val.hr_ones = hour % 10;
-            val.hr_tens = (hour / 10) | 2;
-        }
         val.day_ones = t->day % 10;
         val.day_tens = t->day / 10;
         val.mon_ones = (t->mon+1) % 10;
@@ -627,13 +634,14 @@ int atari_mste_hwclk( int op, struct hwclk_time *t )
         mste_read(&val);
         t->sec = val.sec_ones + val.sec_tens * 10;
         t->min = val.min_ones + val.min_tens * 10;
-        if (hr24)
-            t->hour = val.hr_ones + val.hr_tens * 10;
-        else {
-            t->hour = val.hr_ones + (val.hr_tens & 1) * 10;
-            if (val.hr_tens & 2)
-                t->hour += 12;
+        hour = val.hr_ones + val.hr_tens * 10;
+       if (!hr24) {
+           if (hour == 12 || hour == 12 + 20)
+               hour -= 12;
+           if (hour >= 20)
+                hour += 12 - 20;
         }
+       t->hour = hour;
        t->day = val.day_ones + val.day_tens * 10;
         t->mon = val.mon_ones + val.mon_tens * 10 - 1;
         t->year = val.year_ones + val.year_tens * 10 + 80;
@@ -648,6 +656,7 @@ int atari_hwclk( int op, struct hwclk_time *t )
     unsigned long      flags;
     unsigned short     tos_version;
     unsigned char      ctrl;
+    int pm = 0;
 
     /* Tos version at Physical 2.  See above for explanation why we
        cannot use PTOV(2).  */
@@ -667,9 +676,14 @@ int atari_hwclk( int op, struct hwclk_time *t )
         year = t->year - ((tos_version < 0x306) ? 70 : 68);
         wday = t->wday + (t->wday >= 0);
         
-        if (!(ctrl & RTC_24H) && hour > 11) {
-            hour -= 12;
-            hour |= 0x80;
+        if (!(ctrl & RTC_24H)) {
+           if (hour > 11) {
+               pm = 0x80;
+               if (hour != 12)
+                   hour -= 12;
+           }
+           else if (hour == 0)
+               hour = 12;
         }
         
         if (!(ctrl & RTC_DM_BINARY)) {
@@ -716,7 +730,7 @@ int atari_hwclk( int op, struct hwclk_time *t )
     else {
         RTC_WRITE( RTC_SECONDS, sec );
         RTC_WRITE( RTC_MINUTES, min );
-        RTC_WRITE( RTC_HOURS, hour );
+        RTC_WRITE( RTC_HOURS, hour + pm);
         RTC_WRITE( RTC_DAY_OF_MONTH, day );
         RTC_WRITE( RTC_MONTH, mon );
         RTC_WRITE( RTC_YEAR, year );
@@ -728,7 +742,12 @@ int atari_hwclk( int op, struct hwclk_time *t )
     if (!op) {
         /* read: adjust values */
         
-        if (!(ctrl & RTC_DM_BINARY)) {
+        if (hour & 0x80) {
+           hour &= ~0x80;
+           pm = 1;
+       }
+
+       if (!(ctrl & RTC_DM_BINARY)) {
             BCD_TO_BIN(sec);
             BCD_TO_BIN(min);
             BCD_TO_BIN(hour);
@@ -739,10 +758,10 @@ int atari_hwclk( int op, struct hwclk_time *t )
         }
 
         if (!(ctrl & RTC_24H)) {
-            if (hour & 0x80) {
-                hour &= ~0x80;
-                hour += 12;
-            }
+           if (!pm && hour == 12)
+               hour = 0;
+           else if (pm && hour != 12)
+               hour += 12;
         }
 
         t->sec  = sec;
index 7d058bd982fda2b148c8e87be3ee8216c83766ab..67acec33b397ef48a69e23a51e93a93c632c6a29 100644 (file)
@@ -14,7 +14,7 @@
 #include <asm/atarikb.h>
 #include <asm/atari_joystick.h>
 #include <asm/atari_mouse.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 
 #define MAJOR_NR    JOYSTICK_MAJOR
 
@@ -79,14 +79,14 @@ static int open_joystick(struct inode *inode, struct file *file)
     return 0;
 }
 
-static int write_joystick(struct inode *inode, struct file *file,
-                         const char *buffer, int count)
+static long write_joystick(struct inode *inode, struct file *file,
+                          const char *buffer, unsigned long count)
 {
     return -EINVAL;
 }
 
-static int read_joystick(struct inode *inode, struct file *file,
-                        char *buffer, int count)
+static long read_joystick(struct inode *inode, struct file *file,
+                         char *buffer, unsigned long count)
 {
     int minor = DEVICE_NR(inode->i_rdev);
     int i;
index 1c51ec3e4777103597428b981015e5d7a9ac78a3..303babbe116b4687a65d096ed874d004bd3bac9a 100644 (file)
@@ -7,6 +7,8 @@
 #include <asm/atari_joystick.h>
 #include <asm/atari_stdma.h>
 
+extern void atari_microwire_cmd( int cmd );
+
 static struct symbol_table mach_atari_symbol_table = {
 #include <linux/symtab_begin.h>
 
@@ -27,6 +29,8 @@ static struct symbol_table mach_atari_symbol_table = {
        X(ikbd_mouse_rel_pos),
        X(ikbd_mouse_disable),
 
+       X(atari_microwire_cmd),
+       
 #include <linux/symtab_end.h>
 };
 
index dd45bea571f07a89b4535659038ef102920e1bae..a42e6557b2379178db1b3be1399e60d712ba857f 100644 (file)
@@ -29,12 +29,14 @@ comment 'Processor type'
 bool '68020 support' CONFIG_M68020
 bool '68030 support' CONFIG_M68030
 bool '68040 support' CONFIG_M68040
-if [ "$CONFIG_M68040" = "y" ]; then
-  bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
-fi
 bool '68060 support' CONFIG_M68060
-if [ "$CONFIG_M68060" = "y" ]; then
-  bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+if [ "$CONFIG_M68020" = "n" -a "$CONFIG_M68030" = "n" ]; then
+  if [ "$CONFIG_M68040" = "y" -a "$CONFIG_M68060" = "n" ]; then
+    bool 'Use 68040 specific optimizations' CONFIG_OPTIMIZE_040
+  fi
+  if [ "$CONFIG_M68040" = "n" -a "$CONFIG_M68060" = "y" ]; then
+    bool 'Use 68060 specific optimizations' CONFIG_OPTIMIZE_060
+  fi
 fi
 bool 'Advanced processor options' CONFIG_ADVANCED_CPU
 if [ "$CONFIG_ADVANCED_CPU" = "y" ]; then
@@ -56,11 +58,11 @@ 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
-  bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
-  if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
-    bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
+#  bool 'Amiga GSP (TMS340x0) support' CONFIG_AMIGA_GSP
+#  if [ "$CONFIG_AMIGA_GSP" = "y" ]; then
+#    bool 'DMI Resolver support' CONFIG_GSP_RESOLVER
 #    bool 'A2410 support' CONFIG_GSP_A2410
-  fi
+#  fi
 fi
 endmenu
 
@@ -82,11 +84,11 @@ if [ "$CONFIG_AMIGA" = "y" ]; then
 tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
-bool 'Atari ACSI support' CONFIG_ATARI_ACSI
-if [ "$CONFIG_ATARI_ACSI" = "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
-bool 'Atari SLM laser printer support' CONFIG_ATARI_SLM
+dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
 fi
 fi
 
@@ -132,10 +134,13 @@ mainmenu_option next_comment
 comment 'SCSI low-level drivers'
 
 if [ "$CONFIG_AMIGA" = "y" ]; then
-bool 'A3000 WD33C93A support' CONFIG_A3000_SCSI
-bool 'A2091 WD33C93A support' CONFIG_A2091_SCSI
-bool 'GVP Series II WD33C93A support' CONFIG_GVP11_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
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
 dep_tristate 'Atari native SCSI support' CONFIG_ATARI_SCSI $CONFIG_SCSI
@@ -191,8 +196,9 @@ source fs/Config.in
 mainmenu_option next_comment
 comment 'Character devices'
 
-bool 'Parallel printer support' CONFIG_PRINTER
+tristate 'Parallel printer support' CONFIG_PRINTER
 if [ "$CONFIG_AMIGA" = "y" ]; then
+  dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER
   tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE
 fi
 if [ "$CONFIG_ATARI" = "y" ]; then
@@ -220,9 +226,9 @@ endmenu
 mainmenu_option next_comment
 comment 'Sound support'
 
-bool 'Sound support' CONFIG_SOUND y
+tristate 'Sound support' CONFIG_SOUND
 if [ "$CONFIG_SOUND" != "n" ]; then
-  bool 'Amiga or Atari DMA sound support' CONFIG_DMASOUND y
+  dep_tristate 'Amiga or Atari DMA sound support' CONFIG_DMASOUND $CONFIG_SOUND
 fi
 endmenu
 
index 32c5752c0f64093557c3046e36e6f32b23d933e2..ecb926f882ad5ea78900ec6053cd11fe194aff8c 100644 (file)
@@ -67,6 +67,7 @@
 #include <asm/machdep.h>
 
 #include <asm/system.h>
+#include <asm/uaccess.h>
 
 #include "../../../drivers/char/vt_kern.h"   /* vt_cons and vc_resize_con() */
 
@@ -244,7 +245,7 @@ static int fbcon_blank(int blank);
     *    Internal routines
     */
 
-static void fbcon_setup(int con, int setcol, int cls);
+static void fbcon_setup(int con, int setcol, int init);
 static __inline__ void *mymemclear_small(void *s, size_t count);
 static __inline__ void *mymemclear(void *s, size_t count);
 static __inline__ void *mymemset(void *s, size_t count);
@@ -547,7 +548,7 @@ static void fbcon_init(struct vc_data *conp)
    if (unit)
       disp[unit] = disp[0];
    disp[unit].conp = conp;
-   fbcon_setup(unit, 1, 0);
+   fbcon_setup(unit, 1, 1);
 }
 
 
@@ -560,15 +561,16 @@ static int fbcon_deinit(struct vc_data *conp)
 
 static int fbcon_changevar(int con)
 {
-   fbcon_setup(con, 1, 1);
+   fbcon_setup(con, 1, 0);
    return(0);
 }
 
 
-static void fbcon_setup(int con, int setcol, int cls)
+static void fbcon_setup(int con, int setcol, int init)
 {
    struct display *p = &disp[con];
    struct vc_data *conp = p->conp;
+   int nr_rows, nr_cols;
 
    p->var.xoffset = p->var.yoffset = p->yscroll = 0;  /* reset wrap/pan */
 
@@ -588,8 +590,15 @@ static void fbcon_setup(int con, int setcol, int cls)
    else
       p->scrollmode = SCROLL_YMOVE;
 
-   conp->vc_cols = p->var.xres/p->fontwidth;
-   conp->vc_rows = p->var.yres/p->fontheight;
+   nr_cols = p->var.xres/p->fontwidth;
+   nr_rows = p->var.yres/p->fontheight;
+   /* ++guenther: console.c:vc_allocate() relies on initializing vc_{cols,rows},
+    * but we must not set those if we are only resizing the console.
+    */
+   if (init) {
+      conp->vc_cols = nr_cols;
+      conp->vc_rows = nr_rows;
+   }
    p->vrows = p->var.yres_virtual/p->fontheight;
    conp->vc_can_do_color = p->var.bits_per_pixel != 1;
 
@@ -701,8 +710,8 @@ fail:
       p->bgcol = 0;
    }
 
-   if (cls)
-      vc_resize_con(conp->vc_rows, conp->vc_cols, con);
+   if (!init)
+      vc_resize_con(nr_rows, nr_cols, con);
 }
 
 
@@ -1467,6 +1476,10 @@ static int fbcon_cursor(struct vc_data *conp, int mode)
    int unit = conp->vc_num;
    struct display *p = &disp[unit];
 
+   /* Avoid flickering if there's no real change. */
+   if (p->cursor_x == conp->vc_x && p->cursor_y == conp->vc_y &&
+       (mode == CM_ERASE) == !cursor_on)
+      return 0;
    if (CURSOR_UNDRAWN ())
       p->dispsw->rev_char(p, p->cursor_x, real_y(p, p->cursor_y));
    p->cursor_x = conp->vc_x;
@@ -1752,7 +1765,7 @@ static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
           
                if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
                        return i;
-               memcpy_fromfs( name, data, MAX_FONT_NAME );
+               copy_from_user( name, data, MAX_FONT_NAME );
                name[sizeof(name)-1] = 0;
                
                if (!findsoftfont( name, &w, &h, (u_char **)&data ))
index 31f9c3690507370c99d66e65e22175584a1bd457..e973269290412f61253bfb4fb475ba8b919aa72a 100644 (file)
@@ -27,8 +27,8 @@ CONFIG_AMIGA=y
 CONFIG_M68020=y
 CONFIG_M68030=y
 CONFIG_M68040=y
-# CONFIG_OPTIMIZE_040 is not set
 # CONFIG_M68060 is not set
+# CONFIG_OPTIMIZE_040 is not set
 # CONFIG_OPTIMIZE_060 is not set
 # CONFIG_ADVANCED_CPU is not set
 # CONFIG_RMW_INSNS is not set
@@ -56,6 +56,10 @@ CONFIG_AMIFB_AGA=y
 CONFIG_BLK_DEV_FD=y
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_IDE is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_AMIGA_Z2RAM is not set
 # CONFIG_ATARI_ACSI is not set
 # CONFIG_ACSI_MULTI_LUN is not set
@@ -87,6 +91,7 @@ CONFIG_INET=y
 # CONFIG_TCP_NAGLE_OFF is not set
 CONFIG_IP_NOSR=y
 # CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
 
 #
 #  
@@ -122,7 +127,10 @@ CONFIG_A3000_SCSI=y
 # CONFIG_A2091_SCSI is not set
 # CONFIG_GVP11_SCSI is not set
 # CONFIG_CYBERSTORM_SCSI is not set
-# CONFIG_ATARI_SCSI is not set
+# CONFIG_CYBERSTORMII_SCSI is not set
+# CONFIG_BLZ2060_SCSI is not set
+# CONFIG_BLZ1230_SCSI is not set
+CONFIG_ATARI_SCSI=y
 
 #
 # Network device support
@@ -142,7 +150,6 @@ CONFIG_A3000_SCSI=y
 # Filesystems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_LOCK_MANDATORY is not set
 CONFIG_MINIX_FS=y
 # CONFIG_EXT_FS is not set
 CONFIG_EXT2_FS=y
@@ -151,6 +158,7 @@ CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_VFAT_FS is not set
 # CONFIG_UMSDOS_FS is not set
+# CONFIG_MSDOS_PARTITION is not set
 CONFIG_PROC_FS=y
 CONFIG_NFS_FS=y
 # CONFIG_ROOT_NFS is not set
@@ -166,7 +174,7 @@ CONFIG_NFS_FS=y
 #
 # CONFIG_PRINTER is not set
 CONFIG_AMIGAMOUSE=y
-# CONFIG_ATARIMOUSE is not set
+CONFIG_ATARIMOUSE=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
 # CONFIG_GVPIOEXT is not set
 # CONFIG_MULTIFACE_III_TTY is not set
index e8888387e0375773fa86c026a8edb06689ac5baa..cac94e7d4656b0639a34bcb5209fdd71274af0af 100644 (file)
 #include <linux/ioport.h>
 
 #include <asm/io.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
 
@@ -1134,7 +1134,7 @@ static void set_mode(int currcons, int on_off)
                                if (on_off)
                                        set_kbd(decckm);
                                else
-                                       clr_kbd(decckm); 
+                                       clr_kbd(decckm);
                                break;
                        case 3: /* 80/132 mode switch unimplemented */
                                deccolm = on_off;
@@ -1371,7 +1371,7 @@ static void restore_cur(int currcons)
        need_wrap = 0;
 }
 
-enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, 
+enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
        ESpalette };
 
@@ -1457,8 +1457,18 @@ static void con_start(struct tty_struct *tty)
        set_leds();
 }
 
-static int con_write(struct tty_struct * tty, int from_user,
-                    const unsigned char *buf, int count)
+static void con_flush_chars(struct tty_struct *tty)
+{
+       unsigned int currcons;
+       struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
+
+       currcons = vt->vc_num;
+       if (vcmode != KD_GRAPHICS)
+               set_cursor(currcons);
+}      
+
+static int do_con_write(struct tty_struct * tty, int from_user,
+                       const unsigned char *buf, int count)
 {
        int c, tc, ok, n = 0;
        unsigned int currcons;
@@ -1486,7 +1496,10 @@ static int con_write(struct tty_struct * tty, int from_user,
         disable_bh(CONSOLE_BH);
        while (count) {
                enable_bh(CONSOLE_BH);
-               c = from_user ? get_user(buf) : *buf;
+               if (from_user)
+                       get_user(c, buf);
+               else
+                       c = *buf;
                buf++; n++; count--;
                disable_bh(CONSOLE_BH);
 
@@ -1541,7 +1554,8 @@ static int con_write(struct tty_struct * tty, int from_user,
                 ok = tc && (c >= 32 ||
                             (!utf && !(((disp_ctrl ? CTRL_ALWAYS
                                          : CTRL_ACTION) >> c) & 1)))
-                        && (c != 127 || disp_ctrl);
+                        && (c != 127 || disp_ctrl)
+                       && (c != 128+27);
 
                if (vc_state == ESnormal && ok) {
                        /* Now try to find out how to display it */
@@ -1561,7 +1575,7 @@ static int con_write(struct tty_struct * tty, int from_user,
                                cr(currcons);
                                lf(currcons);
                        }
-                       
+
 #if 1 /* XXX */
                         /* DPC: 1994-04-12
                          *   Speed up overstrike mode, using new putcs.
@@ -1581,7 +1595,7 @@ static int con_write(struct tty_struct * tty, int from_user,
 
                                *p++ = tc;
                                *pos++ = tc | (attr << 8);
-                               
+
                                if (nextx == cols) {
                                        sw->con_putc(vc_cons[currcons].d,
                                                     *putcs_buf, y, x);
@@ -1591,11 +1605,14 @@ static int con_write(struct tty_struct * tty, int from_user,
                                }
                                
                                /* TAB TAB TAB - Arghh!!!! */
-                               
+
                                while (count)
                                {
                                        enable_bh(CONSOLE_BH);
-                                       c = from_user ? get_user(buf) : *buf;
+                                       if (from_user)
+                                               get_user(c, buf);
+                                       else
+                                               c = *buf;
                                        disable_bh(CONSOLE_BH);
                                        tc = translate[toggle_meta ? (c|0x80) : c];
                                        if (!tc ||
@@ -1655,6 +1672,8 @@ static int con_write(struct tty_struct * tty, int from_user,
                 *  of an escape sequence.
                 */
                switch (c) {
+                   case 0:
+                       continue;
                    case 7:
                        if (bell_duration)
                            kd_mksound(bell_pitch, bell_duration);
@@ -2000,12 +2019,26 @@ static int con_write(struct tty_struct * tty, int from_user,
                        vc_state = ESnormal;
                }
        }
-       if (vcmode != KD_GRAPHICS)
-               set_cursor(currcons);
        enable_bh(CONSOLE_BH);
        return n;
 }
 
+static int con_write(struct tty_struct * tty, int from_user,
+                    const unsigned char *buf, int count)
+{
+       int     retval;
+       
+       retval = do_con_write(tty, from_user, buf, count);
+       con_flush_chars(tty);
+       
+       return retval;
+}
+
+static void con_put_char(struct tty_struct *tty, unsigned char ch)
+{
+       do_con_write(tty, 0, &ch, 1);
+}
+
 static int con_write_room(struct tty_struct *tty)
 {
        if (tty->stopped)
@@ -2208,6 +2241,8 @@ unsigned long con_init(unsigned long kmem_start)
        console_driver.open = con_open;
        console_driver.write = con_write;
        console_driver.write_room = con_write_room;
+       console_driver.put_char = con_put_char;
+       console_driver.flush_chars = con_flush_chars;
        console_driver.chars_in_buffer = con_chars_in_buffer;
        console_driver.ioctl = vt_ioctl;
        console_driver.stop = con_stop;
@@ -2474,12 +2509,7 @@ static int set_get_font(char * arg, int set, int ch512)
        int i, unit, size;
        char *charmap;
 
-       if (arg){
-               i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
-                               (void *)arg, ch512 ? 2*cmapsz : cmapsz);
-               if (i)
-                       return i;
-       }else
+       if (!arg)
                return -EINVAL;
 
 
@@ -2488,7 +2518,10 @@ static int set_get_font(char * arg, int set, int ch512)
        charmap = (char *)kmalloc(size, GFP_USER);
 
        if (set){
-               memcpy_fromfs(charmap, arg, size);
+               if (copy_from_user(charmap, arg, size)) {
+                       kfree(charmap);
+                       return -EFAULT;
+               }
 
                for (unit = 32; unit > 0; unit--)
                        for (i = 0; i < (ch512 ? 512 : 256); i++)
@@ -2501,7 +2534,8 @@ static int set_get_font(char * arg, int set, int ch512)
                memset(charmap, 0, size);
                i = conswitchp->con_get_font(vc_cons[fg_console].d,
                                             &unit, &unit, charmap);
-               memcpy_tofs(arg, charmap, size);
+               if (i == 0 && copy_to_user(arg, charmap, size))
+                       i = -EFAULT;
        }
        kfree(charmap);
 
@@ -2572,7 +2606,8 @@ int con_adjust_height(unsigned long fontheight)
 void set_vesa_blanking(int arg)
 {
        char *argp = (char *)arg + 1;
-       unsigned int mode = get_fs_byte(argp);
+       unsigned int mode;
+       get_user(mode, argp);
        vesa_blank_mode = (mode < 4) ? mode : 0;
 }
 
index 396078e099f67ca77b577811061159376b796dce..603afe9abad3f6435627975f4311597f9fe7358f 100644 (file)
@@ -319,8 +319,8 @@ LTSS_KSP    = 0
 LTSS_USP       = 4
 LTSS_SR                = 8
 LTSS_FS                = 10
-LTSS_CRP       = 20
-LTSS_FPCTXT    = 32
+LTSS_CRP       = 12
+LTSS_FPCTXT    = 24
 
 SYMBOL_NAME_LABEL(resume)
        /*
@@ -401,7 +401,7 @@ SYMBOL_NAME_LABEL(resume)
        movec   %cacr,%d0
        oriw    #LFLUSH_I_AND_D,%d0
        movec   %d0,%cacr
-
+       
        /* switch the root pointer */
        pmove   %a1@(LTSS_CRP),%crp
 #endif
@@ -643,4 +643,6 @@ SYMBOL_NAME_LABEL(sys_call_table)
        .long SYMBOL_NAME(sys_sched_rr_get_interval)
        .long SYMBOL_NAME(sys_nanosleep)
        .long SYMBOL_NAME(sys_mremap)
-       .space (NR_syscalls-163)*4
+       .long SYMBOL_NAME(sys_setresuid)
+       .long SYMBOL_NAME(sys_getresuid)
+       .space (NR_syscalls-165)*4
index 354c17eea75fd29f499cfda3a81f1361df86b7a6..3dab4b2eb8eb5785dc76105e4c9c86f6fa9046cc 100644 (file)
@@ -319,7 +319,7 @@ ENTRY(_start)
        lea     %pc@(SYMBOL_NAME(kpt)),%a1
        movel   %a3,%a1@                /* save address of page table */
        movel   %a3,%a1
-       addql   #_PAGE_TABLE,%a1        /* descriptor type */
+       addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* descriptor type */
        movel   #PAGE_TABLE_SIZE<<2,%d2 /* increment */
 
 2:     movel   %a1,%a0@+
@@ -341,7 +341,7 @@ ENTRY(_start)
 
        movel   %a3,%a0
        movel   %d5,%a1
-       addw    #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT,%a1
+       addw    #_PAGE_GLOBAL040+_PAGE_CACHE040+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
        movew   #(PAGE_TABLE_SIZE*TABLENR_4MB)-1,%d1
        movel   #PAGESIZE,%d2
 1:     movel   %a1,%a0@+
@@ -404,7 +404,7 @@ Lnot040:
 
        putc('I')
 
-       moveq   #_PAGE_NOCACHE030+_PAGE_PRESENT,%d0
+       movel   #_PAGE_NOCACHE030+_PAGE_PRESENT+_PAGE_ACCESSED,%d0
        movel   %d0,%a5@(0x40<<2)
 
        jra     Lmapphys
@@ -431,7 +431,7 @@ Lspami68040:
        /* initialize the pointer table */
        movel   %a4,%a0
        movel   %a3,%a1
-       addql   #_PAGE_TABLE,%a1        /* base descriptor */
+       addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a1 /* base descriptor */
        movel   #PAGE_TABLE_SIZE<<2,%d2 /* increment */
        moveq   #TABLENR_16MB-1,%d1
 
@@ -441,7 +441,7 @@ Lspami68040:
 
        /* ensure that the root table points to the pointer table */
        movel   %a4,%a0
-       addql   #_PAGE_TABLE,%a0
+       addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a0
        movel   %a0,%a5@(0x40<<2)
 
        /*
@@ -449,7 +449,7 @@ Lspami68040:
         * descriptor bits include noncachable/serialized and global bits.
         */
        movel   %a3,%a0
-       movew   #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+       movew   #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
        movel   #PAGESIZE,%d2
        movew   #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
 
@@ -518,7 +518,7 @@ Ltest_berr:
        /* Let the root table point to the new pointer table */
        lea     %a4@(PTR_TABLE_SIZE<<2),%a4
        movel   %a4,%a0
-       addl    #_PAGE_TABLE,%a0
+       addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a0
        movel   %a0,%a5@(0x7f<<2)       /* 0xFE000000 - 0xFFFFFFFF */
 
        /* clear lower half of the pointer table (0xfexxxxxx) */
@@ -534,7 +534,7 @@ Ltest_berr:
        movel   #PAGE_TABLE_SIZE*PAGESIZE,%d1
        movel   #(PTR_TABLE_SIZE/2)-1,%d2
        movel   %d3,%d0
-       addl    #_PAGE_PRESENT,%d0
+       orw     #_PAGE_PRESENT+_PAGE_ACCESSED,%d0
 1:     movel   %d0,%a0@+
        addl    %d1,%d0
        dbra    %d2,1b
@@ -552,7 +552,7 @@ Lspata68040:
 
        /* Initialize the upper half of the pointer table (a0 is still valid) */
        movel   %a3,%a1
-       addql   #_PAGE_TABLE,%a1
+       addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a1
        movel   #PAGE_TABLE_SIZE<<2,%d2
        moveq   #TABLENR_16MB-1,%d1
 1:     movel   %a1,%a0@+
@@ -562,7 +562,7 @@ Lspata68040:
        /* Initialize the page tables as noncacheable/serialized! */
        movel   %a3,%a0
        movel   %d3,%a1
-       addw    #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT,%a1
+       addw    #_PAGE_GLOBAL040+_PAGE_NOCACHE_S+_PAGE_PRESENT+_PAGE_ACCESSED,%a1
        movel   #PAGESIZE,%d2
        movew   #(PAGE_TABLE_SIZE*TABLENR_16MB)-1,%d1
 1:     movel   %a1,%a0@+
@@ -629,7 +629,7 @@ Lmapphys:
        lsrl    %d2,%d0
        movel   %d0,%d1
        lsll    %d2,%d1
-       addql   #_PAGE_PRESENT,%d1
+       orw     #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
        lsll    #2,%d0
        movel   %a5@(%d0:w),%d2
        movel   %d1,%a5@(%d0:w)
@@ -722,7 +722,7 @@ Lmapphysnotamiga:
        lsrl    %d0,%d1
        lea     %a1@(%d1:l:4),%a1
        movel   %d5,%d1
-       addql   #_PAGE_PRESENT,%d1
+       orw     #_PAGE_PRESENT+_PAGE_ACCESSED,%d1
        movel   %a1@,%d2
        movel   %d1,%a1@
        lea     5f:w,%a0
index bee06dccee0301da340a9b04fa2dc9564fbe5259..bf067c782250b03e5d5f73cfb7d71fcbbe4690b1 100644 (file)
@@ -40,12 +40,14 @@ static struct symbol_table arch_symbol_table = {
        X(cache_clear),
        X(mm_vtop),
        X(mm_ptov),
+       X(mm_end_of_chunk),
        X(m68k_debug_device),
        X(request_irq),
        X(free_irq),
        X(dump_fpu),
        X(dump_thread),
        X(strnlen),
+       X(strrchr),
 
        /* The following are special because they're not called
           explicitly (the C compiler generates them).  Fortunately,
@@ -55,8 +57,8 @@ static struct symbol_table arch_symbol_table = {
        XNOVERS(memcpy),
        XNOVERS(memset),
 
-       XNOVERS(down_failed),
-       XNOVERS(up_wakeup),
+       XNOVERS(__down_failed),
+       XNOVERS(__up_wakeup),
 
 #include <linux/symtab_end.h>
 };
index 8e6517aa9e11dd7ed8fd1a9b4aa77a8fba2afdfd..cc9664b5fe66568dc8c456bcd7438ca529864c12 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/user.h>
 #include <linux/a.out.h>
 
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/machdep.h>
@@ -172,6 +172,8 @@ int dump_fpu (struct user_m68kfp_struct *fpu)
  */
 void dump_thread(struct pt_regs * regs, struct user * dump)
 {
+       struct switch_stack *sw;
+
 /* changed the size calculations - should hopefully work better. lbt */
        dump->magic = CMAGIC;
        dump->start_code = 0;
@@ -186,8 +188,27 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
                dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
 
        dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump)));
-       dump->regs = *regs;
-       dump->regs2 = ((struct switch_stack *)regs)[-1];
+       sw = ((struct switch_stack *)regs) - 1;
+       dump->regs.d1 = regs->d1;
+       dump->regs.d2 = regs->d2;
+       dump->regs.d3 = regs->d3;
+       dump->regs.d4 = regs->d4;
+       dump->regs.d5 = regs->d5;
+       dump->regs.d6 = sw->d6;
+       dump->regs.d7 = sw->d7;
+       dump->regs.a0 = regs->a0;
+       dump->regs.a1 = regs->a1;
+       dump->regs.a2 = sw->a2;
+       dump->regs.a3 = sw->a3;
+       dump->regs.a4 = sw->a4;
+       dump->regs.a5 = sw->a5;
+       dump->regs.a6 = sw->a6;
+       dump->regs.d0 = regs->d0;
+       dump->regs.orig_d0 = regs->orig_d0;
+       dump->regs.stkadj = regs->stkadj;
+       dump->regs.sr = regs->sr;
+       dump->regs.pc = regs->pc;
+       dump->regs.fmtvec = (regs->format << 12) | regs->vector;
        /* dump floating point stuff */
        dump->u_fpvalid = dump_fpu (&dump->m68kfp);
 }
index 5fbb279e33bdafba1139545981335b57b31c9f34..dc48a2ec53fe5f392c2fcea86ab1b8e306ec366b 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -140,7 +140,7 @@ repeat:
        }
        page = pte_page(*pgtable);
 /* this is a hack for non-kernel-mapped video buffers and similar */
-       if (page >= high_memory)
+       if (MAP_NR(page) >= max_mapnr)
                return 0;
        page += addr & ~PAGE_MASK;
        return *(unsigned long *) page;
@@ -196,7 +196,7 @@ repeat:
                goto repeat;
        }
 /* this is a hack for non-kernel-mapped video buffers and similar */
-       if (page < high_memory) {
+       if (MAP_NR(page) < max_mapnr) {
                *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
                flush_page_to_ram (page);
        }
@@ -380,24 +380,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                        res = read_long(child, addr, &tmp);
                        if (res < 0)
                                return res;
-                       res = verify_area(VERIFY_WRITE, (void *) data, sizeof(long));
-                       if (!res)
-                               put_user(tmp, (unsigned long *) data);
-                       return res;
+                       return put_user(tmp, (unsigned long *) data);
                }
 
        /* read the word at location addr in the USER area. */
                case PTRACE_PEEKUSR: {
                        unsigned long tmp;
-                       int res;
                        
                        if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
                                return -EIO;
                        
-                       res = verify_area(VERIFY_WRITE, (void *) data,
-                                         sizeof(long));
-                       if (res)
-                               return res;
                        tmp = 0;  /* Default return condition */
                        addr = addr >> 2; /* temporary hack. */
                        if (addr < 19) {
@@ -409,8 +401,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
                                tmp = child->tss.fp[addr - 21];
                        else
                                return -EIO;
-                       put_user(tmp,(unsigned long *) data);
-                       return 0;
+                       return put_user(tmp,(unsigned long *) data);
                }
 
       /* when I and D space are separate, this will have to be fixed. */
index f85992a82eb1a377b954890fc317f52689a20d97..0d2a372f94824ac6869d0f82a25e0de2566b1726 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/unistd.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/traps.h>
 
@@ -45,7 +45,7 @@
 asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
 asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs);
 
-static const int extra_sizes[16] = {
+const int frame_extra_sizes[16] = {
   0,
   -1, /* sizeof(((struct frame *)0)->un.fmt1), */
   sizeof(((struct frame *)0)->un.fmt2),
@@ -86,7 +86,7 @@ static unsigned char fpu_version = 0; /* version number of fpu, set by setup_fra
 
 asmlinkage int do_sigreturn(unsigned long __unused)
 {
-       struct sigcontext_struct context;
+       struct sigcontext context;
        struct pt_regs *regs;
        struct switch_stack *sw;
        int fsize = 0;
@@ -103,10 +103,8 @@ asmlinkage int do_sigreturn(unsigned long __unused)
        regs = (struct pt_regs *) (sw + 1);
 
        /* get previous context (including pointer to possible extra junk) */
-        if (verify_area(VERIFY_READ, (void *)usp, sizeof(context)))
-                goto badframe;
-
-       memcpy_fromfs(&context,(void *)usp, sizeof(context));
+       if (copy_from_user(&context,(void *)usp, sizeof(context)))
+               goto badframe;
 
        fp = usp + sizeof (context);
 
@@ -163,7 +161,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
          }
        __asm__ volatile ("frestore %0" : : "m" (*context.sc_fpstate));
 
-       fsize = extra_sizes[regs->format];
+       fsize = frame_extra_sizes[regs->format];
        if (fsize < 0) {
                /*
                 * user process trying to return with weird frame format
@@ -182,31 +180,37 @@ asmlinkage int do_sigreturn(unsigned long __unused)
         */
 
        if (fsize) {
-               if (verify_area(VERIFY_READ, (void *)fp, fsize))
-                        goto badframe;
-
 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
                __asm__ __volatile__
-                       ("movel %0,%/a0\n\t"
-                        "subl %1,%/a0\n\t"     /* make room on stack */
-                        "movel %/a0,%/sp\n\t"  /* set stack pointer */
+                       ("   movel %0,%/a0\n\t"
+                        "   subl %1,%/a0\n\t"     /* make room on stack */
+                        "   movel %/a0,%/sp\n\t"  /* set stack pointer */
                         /* move switch_stack and pt_regs */
                         "1: movel %0@+,%/a0@+\n\t"
                         "   dbra %2,1b\n\t"
-                        "lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt stuff */
-                        "lsrl  #2,%1\n\t"
-                        "subql #1,%1\n\t"
+                        "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+                        "   lsrl  #2,%1\n\t"
+                        "   subql #1,%1\n\t"
                         "2: movesl %4@+,%2\n\t"
-                        "   movel %2,%/a0@+\n\t"
+                        "3: movel %2,%/a0@+\n\t"
                         "   dbra %1,2b\n\t"
-                        "bral " SYMBOL_NAME_STR(ret_from_signal)
+                        "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
+                        "4:\n"
+                        ".section __ex_table,\"a\"\n"
+                        "   .align 4\n"
+                        "   .long 2b,4b\n"
+                        "   .long 3b,4b\n"
+                        ".text"
                         : /* no outputs, it doesn't ever return */
                         : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
                           "n" (frame_offset), "a" (fp)
                         : "a0");
 #undef frame_offset
+               /*
+                * If we ever get here an exception occured while
+                * building the above stack-frame.
+                */
                goto badframe;
-               /* NOTREACHED */
        }
 
        return regs->d0;
@@ -255,14 +259,14 @@ badframe:
  * longwords for format "B".
  */
 
-#define UFRAME_SIZE(fs) (sizeof(struct sigcontext_struct)/4 + 6 + fs/4)
+#define UFRAME_SIZE(fs) (sizeof(struct sigcontext)/4 + 6 + fs/4)
 
 static void setup_frame (struct sigaction * sa, struct pt_regs *regs,
                         int signr, unsigned long oldmask)
 {
-       struct sigcontext_struct context;
+       struct sigcontext context;
        unsigned long *frame, *tframe;
-       int fsize = extra_sizes[regs->format];
+       int fsize = frame_extra_sizes[regs->format];
 
        if (fsize < 0) {
                printk ("setup_frame: Unknown frame format %#x\n",
@@ -277,10 +281,9 @@ static void setup_frame (struct sigaction * sa, struct pt_regs *regs,
        }
        frame -= UFRAME_SIZE(fsize);
 
-       if (verify_area(VERIFY_WRITE,frame,UFRAME_SIZE(fsize)*4))
-               do_exit(SIGSEGV);
        if (fsize) {
-               memcpy_tofs (frame + UFRAME_SIZE(0), regs + 1, fsize);
+               if (copy_to_user (frame + UFRAME_SIZE(0), regs + 1, fsize))
+                       do_exit(SIGSEGV);
                regs->stkadj = fsize;
        }
 
@@ -326,7 +329,8 @@ static void setup_frame (struct sigaction * sa, struct pt_regs *regs,
                                  "m" (*context.sc_fpcntl)
                                  : "memory");
        }
-       memcpy_tofs (tframe, &context, sizeof(context));
+       if (copy_to_user (tframe, &context, sizeof(context)))
+               do_exit(SIGSEGV);
 
        /*
         * no matter what frame format we were using before, we
@@ -440,7 +444,7 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs)
                               isn't restarted (only needed on the
                               68030).  */
                            if (regs->format == 10 || regs->format == 11) {
-                               regs->stkadj = extra_sizes[regs->format];
+                               regs->stkadj = frame_extra_sizes[regs->format];
                                regs->format = 0;
                            }
                            continue;
index 9f79a09b315508de2ded9861c03b84f1d4246fa0..d187e3d570a9d935d1fc1a3d5e17102744085720 100644 (file)
 #include <linux/shm.h>
 #include <linux/stat.h>
 #include <linux/mman.h>
+#include <linux/file.h>
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/cachectl.h>
 #include <asm/traps.h>
+#include <asm/ipc.h>
 
 /*
  * sys_pipe() is the normal C calling standard for creating
@@ -47,47 +49,50 @@ asmlinkage int sys_pipe(unsigned long * fildes)
  * used a memory block for parameter passing..
  */
 
-asmlinkage int old_mmap(unsigned long *buffer)
+struct mmap_arg_struct {
+       unsigned long addr;
+       unsigned long len;
+       unsigned long prot;
+       unsigned long flags;
+       unsigned long fd;
+       unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
 {
        int error;
-       unsigned long flags;
        struct file * file = NULL;
+       struct mmap_arg_struct a;
 
-       error = verify_area(VERIFY_READ, buffer, 6*sizeof(long));
+       error = verify_area(VERIFY_READ, arg, sizeof(*arg));
        if (error)
                return error;
-       flags = get_user(buffer+3);
-       if (!(flags & MAP_ANONYMOUS)) {
-               unsigned long fd = get_user(buffer+4);
-               if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+       copy_from_user(&a, arg, sizeof(a));
+       if (!(a.flags & MAP_ANONYMOUS)) {
+               if (a.fd >= NR_OPEN || !(file = current->files->fd[a.fd]))
                        return -EBADF;
        }
-       flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-       return do_mmap(file, get_user(buffer), get_user(buffer+1),
-                      get_user(buffer+2), flags, get_user(buffer+5));
+       a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+       error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+       return error;
 }
 
 
 extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 
-asmlinkage int old_select(unsigned long *buffer)
-{
-       int n;
-       fd_set *inp;
-       fd_set *outp;
-       fd_set *exp;
+struct sel_arg_struct {
+       unsigned long n;
+       fd_set *inp, *outp, *exp;
        struct timeval *tvp;
+};
 
-       n = verify_area(VERIFY_READ, buffer, 5*sizeof(unsigned long));
-       if (n)
-         return n;
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+       struct sel_arg_struct a;
 
-       n = get_user(buffer);
-       inp = (fd_set *) get_user(buffer+1);
-       outp = (fd_set *) get_user(buffer+2);
-       exp = (fd_set *) get_user(buffer+3);
-       tvp = (struct timeval *) get_user(buffer+4);
-       return sys_select(n, inp, outp, exp, tvp);
+       if (copy_from_user(&a, arg, sizeof(a)))
+               return -EFAULT;
+       return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
 }
 
 /*
@@ -115,7 +120,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
                                return -EINVAL;
                        if ((err = verify_area (VERIFY_READ, ptr, sizeof(long))))
                                return err;
-                       fourth.__pad = get_user((void **)ptr);
+                       get_user(fourth.__pad, (void **)ptr);
                        return sys_semctl (first, second, third, fourth);
                        }
                default:
@@ -130,13 +135,10 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
                        switch (version) {
                        case 0: {
                                struct ipc_kludge tmp;
-                               int err;
                                if (!ptr)
                                        return -EINVAL;
-                               if ((err = verify_area (VERIFY_READ, ptr, sizeof(tmp))))
-                                       return err;
-                               memcpy_fromfs (&tmp,(struct ipc_kludge *) ptr,
-                                              sizeof (tmp));
+                               if (copy_from_user (&tmp, ptr, sizeof (tmp)))
+                                       return -EFAULT;
                                return sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
                                }
                        case 1: default:
index 45c52e7f594c253df8795d9628cd81a55a21118a..dbff49276287d89f6bcb629b4cd433491186c934 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 
 #include <asm/machdep.h>
-#include <asm/segment.h>
 #include <asm/io.h>
 
 #include <linux/timex.h>
index cfaff152f960425e02ce774d193adfd727fc32ec..39625f3b66dcea2572259006a60b4162a744e2f5 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <asm/setup.h>
 #include <asm/system.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/traps.h>
 #include <asm/pgtable.h>
 #include <asm/machdep.h>
@@ -96,7 +96,6 @@ void trap_init (void)
                vectors[VEC_FPNAN] = snan_vec;
                vectors[VEC_FPOE] = operr_vec;
                vectors[VEC_FPBRUC] = bsun_vec;
-               vectors[VEC_FPBRUC] = bsun_vec;
                vectors[VEC_LINE11] = fline_vec;
                vectors[VEC_FPUNSUP] = unsupp_vec;
        }
@@ -159,7 +158,11 @@ char *vec_names[] = {
        "SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
        "TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
        "TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
-       "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15"
+       "TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+       "FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+       "FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+       "FPCP UNSUPPORTED OPERATION",
+       "MMU CONFIGUATION ERROR"
        };
 
 char *space_names[] = {
@@ -205,7 +208,7 @@ static inline void access_error060 (struct frame *fp)
 #endif
                if (fslw & MMU060_MA)
                        addr = PAGE_ALIGN(addr);
-               do_page_fault( (struct pt_regs *)fp, addr, errorcode );
+               do_page_fault(&fp->ptregs, addr, errorcode);
        }
        else {
                printk( "68060 access error, fslw=%lx\n", fslw );
@@ -263,20 +266,20 @@ static void do_040writeback (unsigned short ssw,
 
        mmusr = probe040 (1, wbs & WBTM_040,  wba);
        errorcode = (mmusr & MMU_R_040) ? 3 : 2;
-       if (do_page_fault ((struct pt_regs *)fp, wba, errorcode))
+       if (do_page_fault (&fp->ptregs, wba, errorcode))
          /* just return if we can't perform the writeback */
          return;
 
        set_fs (wbs & WBTM_040);
        switch (wbs & WBSIZ_040) {
            case BA_SIZE_BYTE:
-               put_fs_byte (wbd & 0xff, (char *)wba);
+               put_user (wbd & 0xff, (char *)wba);
                break;
            case BA_SIZE_WORD:
-               put_fs_word (wbd & 0xffff, (short *)wba);
+               put_user (wbd & 0xffff, (short *)wba);
                break;
            case BA_SIZE_LONG:
-               put_fs_long (wbd, (int *)wba);
+               put_user (wbd, (int *)wba);
                break;
        }
        set_fs (fs);
@@ -317,7 +320,7 @@ static inline void access_error040 (struct frame *fp)
 */
                errorcode = ((mmusr & MMU_R_040) ? 1 : 0) |
                        ((ssw & RW_040) ? 0 : 2);
-               do_page_fault ((struct pt_regs *)fp, addr, errorcode);
+               do_page_fault (&fp->ptregs, addr, errorcode);
        } else {
                printk ("68040 access error, ssw=%x\n", ssw);
                trap_c (fp);
@@ -394,8 +397,8 @@ static inline void bus_error030 (struct frame *fp)
                        }
                        printk ("BAD KERNEL BUSERR\n");
                        die_if_kernel("Oops",&fp->ptregs,0);
-                       force_sig(SIGSEGV, current);
-                       user_space_fault = 0;
+                       force_sig(SIGKILL, current);
+                       return;
                }
        } else {
                /* user fault */
@@ -442,9 +445,12 @@ static inline void bus_error030 (struct frame *fp)
            if (!(ssw & RW) || ssw & RM)
                    errorcode |= 2;
 
-           if (mmusr & (MMU_I | MMU_WP))
-                   do_page_fault ((struct pt_regs *)fp, addr, errorcode);
-           else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
+           if (mmusr & (MMU_I | MMU_WP)) {
+               /* Don't try to do anything further if an exception was
+                  handled. */
+               if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)
+                       return;
+           } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
                    printk ("invalid %s access at %#lx from pc %#lx\n",
                            !(ssw & RW) ? "write" : "read", addr,
                            fp->ptregs.pc);
@@ -572,7 +578,7 @@ static inline void bus_error030 (struct frame *fp)
 #endif
 
        if (mmusr & MMU_I)
-               do_page_fault ((struct pt_regs *)fp, addr, 0);
+               do_page_fault (&fp->ptregs, addr, 0);
        else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
                printk ("invalid insn access at %#lx from pc %#lx\n",
                        addr, fp->ptregs.pc);
@@ -733,18 +739,18 @@ static void dump_stack(struct frame *fp)
        stack = (unsigned long *)addr;
        endstack = (unsigned long *)PAGE_ALIGN(addr);
 
-       printk("Stack from %08lx:\n       ", (unsigned long)stack);
+       printk("Stack from %08lx:", (unsigned long)stack);
        for (i = 0; i < kstack_depth_to_print; i++) {
                if (stack + 1 > endstack)
                        break;
-               if (i && ((i % 8) == 0))
+               if (i % 8 == 0)
                        printk("\n       ");
-               printk("%08lx ", *stack++);
+               printk(" %08lx", *stack++);
        }
 
-       printk ("\nCall Trace: ");
+       printk ("\nCall Trace:");
        stack = (unsigned long *) addr;
-       i = 1;
+       i = 0;
        module_start = VMALLOC_START;
        module_end = module_start + MODULE_RANGE;
        while (stack + 1 <= endstack) {
@@ -760,9 +766,9 @@ static void dump_stack(struct frame *fp)
                if (((addr >= (unsigned long) &_start) &&
                     (addr <= (unsigned long) &_etext)) ||
                    ((addr >= module_start) && (addr <= module_end))) {
-                       if (i && ((i % 8) == 0))
+                       if (i % 4 == 0)
                                printk("\n       ");
-                       printk("[<%08lx>] ", addr);
+                       printk(" [<%08lx>]", addr);
                        i++;
                }
        }
@@ -775,7 +781,7 @@ static void dump_stack(struct frame *fp)
 void bad_super_trap (struct frame *fp)
 {
        console_verbose();
-       if ((fp->ptregs.vector) < 48*4)
+       if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
                printk ("*** %s ***   FORMAT=%X\n",
                        vec_names[(fp->ptregs.vector) >> 2],
                        fp->ptregs.format);
index 8aa84de7407cc62b7a0555277a9766e9585e5a0b..786e80dd3c74083e48601a63c07721c6f9cf3163 100644 (file)
@@ -124,7 +124,7 @@ csum_partial (const unsigned char *buff, int len, unsigned int sum)
 
 
 /*
- * copy from fs while checksumming, otherwise like csum_partial
+ * copy from user space while checksumming, otherwise like csum_partial
  */
 
 unsigned int
@@ -138,7 +138,8 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
                "jgt 1f\n\t"
                "addql #2,%1\n\t"       /* len was == 2, treat only rest */
                "jra 4f\n"
-            "1:\t"
+            "1:\n"
+            "10:\t"
                "movesw %2@+,%4\n\t"    /* add first word to sum */
                "addw %4,%0\n\t"
                "movew %4,%3@+\n\t"
@@ -150,28 +151,36 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
                "lsrl #5,%1\n\t"        /* len/32 */
                "jeq 2f\n\t"            /* not enough... */
                "subql #1,%1\n"
-            "1:\t"
+            "1:\n"
+            "11:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "12:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "13:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "14:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "15:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "16:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "17:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
+            "18:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
@@ -187,8 +196,9 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
                "jeq 4f\n\t"
                "lsrw #2,%4\n\t"
                "subqw #1,%4\n"
-            "3:\t"
+            "3:\n"
                /* loop for rest longs */
+            "19:\t"
                "movesl %2@+,%5\n\t"
                "addxl %5,%0\n\t"
                "movel %5,%3@+\n\t"
@@ -202,12 +212,14 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
                "clrl %5\n\t"           /* clear tmp2 for rest bytes */
                "subqw #2,%1\n\t"
                "jlt 5f\n\t"
+            "20:\t"
                "movesw %2@+,%5\n\t"    /* have rest >= 2: get word */
                "movew %5,%3@+\n\t"
                "swap %5\n\t"           /* into bits 16..31 */
                "tstw %1\n\t"           /* another byte? */
                "jeq 6f\n"
-            "5:\t"
+            "5:\n"
+            "21:\t"
                "movesb %2@,%5\n\t"     /* have odd rest: get byte */
                "moveb %5,%3@+\n\t"
                "lslw #8,%5\n\t"        /* into bits 8..15; 16..31 untouched */
@@ -215,7 +227,21 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
                "addl %5,%0\n\t"        /* now add rest long to sum */
                "clrl %5\n\t"
                "addxl %5,%0\n"         /* add X bit */
-            "7:\t"
+            "7:\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"
+               ".text"
                : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst),
                  "=&d" (tmp1), "=&d" (tmp2)
                : "0" (sum), "1" (len), "2" (src), "3" (dst)
@@ -223,7 +249,7 @@ csum_partial_copy_fromuser(const char *src, char *dst, int len, int sum)
        return(sum);
 }
 /*
- * copy from ds while checksumming, otherwise like csum_partial
+ * copy from kernel space while checksumming, otherwise like csum_partial
  */
 
 unsigned int
index 82dc388516cd4ea7e054768175168c64bf97e0d0..be5501f50ce83587c85fdf10a86dabac426e77a0 100644 (file)
 /*
  * "down_failed" is called with the eventual return address
  * in %a0, and the address of the semaphore in %a1. We need
- * to increment the number of waiters on the semaphore,
- * call "__down()", and then eventually return to try again.
+ * to call "__down()", and then re-try until we succeed..
  */
-ENTRY(down_failed)
-       movel %a0,-(%sp)
-       movel %a1,-(%sp)
+ENTRY(__down_failed)
+       moveml %a0/%d0/%d1,-(%sp)
+1:     movel %a1,-(%sp)
        jbsr SYMBOL_NAME(__down)
        movel (%sp)+,%a1
+       subql #1,(%a1)
+       jmi 1b
+       movel (%sp)+,%d0
+       movel (%sp)+,%d1
        rts
 
-ENTRY(up_wakeup)
-       movel %a0,-(%sp)
+ENTRY(__up_wakeup)
+       moveml %a0/%d0/%d1,-(%sp)
        movel %a1,-(%sp)
        jbsr SYMBOL_NAME(__up)
        movel (%sp)+,%a1
+       movel (%sp)+,%d0
+       movel (%sp)+,%d1
        rts
index f062acd13c23952e321e84815b6c5663a875c38c..0f024224f40f414636f3821f63677e8de0d4ef81 100644 (file)
@@ -8,6 +8,6 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS  := init.o fault.o memory.o
+O_OBJS  := init.o fault.o memory.o extable.o
 
 include $(TOPDIR)/Rules.make
diff --git a/arch/m68k/mm/extable.c b/arch/m68k/mm/extable.c
new file mode 100644 (file)
index 0000000..6104120
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/m68k/mm/extable.c
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+extern const struct exception_table_entry __start___ex_table[];
+extern const struct exception_table_entry __stop___ex_table[];
+
+static inline unsigned long
+search_one_table(const struct exception_table_entry *first,
+                const struct exception_table_entry *last,
+                unsigned long value)
+{
+        while (first <= last) {
+               const struct exception_table_entry *mid;
+               long diff;
+
+               mid = (last - first) / 2 + first;
+               diff = value - mid->insn;
+               if (diff >= 0 && diff <= 2)
+                       return mid->fixup;
+               else if (diff > 0)
+                       first = mid+1;
+               else
+                       last = mid-1;
+       }
+       return 0;
+}
+
+unsigned long
+search_exception_table(unsigned long addr)
+{
+       unsigned long ret;
+#ifdef CONFIG_MODULES
+       struct module *mp;
+#endif
+
+       /* Search the kernel's table first.  */
+       ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
+       if (ret)
+               return ret;
+
+#ifdef CONFIG_MODULES
+       for (mp = module_list; mp != NULL; mp = mp->next) {
+               if (mp->exceptinfo.start != NULL) {
+                       ret = search_one_table(mp->exceptinfo.start,
+                               mp->exceptinfo.stop-1, addr);
+                       if (ret)
+                               return ret;
+               }
+       }
+#endif
+       return 0;
+}
index f39179f7d51e76d4b4ed83c235b7795284003831..9da3222089242a34c6f5d9a1519144b8e5dc00dc 100644 (file)
@@ -9,10 +9,14 @@
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 
+#include <asm/setup.h>
+#include <asm/traps.h>
 #include <asm/system.h>
+#include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
 extern void die_if_kernel(char *, struct pt_regs *, long);
+extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
 
 /*
  * This routine handles page faults.  It determines the problem, and
@@ -28,14 +32,20 @@ extern void die_if_kernel(char *, struct pt_regs *, long);
 asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
                              unsigned long error_code)
 {
-       struct vm_area_struct * vma;
+       void (*handler)(struct task_struct *,
+                       struct vm_area_struct *,
+                       unsigned long,
+                       int);
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
+       struct vm_area_struct * vma;
+       unsigned long fixup, fault_pc;
+       int write;
 
 #ifdef DEBUG
        printk ("regs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
                regs->sr, regs->pc, address, error_code,
-               tsk->tss.pagedir_v);
+               tsk->mm->pgd);
 #endif
 
        down(&mm->mmap_sem);
@@ -62,25 +72,24 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
  * we can handle it..
  */
 good_area:
-       /*
-        * was it a write?
-        */
-       if (error_code & 2) {
-         if (!(vma->vm_flags & VM_WRITE))
-           goto bad_area;
-       } else {
-               /* read with protection fault? */
-         if (error_code & 1)
-           goto bad_area;
-         if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
-           goto bad_area;
-       }
-       if (error_code & 1) {
-               do_wp_page(tsk, vma, address, error_code & 2);
-               up(&mm->mmap_sem);
-               return 0;
+       write = 0;
+       handler = do_no_page;
+       switch (error_code & 3) {
+               default:        /* 3: write, present */
+                       handler = do_wp_page;
+                       /* fall through */
+               case 2:         /* write, not present */
+                       if (!(vma->vm_flags & VM_WRITE))
+                               goto bad_area;
+                       write++;
+                       break;
+               case 1:         /* read, present */
+                       goto bad_area;
+               case 0:         /* read, not present */
+                       if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+                               goto bad_area;
        }
-       do_no_page(tsk, vma, address, error_code & 2);
+       handler(tsk, vma, address, write);
        up(&mm->mmap_sem);
 
        /* There seems to be a missing invalidate somewhere in do_no_page.
@@ -96,6 +105,26 @@ good_area:
  */
 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;
+       if ((fixup = search_exception_table(fault_pc)) != 0) {
+               struct pt_regs *tregs;
+               printk("Exception at %lx (%lx)\n", fault_pc, fixup);
+               /* Create a new four word stack frame, discarding the old
+                  one.  */
+               regs->stkadj = frame_extra_sizes[regs->format];
+               tregs = (struct pt_regs *)((ulong)regs + regs->stkadj);
+               tregs->vector = regs->vector;
+               tregs->format = 0;
+               tregs->pc = fixup;
+               tregs->sr = regs->sr;
+               return -1;
+       }
+
        if (user_mode(regs)) {
                /* User memory access */
                force_sig (SIGSEGV, tsk);
@@ -116,4 +145,3 @@ bad_area:
 
        return 1;
 }
-
index f4f6c4c3e169df74b7c0e24edce85a91c4b25fdc..3fcc2d904930972c4eb71297fe5591771b0288db 100644 (file)
@@ -17,7 +17,7 @@
 #endif
 
 #include <asm/setup.h>
-#include <asm/segment.h>
+#include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -66,7 +66,7 @@ void show_mem(void)
     printk("\nMem-info:\n");
     show_free_areas();
     printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
-    i = high_memory >> PAGE_SHIFT;
+    i = max_mapnr;
     while (i-- > 0) {
        total++;
        if (PageReserved(mem_map+i))
@@ -89,12 +89,14 @@ void show_mem(void)
 #endif
 }
 
+#ifndef mm_cachebits
 /*
  * Bits to add to page descriptors for "normal" caching mode.
  * For 68020/030 this is 0.
  * For 68040, this is _PAGE_CACHE040 (cachable, copyback)
  */
 unsigned long mm_cachebits = 0;
+#endif
 
 pte_t *kernel_page_table (unsigned long *memavailp)
 {
@@ -216,7 +218,8 @@ static unsigned long map_chunk (unsigned long addr,
                         */
                        for (i = 0; i < 64; i++) {
                                pte_val(ktablep[i]) = physaddr | _PAGE_PRESENT
-                                       | _PAGE_CACHE040 | _PAGE_GLOBAL040;
+                                       | _PAGE_CACHE040 | _PAGE_GLOBAL040
+                                       | _PAGE_ACCESSED;
                                physaddr += PAGE_SIZE;
                        }
                        ktablep += 64;
@@ -227,7 +230,7 @@ static unsigned long map_chunk (unsigned long addr,
                         * 64 entry section of the page table.
                         */
 
-                       kpointerp[pindex++] = ktable | _PAGE_TABLE;
+                       kpointerp[pindex++] = ktable | _PAGE_TABLE | _PAGE_ACCESSED;
                } else {
                        /*
                         * 68030, use early termination page descriptors.
@@ -247,16 +250,16 @@ static unsigned long map_chunk (unsigned long addr,
                                
                                tbl = (unsigned long *)get_kpointer_table();
 
-                               kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE;
+                               kpointerp[pindex++] = VTOP(tbl) | _PAGE_TABLE |_PAGE_ACCESSED;
 
                                for (i = 0; i < 64; i++, physaddr += PAGE_SIZE)
-                                       tbl[i] = physaddr | _PAGE_PRESENT;
+                                       tbl[i] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
                                
                                /* unmap the zero page */
                                tbl[0] = 0;
                        } else {
                                /* not the first 256K */
-                               kpointerp[pindex++] = physaddr | _PAGE_PRESENT;
+                               kpointerp[pindex++] = physaddr | _PAGE_PRESENT | _PAGE_ACCESSED;
 #ifdef DEBUG
                                printk ("%lx=%lx ", VTOP(&kpointerp[pindex-1]),
                                        kpointerp[pindex-1]);
@@ -302,7 +305,9 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        /* Fix the cache mode in the page descriptors for the 680[46]0.  */
        if (CPU_IS_040_OR_060) {
                int i;
+#ifndef mm_cachebits
                mm_cachebits = _PAGE_CACHE040;
+#endif
                for (i = 0; i < 16; i++)
                        pgprot_val(protection_map[i]) |= _PAGE_CACHE040;
        }
@@ -358,18 +363,16 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
 #endif
 
        memset (swapper_pg_dir, 0, sizeof(pgd_t)*PTRS_PER_PGD);
-       task[0]->tss.pagedir_v = (unsigned long *)swapper_pg_dir;
-       task[0]->tss.pagedir_p = VTOP (swapper_pg_dir);
+
+       /* setup CPU root pointer for swapper task */
+       task[0]->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+       task[0]->tss.crp[1] = VTOP (swapper_pg_dir);
 
 #ifdef DEBUG
        printk ("task 0 pagedir at %p virt, %#lx phys\n",
-               task[0]->tss.pagedir_v, task[0]->tss.pagedir_p);
+               swapper_pg_dir, task[0]->tss.crp[1]);
 #endif
 
-       /* setup CPU root pointer for swapper task */
-       task[0]->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
-       task[0]->tss.crp[1] = task[0]->tss.pagedir_p;
-
        if (CPU_IS_040_OR_060)
                asm __volatile__ ("movel %0,%/d0\n\t"
                                  ".long 0x4e7b0806" /* movec d0,urp */
@@ -406,10 +409,11 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
        extern int _etext;
 
        end_mem &= PAGE_MASK;
-       high_memory = end_mem;
+       high_memory = (void *) end_mem;
+       max_mapnr = MAP_NR(end_mem);
 
        start_mem = PAGE_ALIGN(start_mem);
-       while (start_mem < high_memory) {
+       while (start_mem < end_mem) {
                clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
                start_mem += PAGE_SIZE;
        }
@@ -444,9 +448,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
                }
        }
        
-#endif
-#ifdef DEBUG
-       printk ("task[0] root table is %p\n", task[0]->tss.pagedir_v);
 #endif
 
        for (tmp = 0 ; tmp < end_mem ; tmp += PAGE_SIZE) {
@@ -466,10 +467,9 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
 #endif
                        free_page(tmp);
        }
-       tmp = nr_free_pages << PAGE_SHIFT;
        printk("Memory: %luk/%luk available (%dk kernel code, %dk data)\n",
-              tmp >> 10,
-              high_memory >> 10,
+              (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+              max_mapnr << (PAGE_SHIFT-10),
               codepages << (PAGE_SHIFT-10),
               datapages << (PAGE_SHIFT-10));
 }
@@ -478,7 +478,7 @@ void si_meminfo(struct sysinfo *val)
 {
     unsigned long i;
 
-    i = high_memory >> PAGE_SHIFT;
+    i = max_mapnr;
     val->totalram = 0;
     val->sharedram = 0;
     val->freeram = nr_free_pages << PAGE_SHIFT;
index b72ccb0ec338be6124b4f5635c768b5bb0a326e6..113436136089e5c3abaa74dcf5b07b3198451b86 100644 (file)
@@ -9,14 +9,3 @@ All:           dmesg
 dmesg:         dmesg.c
                $(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
 
-
-CC =           m68k-cbm-amigados-gcc
-CFLAGS =       -Wall -O2
-
-
-All:           dmesg
-
-
-dmesg:         dmesg.c
-               $(CC) $(CFLAGS) -o dmesg dmesg.c -noixemul
-
index bda7e8f66a571487d7dc177494cb69a72981d6ce..7ddbede36348979e53621d4eed4cf5e06d10281d 100644 (file)
@@ -75,7 +75,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
        sti();
        ide_fix_driveid(id);
 
-#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO)
+#if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA)
        /*
         * EATA SCSI controllers do a hardware ATA emulation:
         * Ignore them if there is a driver for them available.
index dfbe6f31f2ddb90f7be7dd65e59c5df22ad24304..6fc6960aafd6d03e058a2adb939f9b219992a2ff 100644 (file)
 #include <linux/module.h>
 
 #include <linux/md.h>
-#include <linux/linear.h>
 #include <linux/malloc.h>
 
+#include "linear.h"
+
 #define MAJOR_NR MD_MAJOR
 #define MD_DRIVER
 #define MD_PERSONALITY
diff --git a/drivers/block/linear.h b/drivers/block/linear.h
new file mode 100644 (file)
index 0000000..1146d83
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct linear_hash
+{
+  struct real_dev *dev0, *dev1;
+};
+
+struct linear_data
+{
+  struct linear_hash *hash_table; /* Dynamically allocated */
+  struct real_dev *smallest;
+  int nr_zones;
+};
+
+#endif
index dddceff15bd70c4cb3dd01a6eacb1461ec781250..b38e8eac606ce2cebc85f98b8528e17be6a7f3a7 100644 (file)
@@ -196,14 +196,6 @@ else
   endif
 endif
   
-ifeq ($(CONFIG_BAYCOM),y)
-L_OBJS += baycom.o
-else
-  ifeq ($(CONFIG_BAYCOM),m)
-  M_OBJS += baycom.o
-  endif
-endif  
-
 ifdef CONFIG_TGA_CONSOLE
 L_OBJS += tga.o
 else
index cb88e4dd734c77379f05e5fb7ca69ed8993d0069..ad0c83af5fde4bdf8298fac18b2c472214588497 100644 (file)
@@ -1002,7 +1002,8 @@ tulip_rx(struct device *dev)
                        if (status & TRING_RxFIFO) lp->stats.rx_fifo_errors++;
                } else {
                        /* Malloc up new buffer, compatible with net-2e. */
-                       short pkt_len = lp->rx_ring[entry].status >> 16;
+                       /* Omit the four octet CRC from the length. */
+                       short pkt_len = (lp->rx_ring[entry].status >> 16) - 4;
                        struct sk_buff *skb;
 
                        skb = dev_alloc_skb(pkt_len + 2);
index 6f8c0d2ea920cdb78381a25e1f43b40a5f34c84f..149be377582134fe9a8a6ee0fc56a6e83e1276a4 100644 (file)
@@ -211,6 +211,8 @@ struct pci_dev_info dev_info[] = {
        DEVICE( AVANCE,         AVANCE_2302,    "ALG-2302"),
        DEVICE( S3,             S3_ViRGE,       "ViRGE"),
        DEVICE( S3,             S3_TRIO,        "Trio32/Trio64"),
+       DEVICE( S3,             S3_AURORA64VP,  "Aurora64V+"),
+       DEVICE( S3,             S3_TRIO64UVP,   "Trio64UV+"),
        DEVICE( S3,             S3_ViRGE_VX,    "ViRGE/VX"),
        DEVICE( S3,             S3_868, "Vision 868"),
        DEVICE( S3,             S3_928,         "Vision 928-P"),
index fba1ef26809a28e0e964e42a7a80b43c5c3c9dfd..366f50398b5412bb29084a89543c7521182a0790 100644 (file)
@@ -29,7 +29,7 @@ dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI
 dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
 dep_tristate 'EATA-DMA (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support' CONFIG_SCSI_EATA_DMA $CONFIG_SCSI
 dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO $CONFIG_SCSI
-dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA $CONFIG_SCSI
+dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
 dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN $CONFIG_SCSI
 dep_tristate 'Generic NCR5380/53c400 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 $CONFIG_SCSI
 if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
index 43e881a1ea0023b9b25268428f8f9962fdbffc24..83806bdb3800d2b255da044b55cae754e72a294a 100644 (file)
@@ -1,6 +1,9 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ *          Added support for EATA 2.0C, PCI, multichannel and wide SCSI.
+ *
  *      27 Sep 1996 rev. 2.12 for linux 2.1.0
  *          Portability cleanups (virtual/bus addressing, little/big endian
  *          support).
@@ -82,7 +85,8 @@
  *
  *  Here is a brief description of the DPT SCSI host adapters.
  *  All these boards provide an EATA/DMA compatible programming interface
- *  and are fully supported by this driver:
+ *  and are fully supported by this driver in any configuration, including
+ *  multiple SCSI channels:
  *
  *  PM2011B/9X -  Entry Level ISA
  *  PM2021A/9X -  High Performance ISA
  *  PM2022A/9X -  Entry Level EISA
  *  PM2122A/9X -  High Performance EISA
  *  PM2322A/9X -  Extra High Performance EISA
+ *  PM3021     -  SmartRAID Adapter for ISA
+ *  PM3222     -  SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI)
+ *  PM3224     -  SmartRAID Adapter for PCI  (PM3224W is 16-bit wide SCSI)
  *
  *  The DPT PM2001 provides only the EATA/PIO interface and hence is not
  *  supported by this driver.
  *
  *  This code has been tested with up to 3 Distributed Processing Technology 
  *  PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) eisa controllers,
- *  no on board cache and no RAID option. 
- *  BIOS must be enabled on the first board and must be disabled for all other 
- *  boards. 
- *  Support is provided for any number of DPT PM2122 eisa boards.
- *  All boards should be configured at the same IRQ level.
- *  Multiple IRQ configurations are supported too.
- *  Boards can be located in any eisa slot (1-15) and are named EATA0, 
- *  EATA1,... in increasing eisa slot number. ISA boards are detected
- *  after the eisa slot probes.
+ *  in any combination of private and shared IRQ.
+ *  PCI support has been tested using a DPT PM3224W (firmware v07G.0).
+ *
+ *  Multiple ISA, EISA and PCI boards can be configured in the same system.
+ *  It is suggested to put all the EISA boards on the same IRQ level, all
+ *  the PCI  boards on another IRQ level, while ISA boards cannot share 
+ *  interrupts.
  *
- *  The IRQ for EISA boards should be _level_ triggered (not _edge_ triggered).
- *  This is a requirement in order to support multiple boards on the same IRQ.
+ *  If you configure multiple boards on the same IRQ, the interrupt must
+ *  be _level_ triggered (not _edge_ triggered).
  *
- *  Other eisa configuration parameters are:
+ *  This driver detects EATA boards by probes at fixed port addresses,
+ *  so no BIOS32 or PCI BIOS support is used or required.
+ *  The suggested way to detect a generic EATA PCI board is to force on it
+ *  any unused EISA address, even if there are other controllers on the EISA
+ *  bus, or even if you system has no EISA bus at all.
+ *  Do not force any ISA address on EATA PCI boards.
  *
- *  COMMAND QUEUING   : ENABLED
- *  COMMAND TIMEOUT   : ENABLED
- *  CACHE             : DISABLED
+ *  The sequence of detection probes is:
+ *  - ISA 0x1F0; 
+ *  - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15);
+ *  - ISA  0x170, 0x230, 0x330.
+ *
+ *  The boards are named EATA0, EATA1,... according to the detection order.
  *
  *  In order to support multiple ISA boards in a reliable way,
  *  the driver sets host->wish_block = TRUE for all ISA boards.
@@ -159,11 +172,14 @@ struct proc_dir_entry proc_scsi_eata2x = {
 #undef  DEBUG_STATISTICS
 #undef  DEBUG_RESET
 
-#define MAX_TARGET 8
+#define MAX_CHANNEL 4
+#define MAX_LUN 32
+#define MAX_TARGET 32
 #define MAX_IRQ 16
 #define MAX_BOARDS 18
 #define MAX_MAILBOXES 64
 #define MAX_SGLIST 64
+#define MAX_LARGE_SGLIST 252
 #define MAX_INTERNAL_RETRIES 64
 #define MAX_CMD_PER_LUN 2
 
@@ -189,7 +205,7 @@ struct proc_dir_entry proc_scsi_eata2x = {
 #define REG_MID         4
 #define REG_MSB         5
 #define REGION_SIZE     9
-#define EISA_RANGE      0xf000
+#define EISA_RANGE      0x1000
 #define BSY_ASSERTED      0x80
 #define DRQ_ASSERTED      0x08
 #define ABSY_ASSERTED     0x01
@@ -214,6 +230,7 @@ struct proc_dir_entry proc_scsi_eata2x = {
 /* Number of valid bytes in the board config structure for EATA 2.0x */
 #define EATA_2_0A_SIZE 28
 #define EATA_2_0B_SIZE 30
+#define EATA_2_0C_SIZE 34
 
 /* Board info structure */
 struct eata_info {
@@ -229,8 +246,7 @@ struct eata_info {
              ata:1,    /* This is an ATA device */
           haaval:1;    /* Host Adapter Address Valid */
    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
-   unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
-   unchar reserved;
+   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */
    ulong  cp_len;       /* Number of valid bytes in cp */
    ulong  sp_len;       /* Number of valid bytes in sp */
    ushort queue_size;   /* Max number of cp that can be queued */
@@ -246,10 +262,14 @@ struct eata_info {
    unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
         forcaddr:1,    /* Port address has been forced */
                 :6;
-   unchar  max_id:5,    /* Max number of SCSI target IDs */
+   unchar  max_id:5,    /* Max SCSI target ID number */
         max_chan:3;    /* Max SCSI channel number on this board */
 
-   ushort ipad[249];
+   /* Structure extension defined in EATA 2.0C */
+   unchar   max_lun;    /* Max SCSI LUN number */
+   unchar   notused[3];
+
+   ushort ipad[247];
    };
 
 /* Board config structure */
@@ -288,9 +308,9 @@ struct mscp {
    unchar unused[4];
    unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
          notused:7;
-   unchar target;        /* SCSI Target ID */
-   unchar     lun:3,     /* LUN */
-                :2,
+   unchar  target:5,     /* SCSI target ID */
+          channel:3;     /* SCSI channel number */
+   unchar     lun:5,     /* SCSI logical unit number */
           luntar:1,     /* This cp is for Target (not LUN) */
           dispri:1,     /* Disconnect Privilege granted */
              one:1;     /* 1 */
@@ -320,17 +340,17 @@ struct hostdata {
    char board_name[16];                 /* Name of this board */
    char board_id[256];                  /* data from INQUIRY on this board */
    int in_reset;                        /* True if board is doing a reset */
-   int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
-   int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
+   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
    unsigned int retries;                /* Number of internal retries */
    unsigned long last_retried_pid;      /* Pid of last retried command */
-   unsigned char subversion;            /* Bus type, either ISA or ESA */
+   unsigned char subversion;            /* Bus type, either ISA or EISA/PCI */
    unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
    struct mssp sp[MAX_MAILBOXES];       /* Returned status for this board */
    };
 
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const chardriver_name = "EATA";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "EATA";
 static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
@@ -344,7 +364,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 static void eata2x_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
    unsigned int loop = MAXLOOP;
 
    while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED)
@@ -353,7 +373,7 @@ static inline unchar wait_on_busy(ushort iobase) {
    return FALSE;
 }
 
-static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
+static inline int do_dma(unsigned int iobase, unsigned int addr, unchar cmd) {
 
    if (wait_on_busy(iobase)) return TRUE;
 
@@ -368,7 +388,7 @@ static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
    return FALSE;
 }
 
-static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
+static inline int read_pio(unsigned int iobase, ushort *start, ushort *end) {
    unsigned int loop = MAXLOOP;
    ushort *p;
 
@@ -384,12 +404,11 @@ static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
    return FALSE;
 }
 
-static inline int port_detect(ushort *port_base, unsigned int j, 
-                             Scsi_Host_Template * tpnt) {
-   unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j, 
+                             Scsi_Host_Template *tpnt) {
+   unsigned char irq, dma_channel, subversion, c;
    unsigned char protocol_rev;
    struct eata_info info;
-   const char *board_status;
 
    /* Allowed DMA channels for ISA (0 indicates reserved) */
    unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
@@ -425,15 +444,12 @@ static inline int port_detect(ushort *port_base, unsigned int j,
    else
       protocol_rev = 'C';
 
-   if (protocol_rev != 'A' && info.max_chan > 0)
-      printk("%s: warning, only scsi channel 0 is supported.\n", name);
-
    irq = info.irq;
 
-   if (*port_base & EISA_RANGE) {
+   if (*port_base >= EISA_RANGE) {
 
       if (!info.haaval || info.ata || info.drqvld) {
-        printk("%s: unusable EISA board found (%d%d%d), detaching.\n", 
+        printk("%s: unusable EISA/PCI board found (%d%d%d), detaching.\n", 
                name, info.haaval, info.ata, info.drqvld);
         return FALSE;
         }
@@ -460,11 +476,6 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
             name, irq);
 
-   if (info.second)
-      board_status = "Sec.";
-   else
-      board_status = "Prim.";
-
    /* Board detected, allocate its IRQ if not already done */
    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
        (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) {
@@ -508,6 +519,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       }
 
    sh[j]->io_port = *port_base;
+   sh[j]->unique_id = *port_base;
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->dma_channel = dma_channel;
    sh[j]->irq = irq;
@@ -536,11 +548,20 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       enable_dma(dma_channel);
       }
 
+   if (protocol_rev != 'A' && info.max_chan > 0 && info.max_chan < MAX_CHANNEL)
+      sh[j]->max_channel = info.max_chan;
+
+   if (protocol_rev != 'A' && info.max_id > 7 && info.max_id < MAX_TARGET)
+      sh[j]->max_id = info.max_id + 1;
+
+   if (protocol_rev == 'C' && info.max_lun > 7 && info.max_lun < MAX_LUN)
+      sh[j]->max_lun = info.max_lun + 1;
+
    strcpy(BN(j), name);
 
-   printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
-         "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status, 
-          sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
+   printk("%s: rev. 2.0%c, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
+         "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev,
+          sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
           sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
 
    /* DPT PM2012 does not allow to detect sg_tablesize correctly */
@@ -555,30 +576,38 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       sh[j]->can_queue = MAX_MAILBOXES;
       }
 
+   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+             BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+             BN(j), c, info.host_addr[3 - c]);
+
 #if defined (DEBUG_DETECT)
    if (protocol_rev != 'A')
       printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
-            " max_chan %u.\n", name, protocol_rev, info.isaena, 
-            info.forcaddr, info.max_id, info.max_chan);
+            " max_chan %u, max_lun %u.\n", name, protocol_rev, info.isaena, 
+            info.forcaddr, info.max_id, info.max_chan, info.max_lun);
 
-   printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n", 
-         name, info.version, info.sync, DEV2H(info.data_len), 
+   printk("%s: Vers. 0x%x, SYNC 0x%x, sec. %u, infol %ld, cpl %ld spl %ld.\n", 
+         name, info.version, info.sync, info.second, DEV2H(info.data_len), 
          DEV2H(info.cp_len), DEV2H(info.sp_len));
 #endif
 
    return TRUE;
 }
 
-int eata2x_detect (Scsi_Host_Template * tpnt) {
+int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k, flags;
 
-   ushort io_port[] = { 
-      0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
-      0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, 
-      0x1f0,  0x170,  0x330,  0x230,  0x0
+   unsigned int io_port[] = { 
+      0x1f0,  0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88,
+      0x8c88, 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, 
+      0x170,  0x230,  0x330,  0x0
       };
 
-   ushort *port_base = io_port;
+   unsigned int *port_base = io_port;
 
    tpnt->proc_dir = &proc_scsi_eata2x;
 
@@ -608,7 +637,7 @@ int eata2x_detect (Scsi_Host_Template * tpnt) {
 
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k;
-   struct scatterlist * sgpnt;
+   struct scatterlist *sgpnt;
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 
@@ -621,7 +650,7 @@ static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));
 }
 
-int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
+int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    unsigned int i, j, k, flags;
    struct mscp *cpp;
    struct mssp *spp;
@@ -687,8 +716,9 @@ int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    cpp->index = i;
    SCpnt->host_scribble = (unsigned char *) &cpp->index;
 
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
-                       BN(j), i, SCpnt->target, SCpnt->pid);
+   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+                       BN(j), i, SCpnt->channel, SCpnt->target,
+                        SCpnt->lun, SCpnt->pid);
 
    for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
@@ -700,6 +730,7 @@ int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    cpp->reqsen = TRUE;
    cpp->dispri = TRUE;
    cpp->one = TRUE;
+   cpp->channel = SCpnt->channel;
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;  
    cpp->SCpnt = SCpnt;
@@ -721,8 +752,9 @@ int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
       SCpnt->result = DID_ERROR << 16; 
       SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
-            BN(j), SCpnt->target, SCpnt->pid);
+      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+             " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+             SCpnt->pid);
       restore_flags(flags);
       done(SCpnt);    
       return 0;
@@ -733,7 +765,7 @@ int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    return 0;
 }
 
-int eata2x_abort (Scsi_Cmnd *SCarg) {
+int eata2x_abort(Scsi_Cmnd *SCarg) {
    unsigned int i, j, flags;
 
    save_flags(flags);
@@ -741,15 +773,15 @@ int eata2x_abort (Scsi_Cmnd *SCarg) {
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d, pid %ld inactive.\n",
-            BN(j), SCarg->target, SCarg->pid);
+      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+            BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
       restore_flags(flags);
       return SCSI_ABORT_NOT_RUNNING;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d, pid %ld.\n", 
-         BN(j), i, SCarg->target, SCarg->pid);
+   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n", 
+         BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -792,16 +824,17 @@ int eata2x_abort (Scsi_Cmnd *SCarg) {
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) {
-   unsigned int i, j, flags, time, k, limit = 0;
+int eata2x_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+   unsigned int i, j, flags, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
    save_flags(flags);
    cli();
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", 
-         BN(j), SCarg->target, SCarg->pid, reset_flags);
+   printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n", 
+         BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+          reset_flags);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -820,9 +853,11 @@ int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) {
 
    HD(j)->retries = 0;
 
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      for (k = 0; k < sh[j]->max_id; k++) {
+         HD(j)->target_redo[k][c] = TRUE;
+         HD(j)->target_to[k][c] = 0;
+         }
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
@@ -906,9 +941,10 @@ int eata2x_reset (Scsi_Cmnd *SCarg, unsigned int reset_flags) {
       }
 }
 
-static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void eata2x_interrupt_handler(int irq, void *dev_id,
+                                     struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
-   unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+   unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
    struct mssp *spp;
    struct mscp *cpp;
 
@@ -1001,9 +1037,8 @@ static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * reg
                     status = DID_ERROR << 16;
    
                  /* If there was a bus reset, redo operation on each target */
-                 else if (tstatus != GOOD
-                          && SCpnt->device->type == TYPE_DISK
-                          && HD(j)->target_reset[SCpnt->target])
+                 else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+                          && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
                     status = DID_BUS_BUSY << 16;
    
                  /* Works around a flaw in scsi.c */
@@ -1016,15 +1051,16 @@ static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * reg
                     status = DID_OK << 16;
    
                  if (tstatus == GOOD)
-                    HD(j)->target_reset[SCpnt->target] = FALSE;
+                    HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
    
                  if (spp->target_status && SCpnt->device->type == TYPE_DISK)
-                    printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
-                           "0x%x, sense key 0x%x.\n", BN(j), 
-                           SCpnt->target, SCpnt->lun, SCpnt->pid,
-                           spp->target_status, SCpnt->sense_buffer[2]);
+                    printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+                            "target_status 0x%x, sense key 0x%x.\n", BN(j), 
+                           SCpnt->channel, SCpnt->target, SCpnt->lun, 
+                            SCpnt->pid, spp->target_status, 
+                            SCpnt->sense_buffer[2]);
    
-                 HD(j)->target_time_out[SCpnt->target] = 0;
+                 HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
    
                   if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
@@ -1032,11 +1068,11 @@ static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * reg
               case ASST:     /* Selection Time Out */
               case 0x02:     /* Command Time Out   */
    
-                 if (HD(j)->target_time_out[SCpnt->target] > 1)
+                 if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
                     status = DID_ERROR << 16;
                  else {
                     status = DID_TIME_OUT << 16;
-                    HD(j)->target_time_out[SCpnt->target]++;
+                    HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
                     }
    
                  break;
@@ -1045,8 +1081,9 @@ static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * reg
               case 0x03:     /* SCSI Bus Reset Received */
               case 0x04:     /* Initial Controller Power-up */
    
-                 for (k = 0; k < MAX_TARGET; k++) 
-                    HD(j)->target_reset[k] = TRUE;
+                 for (c = 0; c <= sh[j]->max_channel; c++) 
+                    for (k = 0; k < sh[j]->max_id; k++) 
+                       HD(j)->target_redo[k][c] = TRUE;
    
                  if (SCpnt->device->type != TYPE_TAPE
                       && HD(j)->retries < MAX_INTERNAL_RETRIES) {
@@ -1085,9 +1122,10 @@ static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * reg
                do_trace)
 #endif
               printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-                     " target %d:%d, pid %ld, count %d.\n",
+                     " target %d.%d:%d, pid %ld, count %d.\n",
                      BN(j), i, spp->adapter_status, spp->target_status,
-                     SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+                     SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+                      HD(j)->iocount);
    
            /* Set the command state to inactive */
            SCpnt->host_scribble = NULL;
index 2165632959b6d0323f55c4b6cb9c52882913af2a..0edcb31d4c5ba94ec53e5f4ecf3700b687ece74a 100644 (file)
@@ -11,7 +11,7 @@ int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int eata2x_abort(Scsi_Cmnd *);
 int eata2x_reset(Scsi_Cmnd *, unsigned int);
 
-#define EATA_VERSION "2.12.00"
+#define EATA_VERSION "2.20.00"
 
 
 #define EATA {                                                 \
index 223edd692fed47a4a883e29cef452d1fe25499b1..df9cb1b02ee20118f4d011618af92dd5def13de2 100644 (file)
@@ -386,14 +386,15 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
        blocks--;
     }
 
+    if (blocks) {
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: EXTRA: Waiting for buffer\n");
+       printk("53C400r: EXTRA: Waiting for buffer\n");
 #endif
-    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
-       ;
+       while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
+           ;
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
-    printk("53C400r: Transferring EXTRA 128 bytes\n");
+       printk("53C400r: Transferring EXTRA 128 bytes\n");
 #endif
 #ifdef CONFIG_SCSI_G_NCR5380_PORT
        for (i=0; i<128; i++)
@@ -402,8 +403,13 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
 #endif
-    start+=128;
-    blocks--;
+       start+=128;
+       blocks--;
+    }
+#if (NDEBUG & NDEBUG_C400_PREAD)
+    else
+       printk("53C400r: No EXTRA required\n");
+#endif
 
 #if (NDEBUG & NDEBUG_C400_PREAD)
     printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
index 73c54d4bfa7ab6c72fc4fa265bb824d231d3f09f..8734506a3de6c6039e6864c46f291141dcbdf881 100644 (file)
@@ -246,17 +246,22 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        
     case CDROMPLAYMSF:
     {
-       struct cdrom_msf* msf = (struct cdrom_msf*)arg;
+       struct cdrom_msf msf;
+
+       if (copy_from_user(&msf, (void *) arg, sizeof(msf))) {
+               result = -EFAULT;
+               break;
+       }
 
        sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = 0;
-       sr_cmd[3] = msf->cdmsf_min0;
-       sr_cmd[4] = msf->cdmsf_sec0;
-       sr_cmd[5] = msf->cdmsf_frame0;
-       sr_cmd[6] = msf->cdmsf_min1;
-       sr_cmd[7] = msf->cdmsf_sec1;
-       sr_cmd[8] = msf->cdmsf_frame1;
+       sr_cmd[3] = msf.cdmsf_min0;
+       sr_cmd[4] = msf.cdmsf_sec0;
+       sr_cmd[5] = msf.cdmsf_frame0;
+       sr_cmd[6] = msf.cdmsf_min1;
+       sr_cmd[7] = msf.cdmsf_sec1;
+       sr_cmd[8] = msf.cdmsf_frame1;
        sr_cmd[9] = 0;
        
        result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -265,17 +270,22 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
 
     case CDROMPLAYBLK:
     {
-       struct cdrom_blk* blk = (struct cdrom_blk*)arg;
+       struct cdrom_blk blk;
+
+       if (copy_from_user(&blk, (void *) arg, sizeof(blk))) {
+               result = -EFAULT;
+               break;
+       }
 
        sr_cmd[0] = SCMD_PLAYAUDIO10;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
-       sr_cmd[2] = blk->from >> 24;
-       sr_cmd[3] = blk->from >> 16;
-       sr_cmd[4] = blk->from >> 8;
-       sr_cmd[5] = blk->from;
+       sr_cmd[2] = blk.from >> 24;
+       sr_cmd[3] = blk.from >> 16;
+       sr_cmd[4] = blk.from >> 8;
+       sr_cmd[5] = blk.from;
        sr_cmd[6] = 0;
-       sr_cmd[7] = blk->len >> 8;
-       sr_cmd[8] = blk->len;
+       sr_cmd[7] = blk.len >> 8;
+       sr_cmd[8] = blk.len;
        sr_cmd[9] = 0;
        
        result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -284,17 +294,22 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
                
     case CDROMPLAYTRKIND:
     {
-       struct cdrom_ti* ti = (struct cdrom_ti*)arg;
+       struct cdrom_ti ti;
+
+       if (copy_from_user(&ti, (void *) arg, sizeof(ti))) {
+               result = -EFAULT;
+               break;
+       }
 
        sr_cmd[0] = SCMD_PLAYAUDIO_TI;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = 0;
        sr_cmd[3] = 0;
-       sr_cmd[4] = ti->cdti_trk0;
-       sr_cmd[5] = ti->cdti_ind0;
+       sr_cmd[4] = ti.cdti_trk0;
+       sr_cmd[5] = ti.cdti_ind0;
        sr_cmd[6] = 0;
-       sr_cmd[7] = ti->cdti_trk1;
-       sr_cmd[8] = ti->cdti_ind1;
+       sr_cmd[7] = ti.cdti_trk1;
+       sr_cmd[8] = ti.cdti_ind1;
        sr_cmd[9] = 0;
        
        result = sr_do_ioctl(target, sr_cmd, NULL, 255);
@@ -303,7 +318,7 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        
     case CDROMREADTOCHDR:
     {
-       struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
+       struct cdrom_tochdr tochdr;
        char * buffer;
        
        sr_cmd[0] = SCMD_READ_TOC;
@@ -319,23 +334,31 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        
        result = sr_do_ioctl(target, sr_cmd, buffer, 12);
        
-       tochdr->cdth_trk0 = buffer[2];
-       tochdr->cdth_trk1 = buffer[3];
+       tochdr.cdth_trk0 = buffer[2];
+       tochdr.cdth_trk1 = buffer[3];
        
        scsi_free(buffer, 512);
+
+       if (copy_to_user ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr)))
+               result = -EFAULT;
         break;
     }
        
     case CDROMREADTOCENTRY:
     {
-       struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
+       struct cdrom_tocentry tocentry;
        unsigned char * buffer;
        
+       if (copy_from_user (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry))) {
+               result = -EFAULT;
+               break;
+       }
+
        sr_cmd[0] = SCMD_READ_TOC;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |
-          (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
+          (tocentry.cdte_format == CDROM_MSF ? 0x02 : 0);
        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
-       sr_cmd[6] = tocentry->cdte_track;
+       sr_cmd[6] = tocentry.cdte_track;
        sr_cmd[7] = 0;             /* MSB of length (12)  */
        sr_cmd[8] = 12;            /* LSB of length */
        sr_cmd[9] = 0;
@@ -345,18 +368,21 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        
        result = sr_do_ioctl (target, sr_cmd, buffer, 12);
        
-        tocentry->cdte_ctrl = buffer[5] & 0xf; 
-        tocentry->cdte_adr = buffer[5] >> 4;
-        tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
-       if (tocentry->cdte_format == CDROM_MSF) {
-           tocentry->cdte_addr.msf.minute = buffer[9];
-           tocentry->cdte_addr.msf.second = buffer[10];
-           tocentry->cdte_addr.msf.frame = buffer[11];
+        tocentry.cdte_ctrl = buffer[5] & 0xf;  
+        tocentry.cdte_adr = buffer[5] >> 4;
+        tocentry.cdte_datamode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0;
+       if (tocentry.cdte_format == CDROM_MSF) {
+           tocentry.cdte_addr.msf.minute = buffer[9];
+           tocentry.cdte_addr.msf.second = buffer[10];
+           tocentry.cdte_addr.msf.frame = buffer[11];
        } else
-           tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
+           tocentry.cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
                                        + buffer[10]) << 8) + buffer[11];
        
        scsi_free(buffer, 512);
+
+       if (copy_to_user ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry)))
+               result = -EFAULT;
         break;
     }
        
@@ -381,8 +407,13 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
     case CDROMVOLCTRL:
     {
        char * buffer, * mask;
-       struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+       struct cdrom_volctrl volctrl;
        
+       if (copy_from_user (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl))) {
+               result = -EFAULT;
+               break;
+       }
+
        /* First we get the current params so we can just twiddle the volume */
        
        sr_cmd[0] = MODE_SENSE;
@@ -425,10 +456,10 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        /* Now mask and substitute our own volume and reuse the rest */
        buffer[0] = 0;  /* Clear reserved field */
        
-       buffer[21] = volctrl->channel0 & mask[21];
-       buffer[23] = volctrl->channel1 & mask[23];
-       buffer[25] = volctrl->channel2 & mask[25];
-       buffer[27] = volctrl->channel3 & mask[27];
+       buffer[21] = volctrl.channel0 & mask[21];
+       buffer[23] = volctrl.channel1 & mask[23];
+       buffer[25] = volctrl.channel2 & mask[25];
+       buffer[27] = volctrl.channel3 & mask[27];
        
        sr_cmd[0] = MODE_SELECT;
        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;    /* Params are SCSI-2 */
@@ -445,7 +476,7 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
     case CDROMVOLREAD:
     {
        char * buffer;
-       struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+       struct cdrom_volctrl volctrl;
        
        /* Get the current params */
        
@@ -465,18 +496,21 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
             break;
        }
 
-       volctrl->channel0 = buffer[21];
-       volctrl->channel1 = buffer[23];
-       volctrl->channel2 = buffer[25];
-       volctrl->channel3 = buffer[27];
+       volctrl.channel0 = buffer[21];
+       volctrl.channel1 = buffer[23];
+       volctrl.channel2 = buffer[25];
+       volctrl.channel3 = buffer[27];
 
        scsi_free(buffer, 512);
+
+       if (copy_to_user ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl)))
+               result = -EFAULT;
         break;
     }
        
     case CDROMSUBCHNL:
     {
-       struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
+       struct cdrom_subchnl subchnl;
        char * buffer;
        
        sr_cmd[0] = SCMD_READ_SUBCHANNEL;
@@ -494,20 +528,23 @@ int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
        
        result = sr_do_ioctl(target, sr_cmd, buffer, 16);
        
-       subchnl->cdsc_audiostatus = buffer[1];
-       subchnl->cdsc_format = CDROM_MSF;
-       subchnl->cdsc_ctrl = buffer[5] & 0xf;
-       subchnl->cdsc_trk = buffer[6];
-       subchnl->cdsc_ind = buffer[7];
+       subchnl.cdsc_audiostatus = buffer[1];
+       subchnl.cdsc_format = CDROM_MSF;
+       subchnl.cdsc_ctrl = buffer[5] & 0xf;
+       subchnl.cdsc_trk = buffer[6];
+       subchnl.cdsc_ind = buffer[7];
        
-       subchnl->cdsc_reladdr.msf.minute = buffer[13];
-       subchnl->cdsc_reladdr.msf.second = buffer[14];
-       subchnl->cdsc_reladdr.msf.frame = buffer[15];
-       subchnl->cdsc_absaddr.msf.minute = buffer[9];
-       subchnl->cdsc_absaddr.msf.second = buffer[10];
-       subchnl->cdsc_absaddr.msf.frame = buffer[11];
+       subchnl.cdsc_reladdr.msf.minute = buffer[13];
+       subchnl.cdsc_reladdr.msf.second = buffer[14];
+       subchnl.cdsc_reladdr.msf.frame = buffer[15];
+       subchnl.cdsc_absaddr.msf.minute = buffer[9];
+       subchnl.cdsc_absaddr.msf.second = buffer[10];
+       subchnl.cdsc_absaddr.msf.frame = buffer[11];
        
        scsi_free(buffer, 512);
+
+       if (copy_to_user ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)))
+               result = -EFAULT;
         break;
     }
     default:
index a1f19d7a8673193dbabd56411c08dc460a15d2b5..60a7b8b166fff70f095b2cd58687208898d726f3 100644 (file)
@@ -1,6 +1,9 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25
+ *          Added multichannel support.
+ *
  *      27 Sep 1996 rev. 2.12 for linux 2.1.0
  *          Portability cleanups (virtual/bus addressing, little/big endian
  *          support).
@@ -202,6 +205,8 @@ struct proc_dir_entry proc_scsi_u14_34f = {
 #undef  DEBUG_STATISTICS
 #undef  DEBUG_RESET
 
+#define MAX_CHANNEL 1
+#define MAX_LUN 8
 #define MAX_TARGET 8
 #define MAX_IRQ 16
 #define MAX_BOARDS 4
@@ -253,9 +258,9 @@ struct mscp {
    unsigned char dcn: 1;                /* disable disconnect */
    unsigned char ca: 1;                 /* use cache (if available) */
    unsigned char sg: 1;                 /* scatter/gather operation */
-   unsigned char target: 3;             /* target SCSI id */
-   unsigned char ch_no: 2;              /* SCSI channel (always 0 for 14f) */
-   unsigned char lun: 3;                /* logical unit number */
+   unsigned char target: 3;             /* SCSI target id */
+   unsigned char channel: 2;            /* SCSI channel number */
+   unsigned char lun: 3;                /* SCSI logical unit number */
    unsigned int data_address PACKED;    /* transfer data pointer */
    unsigned int data_len PACKED;        /* length in bytes */
    unsigned int command_link PACKED;    /* for linking command chains */
@@ -288,8 +293,8 @@ struct hostdata {
    char board_name[16];                 /* Name of this board */
    char board_id[256];                  /* data from INQUIRY on this board */
    int in_reset;                        /* True if board is doing a reset */
-   int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
-   int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
+   int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */
+   int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If TRUE redo i/o on target */
    unsigned int retries;                /* Number of internal retries */
    unsigned long last_retried_pid;      /* Pid of last retried command */
    unsigned char subversion;            /* Bus type, either ISA or ESA */
@@ -300,8 +305,8 @@ struct hostdata {
    unsigned char slot;
    };
 
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const chardriver_name = "Ux4F";
+static struct Scsi_Host *sh[MAX_BOARDS + 1];
+static const char *driver_name = "Ux4F";
 static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
@@ -324,7 +329,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
 static void u14_34f_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
-static inline unchar wait_on_busy(ushort iobase) {
+static inline int wait_on_busy(unsigned int iobase) {
    unsigned int loop = MAXLOOP;
 
    while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED)
@@ -376,9 +381,9 @@ static int board_inquiry(unsigned int j) {
    return FALSE;
 }
 
-static inline int port_detect(ushort *port_base, unsigned int j, 
-                             Scsi_Host_Template * tpnt) {
-   unsigned char irq, dma_channel, subversion;
+static inline int port_detect(unsigned int *port_base, unsigned int j, 
+                             Scsi_Host_Template *tpnt) {
+   unsigned char irq, dma_channel, subversion, c;
    unsigned char in_byte;
 
    /* Allowed BIOS base addresses (NULL indicates reserved) */
@@ -466,6 +471,7 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       }
 
    sh[j]->io_port = *port_base;
+   sh[j]->unique_id = *port_base;
    sh[j]->n_io_port = REGION_SIZE;
    sh[j]->base = bios_segment_table[config_1.bios_segment];
    sh[j]->irq = irq;
@@ -524,6 +530,10 @@ static inline int port_detect(ushort *port_base, unsigned int j,
       enable_dma(dma_channel);
       }
 
+   sh[j]->max_channel = MAX_CHANNEL - 1;
+   sh[j]->max_id = MAX_TARGET;
+   sh[j]->max_lun = MAX_LUN;
+
    if (HD(j)->subversion == ISA && !board_inquiry(j)) {
       HD(j)->board_id[40] = 0;
 
@@ -538,21 +548,29 @@ static inline int port_detect(ushort *port_base, unsigned int j,
 
    printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, DMA %u, SG %d, "\
          "Mbox %d, CmdLun %d, C%d.\n", BN(j), sh[j]->io_port, 
-         (int)sh[j]->base, sh[j]->irq, 
-         sh[j]->dma_channel, sh[j]->sg_tablesize, 
-         sh[j]->can_queue, sh[j]->cmd_per_lun,
+         (int)sh[j]->base, sh[j]->irq, sh[j]->dma_channel,
+          sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun,
          sh[j]->hostt->use_clustering);
+
+   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)
+      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",
+             BN(j), sh[j]->max_id, sh[j]->max_lun);
+
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      printk("%s: SCSI channel %u enabled, host target ID %u.\n",
+             BN(j), c, sh[j]->this_id);
+
    return TRUE;
 }
 
-int u14_34f_detect (Scsi_Host_Template * tpnt) {
+int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k, flags;
 
-   ushort io_port[] = {
+   unsigned int io_port[] = {
       0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, 0x0
       };
 
-   ushort *port_base = io_port;
+   unsigned int *port_base = io_port;
 
    tpnt->proc_dir = &proc_scsi_u14_34f;
 
@@ -582,7 +600,7 @@ int u14_34f_detect (Scsi_Host_Template * tpnt) {
 
 static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
    unsigned int k, data_len = 0;
-   struct scatterlist * sgpnt;
+   struct scatterlist *sgpnt;
 
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 
@@ -653,8 +671,9 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    cpp->index = i;
    SCpnt->host_scribble = (unsigned char *) &cpp->index;
 
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
-                       BN(j), i, SCpnt->target, SCpnt->pid);
+   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+                       BN(j), i, SCpnt->channel, SCpnt->target, 
+                        SCpnt->lun, SCpnt->pid);
 
    cpp->xdir = DTD_IN;
 
@@ -665,6 +684,7 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
        }
 
    cpp->opcode = OP_SCSI;
+   cpp->channel = SCpnt->channel;
    cpp->target = SCpnt->target;
    cpp->lun = SCpnt->lun;
    cpp->SCpnt = SCpnt;
@@ -686,8 +706,9 @@ int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
    if (wait_on_busy(sh[j]->io_port)) {
       SCpnt->result = DID_ERROR << 16;
       SCpnt->host_scribble = NULL;
-      printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
-            BN(j), SCpnt->target, SCpnt->pid);
+      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy, DID_ERROR,"\
+             " done.\n", BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun,
+             SCpnt->pid);
       restore_flags(flags);
       done(SCpnt);
       return 0;
@@ -712,15 +733,15 @@ int u14_34f_abort(Scsi_Cmnd *SCarg) {
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
-      printk("%s: abort, target %d, pid %ld inactive.\n",
-            BN(j), SCarg->target, SCarg->pid);
+      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",
+            BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
       restore_flags(flags);
       return SCSI_ABORT_NOT_RUNNING;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
-   printk("%s: abort, mbox %d, target %d, pid %ld.\n",
-         BN(j), i, SCarg->target, SCarg->pid);
+   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",
+         BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -763,16 +784,17 @@ int u14_34f_abort(Scsi_Cmnd *SCarg) {
    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
 }
 
-int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) {
-   unsigned int i, j, flags, time, k, limit = 0;
+int u14_34f_reset(Scsi_Cmnd *SCarg, unsigned int reset_flags) {
+   unsigned int i, j, flags, time, k, c, limit = 0;
    int arg_done = FALSE;
    Scsi_Cmnd *SCpnt;
 
    save_flags(flags);
    cli();
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-   printk("%s: reset, enter, target %d, pid %ld, reset_flags %u.\n", 
-         BN(j), SCarg->target, SCarg->pid, reset_flags);
+   printk("%s: reset, enter, target %d.%d:%d, pid %ld, reset_flags %u.\n", 
+         BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid,
+          reset_flags);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -791,9 +813,11 @@ int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) {
 
    HD(j)->retries = 0;
 
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
-   for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
+   for (c = 0; c <= sh[j]->max_channel; c++)
+      for (k = 0; k < sh[j]->max_id; k++) {
+         HD(j)->target_redo[k][c] = TRUE;
+         HD(j)->target_to[k][c] = 0;
+         }
 
    for (i = 0; i < sh[j]->can_queue; i++) {
 
@@ -878,7 +902,7 @@ int u14_34f_reset(Scsi_Cmnd * SCarg, unsigned int reset_flags) {
       }
 }
 
-int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
+int u14_34f_biosparam(Disk *disk, kdev_t dev, int *dkinfo) {
    unsigned int j = 0;
    int size = disk->capacity;
 
@@ -888,9 +912,10 @@ int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
    return 0;
 }
 
-static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
+static void u14_34f_interrupt_handler(int irq, void *dev_id,
+                                      struct pt_regs *regs) {
    Scsi_Cmnd *SCpnt;
-   unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
+   unsigned int i, j, k, c, flags, status, tstatus, loops, total_loops = 0;
    struct mscp *spp;
 
    save_flags(flags);
@@ -975,9 +1000,8 @@ static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * re
                  status = DID_ERROR << 16;
 
               /* If there was a bus reset, redo operation on each target */
-              else if (tstatus != GOOD
-                       && SCpnt->device->type == TYPE_DISK
-                       && HD(j)->target_reset[SCpnt->target])
+              else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK
+                       && HD(j)->target_redo[SCpnt->target][SCpnt->channel])
                  status = DID_BUS_BUSY << 16;
 
               /* Works around a flaw in scsi.c */
@@ -990,26 +1014,27 @@ static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * re
                  status = DID_OK << 16;
 
               if (tstatus == GOOD)
-                 HD(j)->target_reset[SCpnt->target] = FALSE;
+                 HD(j)->target_redo[SCpnt->target][SCpnt->channel] = FALSE;
 
               if (spp->target_status && SCpnt->device->type == TYPE_DISK)
-                 printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
-                        "0x%x, sense key 0x%x.\n", BN(j), 
-                        SCpnt->target, SCpnt->lun, SCpnt->pid,
-                        spp->target_status, SCpnt->sense_buffer[2]);
+                 printk("%s: ihdlr, target %d.%d:%d, pid %ld, "\
+                         "target_status 0x%x, sense key 0x%x.\n", BN(j), 
+                        SCpnt->channel, SCpnt->target, SCpnt->lun,
+                         SCpnt->pid, spp->target_status,
+                         SCpnt->sense_buffer[2]);
 
-              HD(j)->target_time_out[SCpnt->target] = 0;
+              HD(j)->target_to[SCpnt->target][SCpnt->channel] = 0;
 
                if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0;
 
               break;
            case ASST:     /* Selection Time Out */
 
-              if (HD(j)->target_time_out[SCpnt->target] > 1)
+              if (HD(j)->target_to[SCpnt->target][SCpnt->channel] > 1)
                  status = DID_ERROR << 16;
               else {
                  status = DID_TIME_OUT << 16;
-                 HD(j)->target_time_out[SCpnt->target]++;
+                 HD(j)->target_to[SCpnt->target][SCpnt->channel]++;
                  }
 
               break;
@@ -1020,8 +1045,10 @@ static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * re
            case 0x96:     /* Illegal SCSI command */
            case 0xa3:     /* SCSI bus reset error */
 
-              for (k = 0; k < MAX_TARGET; k++) 
-                 HD(j)->target_reset[k] = TRUE;
+              for (c = 0; c <= sh[j]->max_channel; c++) 
+                 for (k = 0; k < sh[j]->max_id; k++) 
+                    HD(j)->target_redo[k][c] = TRUE;
+   
 
            case 0x92:     /* Data over/under-run */
 
@@ -1061,9 +1088,10 @@ static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * re
             do_trace)
 #endif
            printk("%s: ihdlr, mbox %2d, err 0x%x:%x,"\
-                  " target %d:%d, pid %ld, count %d.\n",
+                  " target %d.%d:%d, pid %ld, count %d.\n",
                   BN(j), i, spp->adapter_status, spp->target_status,
-                  SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+                  SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid,
+                   HD(j)->iocount);
 
         /* Set the command state to inactive */
         SCpnt->host_scribble = NULL;
index b6051a248d3e6edbccb8c811495a5261c2567671..f301f48ae629c72ffcb55f09afc117b36fefb635 100644 (file)
@@ -10,7 +10,7 @@ int u14_34f_abort(Scsi_Cmnd *);
 int u14_34f_reset(Scsi_Cmnd *, unsigned int);
 int u14_34f_biosparam(Disk *, kdev_t, int *);
 
-#define U14_34F_VERSION "2.12.00"
+#define U14_34F_VERSION "2.20.00"
 
 #define ULTRASTOR_14_34F {                                            \
                NULL, /* Ptr for modules */                           \
index 035fc4a2836c48a5483f275510b434b01d43bc21..6b75fa830fb7e6bb102025dae8a1118a4cc6a565 100644 (file)
@@ -3,6 +3,9 @@
  *
  *  Copyright (C) 1996  Brian A. Lantz
  *  derived from binfmt_script.c
+ *
+ *  Simplified and modified to support binary java interpreters
+ *  by Tom May <ftom@netcom.com>.
  */
 
 #include <linux/module.h>
 
 #define _PATH_JAVA     "/usr/bin/java"
 #define _PATH_APPLET   "/usr/bin/appletviewer"
-#define _PATH_SH       "/bin/bash"
+
+/*  These paths can be modified with sysctl().  */
 
 char binfmt_java_interpreter[65] = _PATH_JAVA;
 char binfmt_java_appletviewer[65] = _PATH_APPLET;
 
-static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-       char *cp, *interp, *i_name;
+       char *i_name;
+       int len;
        int retval;
        unsigned char *ucp = (unsigned char *) bprm->buf;
        if ((ucp[0] != 0xca) || (ucp[1] != 0xfe) || (ucp[2] != 0xba) || (ucp[3] != 0xbe)) 
                return -ENOEXEC;
 
+       /*
+        * Fail if we're called recursively, e.g., the Java interpreter
+        * is a java binary.
+        */
+
+       if (bprm->java)
+               return -ENOEXEC;
+
+       bprm->java = 1;
+
        iput(bprm->inode);
        bprm->dont_iput=1;
 
        /*
-        * OK, we've set the interpreter name
-        * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
-        *           (2) the name of the java wrapper for argv[1] (_PATH_JAVA)
-        *           (3) filename of Java class (replace argv[0])
-        *               without leading path or trailing '.class'
+        * Set args: [0] the name of the java interpreter
+        *           [1] name of java class to execute, which is the
+        *               filename without the path and without trailing
+        *               ".class".  Note that the interpreter will use
+        *               its own way to found the class file (typically using
+        *               environment variable CLASSPATH), and may in fact
+        *               execute a different file from the one we want.
         *
         * This is done in reverse order, because of how the
         * user environment and arguments are stored.
         */
        remove_arg_zero(bprm);
-       if ((cp = strstr (bprm->filename, ".class")) != NULL)
-               *cp = 0;
+       len = strlen (bprm->filename);
+       if (len >= 6 && !strcmp (bprm->filename + len - 6, ".class"))
+               bprm->filename[len - 6] = 0;
        if ((i_name = strrchr (bprm->filename, '/')) != NULL)
                i_name++;
        else
@@ -49,27 +67,17 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
        bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
        bprm->argc++;
 
-       strcpy (bprm->buf, binfmt_java_interpreter);
-       cp = bprm->buf;
-       bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
-       bprm->argc++;
-
-       strcpy (bprm->buf, _PATH_SH);
-       interp = bprm->buf;
-       if ((i_name = strrchr (bprm->buf, '/')) != NULL)
-               i_name++;
-       else
-               i_name = bprm->buf;
+       i_name = binfmt_java_interpreter;
        bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
        bprm->argc++;
+
        if (!bprm->p) 
                return -E2BIG;
        /*
         * OK, now restart the process with the interpreter's inode.
-        * Note that we use open_namei() as the name is now in kernel
-        * space, and we don't need to copy it.
         */
-       retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+       bprm->filename = binfmt_java_interpreter;
+       retval = open_namei(binfmt_java_interpreter, 0, 0, &bprm->inode, NULL);
        if (retval)
                return retval;
        bprm->dont_iput=0;
@@ -82,7 +90,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 
 static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-       char *cp, *interp, *i_name;
+       char *i_name;
        int retval;
        if (strncmp (bprm->buf, "<!--applet", 10))
                return -ENOEXEC;
@@ -91,10 +99,8 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
        bprm->dont_iput=1;
 
        /*
-        * OK, we've set the interpreter name
-        * Splice in (1) the interpreter's name for argv[0] (_PATH_SH)
-        *           (2) the name of the appletviewer wrapper for argv[1] (_PATH_APPLET)
-        *           (3) filename of html file (replace argv[0])
+        * Set args: [0] the name of the appletviewer
+        *           [1] filename of html file
         *
         * This is done in reverse order, because of how the
         * user environment and arguments are stored.
@@ -104,27 +110,17 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
        bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
        bprm->argc++;
 
-       strcpy (bprm->buf, binfmt_java_appletviewer);
-       cp = bprm->buf;
-       bprm->p = copy_strings(1, &cp, bprm->page, bprm->p, 2);
-       bprm->argc++;
-
-       strcpy (bprm->buf, _PATH_SH);
-       interp = bprm->buf;
-       if ((i_name = strrchr (bprm->buf, '/')) != NULL)
-               i_name++;
-       else
-               i_name = bprm->buf;
+       i_name = binfmt_java_appletviewer;
        bprm->p = copy_strings(1, &i_name, bprm->page, bprm->p, 2);
        bprm->argc++;
+
        if (!bprm->p) 
                return -E2BIG;
        /*
         * OK, now restart the process with the interpreter's inode.
-        * Note that we use open_namei() as the name is now in kernel
-        * space, and we don't need to copy it.
         */
-       retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
+       bprm->filename = binfmt_java_appletviewer;
+       retval = open_namei(binfmt_java_appletviewer, 0, 0, &bprm->inode, NULL);
        if (retval)
                return retval;
        bprm->dont_iput=0;
@@ -135,20 +131,20 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
        return search_binary_handler(bprm,regs);
 }
 
-static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
+static int load_java(struct linux_binprm *bprm,struct pt_regs *regs)
 {
        int retval;
        MOD_INC_USE_COUNT;
-       retval = do_load_script(bprm,regs);
+       retval = do_load_java(bprm,regs);
        MOD_DEC_USE_COUNT;
        return retval;
 }
 
-struct linux_binfmt java_format = {
+static struct linux_binfmt java_format = {
 #ifndef MODULE
-       NULL, 0, load_script, NULL, NULL
+       NULL, 0, load_java, NULL, NULL
 #else
-       NULL, &mod_use_count_, load_script, NULL, NULL
+       NULL, &mod_use_count_, load_java, NULL, NULL
 #endif
 };
 
@@ -161,7 +157,7 @@ static int load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
        return retval;
 }
 
-struct linux_binfmt applet_format = {
+static struct linux_binfmt applet_format = {
 #ifndef MODULE
        NULL, 0, load_applet, NULL, NULL
 #else
@@ -170,7 +166,6 @@ struct linux_binfmt applet_format = {
 };
 
 int init_java_binfmt(void) {
-       printk(KERN_INFO "JAVA Binary support v1.01 for Linux 1.3.98 (C)1996 Brian A. Lantz\n");
        register_binfmt(&java_format);
        return register_binfmt(&applet_format);
 }
@@ -182,7 +177,6 @@ int init_module(void)
 }
 
 void cleanup_module( void) {
-       printk(KERN_INFO "Removing JAVA Binary support...\n");
        unregister_binfmt(&java_format);
        unregister_binfmt(&applet_format);
 }
index 4e347c49f0146fcf162d919cabade8dc3c334aa9..67b1b058871d606cb736c9ecca480bb029617964 100644 (file)
@@ -13,7 +13,8 @@
 
 static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-       char *cp, *interp, *i_name, *i_arg;
+       char *cp, *i_name, *i_arg;
+       char interp[128];
        int retval;
        if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang)) 
                return -ENOEXEC;
@@ -38,9 +39,10 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
                        break;
        }
        for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
-       if (!cp || *cp == '\0') 
+       if (cp == '\0') 
                return -ENOEXEC; /* No interpreter name found */
-       interp = i_name = cp;
+       strcpy (interp, cp);
+       i_name = cp;
        i_arg = 0;
        for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
                if (*cp == '/')
@@ -73,9 +75,8 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
                return -E2BIG;
        /*
         * OK, now restart the process with the interpreter's inode.
-        * Note that we use open_namei() as the name is now in kernel
-        * space, and we don't need to copy it.
         */
+       bprm->filename = interp;
        retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
        if (retval)
                return retval;
index 560e387681c0af2fc72f331fa02cc4ac67de7150..4029063d00c188ad4d8ecb65a75118df9a3b955e 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -629,6 +629,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
                return retval;
        bprm.filename = filename;
        bprm.sh_bang = 0;
+       bprm.java = 0;
        bprm.loader = 0;
        bprm.exec = 0;
        bprm.dont_iput = 0;
index 0222a032063ae165d27f2a7d362b3069920081db..2f12cae9b775942f9b5a1ace41202592e0e2b7f6 100644 (file)
@@ -1560,7 +1560,7 @@ static int *root_nfs_call(int *end)
  */
 static int *root_nfs_header(int proc, int program, int version)
 {
-       int groups[] = { 0, NOGROUP };
+       gid_t groups[] = { 0 };
 
        if (rpc_packet == NULL) {
                if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
@@ -1568,7 +1568,7 @@ static int *root_nfs_header(int proc, int program, int version)
                        return NULL;
                }
        }
-       return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
+       return rpc_header(rpc_packet, proc, program, version, 0, 0, 1, groups);
 }
 
 
index 207021883f3314d8bc5508ef778b8f4b84168e3e..ff71bd63194837bb242b98a35f778930e060f67d 100644 (file)
@@ -904,10 +904,10 @@ retry:
  */
 
 int *rpc_header(int *p, int procedure, int program, int version,
-                                       int uid, int gid, int *groups)
+                                       int uid, int gid,
+                                       int ngroup, gid_t *groups)
 {
-       int *p1, *p2;
-       int i;
+       int *p1;
        static int xid = 0;
        unsigned char *sys = (unsigned char *) system_utsname.nodename;
 
@@ -927,10 +927,14 @@ int *rpc_header(int *p, int procedure, int program, int version,
        p = xdr_encode_string(p, (char *) sys);
        *p++ = htonl(uid);
        *p++ = htonl(gid);
-       p2 = p++;
-       for (i = 0; i < 16 && i < NGROUPS && groups[i] != NOGROUP; i++)
-               *p++ = htonl(groups[i]);
-       *p2 = htonl(i);
+       if (ngroup > 16)
+               ngroup = 16;
+       *p++ = htonl(ngroup);
+       while (ngroup) {
+               *p++ = htonl(*groups);
+               groups++;
+               ngroup--;
+       }
        *p1 = htonl((p - (p1 + 1)) << 2);
        *p++ = htonl(RPC_AUTH_NULL);
        *p++ = htonl(0);
@@ -942,7 +946,7 @@ static int *nfs_rpc_header(int *p, int procedure, int ruid)
 {
        return rpc_header(p, procedure, NFS_PROGRAM, NFS_VERSION,
                        (ruid ? current->uid : current->fsuid),
-                       current->egid, current->groups);
+                       current->egid, current->ngroups, current->groups);
 }
 
 
index bb7fe8b8db0b62f725c17d061f8ab04a27467645..2c81e938ea8324aa4b38984011a991d19f8cfb02 100644 (file)
@@ -408,7 +408,7 @@ clear_user(void *to, unsigned long n)
                "       .align 4\n"                                        \
                "       .long 0b,3b\n"                                     \
                ".text"                                                    \
-               : "=r"(res), "=r"(count)                                   \
+               : "=d"(res), "=c"(count)                                   \
                : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \
                : "si", "di", "ax", "memory")
 
diff --git a/include/asm-m68k/atari_SLM.h b/include/asm-m68k/atari_SLM.h
new file mode 100644 (file)
index 0000000..42f4fcd
--- /dev/null
@@ -0,0 +1,28 @@
+
+#ifndef _ATARI_SLM_H
+#define _ATARI_SLM_H
+
+/* Atari SLM laser printer specific ioctls */
+
+#define        SLMIOGSTAT      0xa100
+#define        SLMIOGPSIZE     0xa101
+#define        SLMIOGMFEED     0xa102
+
+#define        SLMIORESET      0xa140
+
+#define        SLMIOSPSIZE     0xa181
+#define        SLMIOSMFEED     0xa182
+
+/* Status returning structure (SLMIOGSTAT) */
+struct SLM_status {
+       int             stat;           /* numeric status code */
+       char    str[40];        /* status string */
+};
+
+/* Paper size structure (SLMIO[GS]PSIZE) */
+struct SLM_paper_size {
+       int             width;
+       int             height;
+};
+
+#endif /* _ATARI_SLM_H */
index 7f82a8c91c46abc657feb0e51d6f122c6b55d516..c6c9fc1e992ece49cc2f798988e3bb9e99cfac9b 100644 (file)
@@ -9,6 +9,38 @@
 #define __BIG_ENDIAN_BITFIELD
 #endif
 
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/types.h>
+
+/*
+ * In-kernel byte order macros to handle stuff like
+ * byte-order-dependent filesystems etc.
+ */
+
+#define le16_to_cpu(__val) __swab16(__val)
+#define le32_to_cpu(__val) __swab32(__val)
+#define cpu_to_le32(__val) __swab32(__val)
+#define cpu_to_le16(__val) __swab16(__val)
+
+extern __inline__ __u16 __swab16 (__u16 val)
+{
+       return (val << 8) | (val >> 8);
+}
+
+extern __inline__ __u32 __swab32 (__u32 val)
+{
+       __asm__ ("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
+       return val;
+}
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+
+#endif
+
 #undef ntohl
 #undef ntohs
 #undef htonl
@@ -37,6 +69,11 @@ __ntohs(unsigned short int x)
 #define __htonl(x) __ntohl(x)
 #define __htons(x) __ntohs(x)
 
+#define __constant_htonl(x) (x)
+#define __constant_htons(x) (x)
+#define __constant_ntohl(x) (x)
+#define __constant_ntohs(x) (x)
+
 #ifdef __OPTIMIZE__
 #define ntohl(x) __ntohl(x)
 #define ntohs(x) __ntohs(x)
index 8eec9d21af04f7de59e0efc9cde9028253312e3d..8ccf73858cdb59e0bc82e902cd9c082eda873496 100644 (file)
@@ -6,10 +6,11 @@
  */
 
 #include <asm/ptrace.h>
+#include <asm/user.h>
 
 typedef unsigned long elf_greg_t;
 
-#define ELF_NGREG 20 /* d1-d7/a0-a6/d0/usp/orig_d0/sr/pc/fmtvec */
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct user_m68kfp_struct elf_fpregset_t;
@@ -45,9 +46,10 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
        pr_reg[8] = regs->a1;                                           \
        pr_reg[14] = regs->d0;                                          \
        pr_reg[15] = rdusp();                                           \
-       pr_reg[16] = 0; /* orig_d0 */                                   \
+       pr_reg[16] = regs->orig_d0;                                     \
        pr_reg[17] = regs->sr;                                          \
        pr_reg[18] = regs->pc;                                          \
+       pr_reg[19] = (regs->format << 12) | regs->vector;               \
        {                                                               \
          struct switch_stack *sw = ((struct switch_stack *)regs) - 1;  \
          pr_reg[5] = sw->d6;                                           \
index 0360aa0ecc28ee2b6e5153c612457c1db5972732..a9d65f743045a9d57769f8d1f1b2c0ddc140363a 100644 (file)
@@ -1,38 +1,41 @@
 #ifndef _M68K_IO_H
 #define _M68K_IO_H
 
-static inline unsigned char get_user_byte_io(const char * addr)
-{
-       register unsigned char _v;
+#ifdef __KERNEL__
 
-       __asm__ __volatile__ ("moveb %1,%0":"=dm" (_v):"m" (*addr));
-       return _v;
-}
-#define inb_p(addr) get_user_byte_io((char *)(addr))
-#define inb(addr) get_user_byte_io((char *)(addr))
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the m68k architecture, we just read/write the
+ * memory location directly.
+ */
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
 
-static inline void put_user_byte_io(char val,char *addr)
-{
-       __asm__ __volatile__ ("moveb %0,%1"
-                             : /* no outputs */
-                             :"idm" (val),"m" (*addr)
-                             : "memory");
-}
-#define outb_p(x,addr) put_user_byte_io((x),(char *)(addr))
-#define outb(x,addr) put_user_byte_io((x),(char *)(addr))
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)     memcpy((void *)(a),(b),(c))
+
+#define inb_p(addr) readb(addr)
+#define inb(addr) readb(addr)
+
+#define outb(x,addr) ((void) writeb(x,addr))
+#define outb_p(x,addr) outb(x,addr)
 
 /*
  * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
- * make the kernel segment mapped at 0, we need to do translation
- * on the i386 as well)
  */
-extern unsigned long mm_vtop(unsigned long addr);
-extern unsigned long mm_ptov(unsigned long addr);
+extern unsigned long mm_vtop(unsigned long addr) __attribute__ ((const));
+extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
 
 extern inline unsigned long virt_to_phys(volatile void * address)
 {
-       return (unsigned long) mm_vtop((unsigned long)address);
+       return mm_vtop((unsigned long)address);
 }
 
 extern inline void * phys_to_virt(unsigned long address)
@@ -41,10 +44,11 @@ extern inline void * phys_to_virt(unsigned long address)
 }
 
 /*
- * IO bus memory addresses are also 1:1 with the physical address
+ * IO bus memory addresses are 1:1 with the physical address
  */
 #define virt_to_bus virt_to_phys
 #define bus_to_virt phys_to_virt
 
+#endif /* __KERNEL__ */
 
 #endif /* _M68K_IO_H */
diff --git a/include/asm-m68k/ipc.h b/include/asm-m68k/ipc.h
new file mode 100644 (file)
index 0000000..f1a75cc
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __m68k_IPC_H__
+#define __m68k_IPC_H__
+
+/* 
+ * These are used to wrap system calls on m68k.
+ *
+ * See arch/m68k/kernel/sys_m68k.c for ugly details..
+ */
+struct ipc_kludge {
+       struct msgbuf *msgp;
+       long msgtyp;
+};
+
+#define SEMOP           1
+#define SEMGET          2
+#define SEMCTL          3
+#define MSGSND         11
+#define MSGRCV         12
+#define MSGGET         13
+#define MSGCTL         14
+#define SHMAT          21
+#define SHMDT          22
+#define SHMGET         23
+#define SHMCTL         24
+
+#define IPCCALL(version,op)    ((version)<<16 | (op))
+
+#endif
index c23f48eafe94ead0d77e178f42953da2fcb15be7..cbee6c99803d50dfe0b6adb4d1698ded7b62e1f8 100644 (file)
@@ -16,6 +16,7 @@
 #define MAP_DENYWRITE  0x0800          /* ETXTBSY */
 #define MAP_EXECUTABLE 0x1000          /* mark it as an executable */
 #define MAP_LOCKED     0x2000          /* pages are locked */
+#define MAP_NORESERVE  0x4000          /* don't check for reservations */
 
 #define MS_ASYNC       1               /* sync memory asynchronously */
 #define MS_INVALIDATE  2               /* invalidate the caches */
index 783ea2527867ac3c5419fb026f3e6c43d93ad3aa..82dbe59c34f15b5d626e5cfaefaff031e258d8e9 100644 (file)
@@ -10,6 +10,9 @@
 
 #define STRICT_MM_TYPECHECKS
 
+#define clear_page(page)       memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
 #ifdef STRICT_MM_TYPECHECKS
 /*
  * These are used to make use of C type-checking..
@@ -50,18 +53,14 @@ typedef unsigned long pgprot_t;
 
 #endif
 
-/* This is the cache mode to be used for pages containing page descriptors for
- * processors >= '040. It is in pte_mknocache(), and the variable is defined
- * and initialized in head.S */
-extern int m68k_pgtable_cachemode;
-
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* This handles the memory map.. */
 #define PAGE_OFFSET            0
-#define MAP_NR(addr)           (((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED      (1<<15)
+#define __pa(x)                        ((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)                        ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define MAP_NR(addr)           (__pa(addr) >> PAGE_SHIFT)
 
 #endif /* __KERNEL__ */
 
index 252f01cc0e6f310359b8d1aa18c52d88d84031ce..429a689386d845b15836948dd9eb6145492ece44 100644 (file)
@@ -116,7 +116,7 @@ typedef pte_table pte_tablepage[PTE_TABLES_PER_PAGE];
  * area for the same reason. ;)
  */
 #define VMALLOC_OFFSET (8*1024*1024)
-#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 
 #endif /* __ASSEMBLY__ */
@@ -147,7 +147,18 @@ typedef pte_table pte_tablepage[PTE_TABLES_PER_PAGE];
 
 #ifndef __ASSEMBLY__
 
+/* This is the cache mode to be used for pages containing page descriptors for
+ * processors >= '040. It is in pte_mknocache(), and the variable is defined
+ * and initialized in head.S */
+extern int m68k_pgtable_cachemode;
+
+#if defined(CONFIG_M68040_OR_M68060_ONLY)
+#define mm_cachebits _PAGE_CACHE040
+#elif defined(CONFIG_M68020_OR_M68030_ONLY)
+#define mm_cachebits 0
+#else
 extern unsigned long mm_cachebits;
+#endif
 
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_RONLY | _PAGE_ACCESSED | mm_cachebits)
 #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | mm_cachebits)
@@ -215,8 +226,6 @@ extern pte_t * __bad_pagetable(void);
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-extern unsigned long high_memory;
-
 /* 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));
@@ -227,8 +236,10 @@ extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const));
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = VTOP(page) | pgprot_val(pgprot); return pte; }
+#define mk_pte(page, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(page) + pgprot_val(pgprot); __pte; })
+#define mk_pte_phys(physpage, pgprot) \
+({ pte_t __pte; pte_val(__pte) = VTOP(physpage) + pgprot_val(pgprot); __pte; })
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
@@ -239,7 +250,7 @@ extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 
        ptep = (pte_t *) VTOP(ptep);
        for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
-               pmdp->pmd[i] = _PAGE_TABLE | (unsigned long)ptep;
+               pmdp->pmd[i] = _PAGE_TABLE | _PAGE_ACCESSED | (unsigned long)ptep;
 }
 
 /* early termination version of the above */
@@ -249,11 +260,11 @@ extern inline void pmd_set_et(pmd_t * pmdp, pte_t * ptep)
 
        ptep = (pte_t *) VTOP(ptep);
        for (i = 0; i < 16; i++, ptep += PTRS_PER_PTE/16)
-               pmdp->pmd[i] = _PAGE_PRESENT | (unsigned long)ptep;
+               pmdp->pmd[i] = _PAGE_PRESENT | _PAGE_ACCESSED | (unsigned long)ptep;
 }
 
 extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | VTOP(pmdp); }
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | VTOP(pmdp); }
 
 extern inline unsigned long pte_page(pte_t pte)
 { return PTOV(pte_val(pte) & PAGE_MASK); }
@@ -271,7 +282,7 @@ extern inline void pte_clear(pte_t *ptep)   { pte_val(*ptep) = 0; }
 
 extern inline int pmd_none2(pmd_t *pmd)                { return !pmd_val(*pmd); }
 #define pmd_none(pmd) pmd_none2(&(pmd))
-extern inline int pmd_bad2(pmd_t *pmd)         { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE || pmd_page(*pmd) > high_memory; }
+extern inline int pmd_bad2(pmd_t *pmd)         { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
 #define pmd_bad(pmd) pmd_bad2(&(pmd))
 extern inline int pmd_present2(pmd_t *pmd)     { return pmd_val(*pmd) & _PAGE_TABLE; }
 #define pmd_present(pmd) pmd_present2(&(pmd))
@@ -284,7 +295,7 @@ extern inline void pmd_clear(pmd_t * pmdp)
 }
 
 extern inline int pgd_none(pgd_t pgd)          { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)           { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
+extern inline int pgd_bad(pgd_t pgd)           { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
 extern inline int pgd_present(pgd_t pgd)       { return pgd_val(pgd) & _PAGE_TABLE; }
 
 extern inline void pgd_clear(pgd_t * pgdp)     { pgd_val(*pgdp) = 0; }
@@ -319,10 +330,8 @@ extern inline pte_t pte_mkcache(pte_t pte) { pte_val(pte) = (pte_val(pte) & _CAC
 /* to set the page-dir */
 extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
 {
-       tsk->tss.pagedir_v = (unsigned long *)pgdir;
-       tsk->tss.pagedir_p = VTOP(pgdir);
-       tsk->tss.crp[0] = 0x80000000 | _PAGE_SHORT;
-       tsk->tss.crp[1] = tsk->tss.pagedir_p;
+       tsk->tss.crp[0] = 0x80000000 | _PAGE_TABLE;
+       tsk->tss.crp[1] = VTOP(pgdir);
        if (tsk == current) {
                if (CPU_IS_040_OR_060)
                        __asm__ __volatile__ ("movel %0@,%/d0\n\t"
@@ -425,9 +434,10 @@ extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
 {
        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
        if (pmd_none(*pmd)) {
-               pte_t * page = (pte_t *)get_free_page(GFP_KERNEL);
+               pte_t * page = (pte_t *)__get_free_page(GFP_KERNEL);
                if (pmd_none(*pmd)) {
                        if (page) {
+                               memset((void *) page, 0, PAGE_SIZE);
                                nocache_page((unsigned long)page);
                                pmd_set(pmd,page);
                                return page + address;
index 2f1d561befc905175c12c992270f08032d12dc25..5350959715f2984c9d56adf35107d1988d3d3ba7 100644 (file)
@@ -13,6 +13,7 @@ typedef unsigned short        __kernel_mode_t;
 typedef unsigned short __kernel_nlink_t;
 typedef long           __kernel_off_t;
 typedef int            __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
 typedef unsigned short __kernel_uid_t;
 typedef unsigned short __kernel_gid_t;
 typedef unsigned int   __kernel_size_t;
index 89f369017b181be8592d2ca1308ea0068601ead9..4610786bdedd8dd768679f02b462cb788de8e1d8 100644 (file)
 /*
  * Bus types
  */
-#define EISA_bus__is_a_macro   1
 #define EISA_bus 0
-#define MCA_bus__is_a_macro    1
 #define MCA_bus 0
 
-/*
- * The m68k has no problems with write protection
- */
-#define wp_works_ok__is_a_macro        1
-#define wp_works_ok 1
-
 /* MAX floating point unit state size (FSAVE/FRESTORE) */
 #define FPSTATESIZE   (216/sizeof(unsigned char))
 
@@ -42,8 +34,6 @@ struct thread_struct {
        unsigned long  usp;             /* user stack pointer */
        unsigned short sr;              /* saved status register */
        unsigned short fs;              /* saved fs (sfc, dfc) */
-       unsigned long  *pagedir_v;      /* root page table virtual addr */
-       unsigned long  pagedir_p;       /* root page table physaddr */
        unsigned long  crp[2];          /* cpu root pointer */
        unsigned long  esp0;            /* points to SR of stack frame */
        unsigned long  fp[8*3];
@@ -56,7 +46,7 @@ struct thread_struct {
 #define INIT_TSS  { \
        sizeof(init_kernel_stack) + (long) init_kernel_stack, 0, \
        PS_S, KERNEL_DS, \
-       NULL, 0, {0, 0}, 0 \
+       {0, 0}, 0, {0,}, {0, 0, 0}, {0,}, \
 }
 
 #define alloc_kernel_stack()    __get_free_page(GFP_KERNEL)
index f375cc977108408b668e9b3ffc907e12c0b7d213..5fe0c033fedf83aeb88f0e0beb0ae877ed1e1268 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-/*
- * Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- */
-#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
-#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
-
-/*
- * This is a silly but good way to make sure that
- * the __put_user function is indeed always optimized,
- * and that we use the correct sizes..
- */
-extern int bad_user_access_length(void);
-
-#define __ptr(x) ((unsigned long *)(x))
-
-static inline void __put_user(unsigned long x, void * y, int size)
-{
-       switch (size) {
-               case 1:
-                       __asm__ ("movesb %0,%1"
-                               : /* no outputs */
-                               :"r" (x),"m" (*__ptr(y)) : "memory");
-                       break;
-               case 2:
-                       __asm__ ("movesw %0,%1"
-                               : /* no outputs */
-                               :"r" (x),"m" (*__ptr(y)) : "memory");
-                       break;
-               case 4:
-                       __asm__ ("movesl %0,%1"
-                               : /* no outputs */
-                               :"r" (x),"m" (*__ptr(y)) : "memory");
-                       break;
-               default:
-                       bad_user_access_length();
-       }
-}
-
-static inline unsigned long __get_user(const void * y, int size)
-{
-       unsigned long result;
-
-       switch (size) {
-               case 1:
-                       __asm__ ("movesb %1,%0"
-                                :"=r" (result)
-                                :"m" (*__ptr(y)));
-                       return (unsigned char) result;
-               case 2:
-                       __asm__ ("movesw %1,%0"
-                                :"=r" (result)
-                                :"m" (*__ptr(y)));
-                       return (unsigned short) result;
-               case 4:
-                       __asm__ ("movesl %1,%0"
-                                :"=r" (result)
-                                :"m" (*__ptr(y)));
-                       return result;
-               default:
-                       return bad_user_access_length();
-       }
-}
-#undef __ptr
-
-/*
- * These are deprecated..
- *
- * Use "put_user()" and "get_user()" with the proper pointer types instead.
- */
-
-#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
-#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
-#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
-
-#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
-#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
-#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
-
-#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
-
-static inline unsigned char get_user_byte(const char * addr)
-{
-       return __get_user(addr,1);
-}
-
-static inline unsigned short get_user_word(const short *addr)
-{
-       return __get_user(addr,2);
-}
-
-static inline unsigned long get_user_long(const int *addr)
-{
-       return __get_user(addr,4);
-}
-
-static inline void put_user_byte(char val,char *addr)
-{
-       __put_user(val, addr, 1);
-}
-
-static inline void put_user_word(short val,short * addr)
-{
-       __put_user(val, addr, 2);
-}
-
-static inline void put_user_long(unsigned long val,int * addr)
-{
-       __put_user(val, addr, 4);
-}
-
-#endif
-
-static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
-       unsigned long tmp;
-       if (n == 0) return;
-       tmp = n;
-       n >>= 2;
-       if (n != 0)
-               __asm__ __volatile__ ("1:\t"
-                        "movel %1@+,%/d0\n\t"
-                        "movesl %/d0,%2@+\n\t"
-                        "dbra %0,1b\n\t"
-                        "clrw %0\n\t"
-                        "subql #1,%0\n\t"
-                        "bccs 1b\n\t"
-                        : "=d" (n), "=a" (from), "=a" (to)
-                        : "0" (n-1), "1" (from), "2" (to)
-                        : "d0", "memory");
-       if (tmp & 2)
-               __asm__ __volatile__ ("movew %0@+,%/d0\n\t"
-                        "movesw %/d0,%1@+\n\t"
-                        : "=a" (from), "=a" (to)
-                        : "0" (from), "1" (to)
-                        : "d0", "memory");
-       if (tmp & 1)
-               __asm__ __volatile__ ("moveb %0@,%/d0\n\t"
-                        "movesb %/d0,%1@\n\t"
-                        : /* no outputs */
-                        : "a" (from), "a" (to)
-                        : "d0", "memory");
-}
-
-static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
-       switch (n) {
-               case 0:
-                       return;
-               case 1:
-                       __put_user(*(const char *) from, (char *) to, 1);
-                       return;
-               case 2:
-                       __put_user(*(const short *) from, (short *) to, 2);
-                       return;
-               case 3:
-                       __put_user(*(const short *) from, (short *) to, 2);
-                       __put_user(*(2+(const char *) from), 2+(char *) to, 1);
-                       return;
-               case 4:
-                       __put_user(*(const int *) from, (int *) to, 4);
-                       return;
-               case 8:
-                       __put_user(*(const int *) from, (int *) to, 4);
-                       __put_user(*(1+(const int *) from), 1+(int *) to, 4);
-                       return;
-               case 12:
-                       __put_user(*(const int *) from, (int *) to, 4);
-                       __put_user(*(1+(const int *) from), 1+(int *) to, 4);
-                       __put_user(*(2+(const int *) from), 2+(int *) to, 4);
-                       return;
-               case 16:
-                       __put_user(*(const int *) from, (int *) to, 4);
-                       __put_user(*(1+(const int *) from), 1+(int *) to, 4);
-                       __put_user(*(2+(const int *) from), 2+(int *) to, 4);
-                       __put_user(*(3+(const int *) from), 3+(int *) to, 4);
-                       return;
-       }
-#define COMMON(x)                     \
-__asm__ __volatile__ ("1:\n\t"        \
-            "movel %1@+,%/d0\n\t"     \
-            "movesl %/d0,%2@+\n\t"    \
-            "dbra %0,1b\n\t"          \
-            "clrw %0\n\t"             \
-            "subql #1,%0\n\t"         \
-            "bccs 1b\n\t"             \
-            x                     \
-            : "=d" (n), "=a" (from), "=a" (to)    \
-            : "1" (from), "2" (to), "0" (n/4-1)   \
-            : "d0", "memory");
-
-  switch (n % 4) {
-      case 0:
-          COMMON("");
-          return;
-      case 1:
-          COMMON("moveb %1@+,%/d0; movesb %/d0,%2@+");
-          return;
-      case 2:
-          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+");
-          return;
-      case 3:
-          COMMON("movew %1@+,%/d0; movesw %/d0,%2@+\n\t"
-                 "moveb %1@+,%/d0; movesb %/d0,%2@+");
-          return;
-  }
-#undef COMMON
-}
-
-static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
-       unsigned long tmp;
-       if (n == 0) return;
-       tmp = n;
-       n >>= 2;
-       if (n != 0)
-               __asm__ __volatile__ ("1:\t"
-                        "movesl %1@+,%/d0\n\t"
-                        "movel %/d0,%2@+\n\t"
-                        "dbra %0,1b\n\t"
-                        "clrw %0\n\t"
-                        "subql #1,%0\n\t"
-                        "bccs 1b\n\t"
-                        : "=d" (n), "=a" (from), "=a" (to)
-                        : "0" (n-1), "1" (from), "2" (to)
-                        : "d0", "memory");
-       if (tmp & 2)
-               __asm__ __volatile__ ("movesw %0@+,%/d0\n\t"
-                        "movew %/d0,%1@+\n\t"
-                        : "=a" (from), "=a" (to)
-                        : "0" (from), "1" (to)
-                        : "d0", "memory");
-       if (tmp & 1)
-               __asm__ __volatile__ ("movesb %0@,%/d0\n\t"
-                        "moveb %/d0,%1@\n\t"
-                        : /* no outputs */
-                        : "a" (from), "a" (to)
-                        : "d0", "memory");
-}
-
-static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
-       switch (n) {
-               case 0:
-                       return;
-               case 1:
-                       *(char *)to = __get_user((const char *) from, 1);
-                       return;
-               case 2:
-                       *(short *)to = __get_user((const short *) from, 2);
-                       return;
-               case 3:
-                       *(short *) to = __get_user((const short *) from, 2);
-                       *((char *) to + 2) = __get_user(2+(const char *) from, 1);
-                       return;
-               case 4:
-                       *(int *) to = __get_user((const int *) from, 4);
-                       return;
-               case 8:
-                       *(int *) to = __get_user((const int *) from, 4);
-                       *(1+(int *) to) = __get_user(1+(const int *) from, 4);
-                       return;
-               case 12:
-                       *(int *) to = __get_user((const int *) from, 4);
-                       *(1+(int *) to) = __get_user(1+(const int *) from, 4);
-                       *(2+(int *) to) = __get_user(2+(const int *) from, 4);
-                       return;
-               case 16:
-                       *(int *) to = __get_user((const int *) from, 4);
-                       *(1+(int *) to) = __get_user(1+(const int *) from, 4);
-                       *(2+(int *) to) = __get_user(2+(const int *) from, 4);
-                       *(3+(int *) to) = __get_user(3+(const int *) from, 4);
-                       return;
-       }
-#define COMMON(x)                     \
-__asm__ __volatile__ ("1:\n\t"        \
-            "movesl %1@+,%/d0\n\t"    \
-            "movel %/d0,%2@+\n\t"     \
-            "dbra %0,1b\n\t"          \
-            "clrw %0\n\t"             \
-            "subql #1,%0\n\t"         \
-            "bccs 1b\n\t"             \
-            x                         \
-            : "=d" (n), "=a" (from), "=a" (to)    \
-            : "1" (from), "2" (to), "0" (n/4-1)   \
-            : "d0", "memory");
-
-  switch (n % 4) {
-      case 0:
-          COMMON("");
-          return;
-      case 1:
-          COMMON("movesb %1@+,%/d0; moveb %/d0,%2@+");
-          return;
-      case 2:
-          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+");
-          return;
-      case 3:
-          COMMON("movesw %1@+,%/d0; movew %/d0,%2@+\n\t"
-                 "movesb %1@+,%/d0; moveb %/d0,%2@+");
-          return;
-  }
-#undef COMMON
-}
-
-#define memcpy_fromfs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_fromfs((to),(from),(n)) : \
- __generic_memcpy_fromfs((to),(from),(n)))
-
-#define memcpy_tofs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_tofs((to),(from),(n)) : \
- __generic_memcpy_tofs((to),(from),(n)))
-
 /*
  * Get/set the SFC/DFC registers for MOVES instructions
  */
index ddb7180b02033dbdae6fba6a8029e38810d54acb..ef23201c338b1398f1d42d73160837261a5659eb 100644 (file)
@@ -20,8 +20,8 @@ struct semaphore {
 #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 void up_wakeup(void /* special register calling convention */);
+asmlinkage void __down_failed(void /* special register calling convention */);
+asmlinkage void __up_wakeup(void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
@@ -35,14 +35,14 @@ extern inline void down(struct semaphore * sem)
 {
        register struct semaphore *sem1 __asm__ ("%a1") = sem;
        __asm__ __volatile__(
-               "# atomic down operation\n"
-               "1:\n\t"
-               "lea %%pc@(1b),%%a0\n\t"
+               "| atomic down operation\n\t"
+               "lea %%pc@(1f),%%a0\n\t"
                "subql #1,%0\n\t"
-               "jmi " SYMBOL_NAME_STR(down_failed)
+               "jmi " SYMBOL_NAME_STR(__down_failed) "\n"
+               "1:"
                : /* no outputs */
                : "m" (sem->count), "a" (sem1)
-               : "%a0", "%d0", "%d1", "memory");
+               : "%a0", "memory");
 }
 
 /*
@@ -55,14 +55,14 @@ extern inline void up(struct semaphore * sem)
 {
        register struct semaphore *sem1 __asm__ ("%a1") = sem;
        __asm__ __volatile__(
-               "# atomic up operation\n\t"
+               "| atomic up operation\n\t"
                "lea %%pc@(1f),%%a0\n\t"
                "addql #1,%0\n\t"
-               "jls " SYMBOL_NAME_STR(up_wakeup) "\n"
+               "jle " SYMBOL_NAME_STR(__up_wakeup) "\n"
                "1:"
                : /* no outputs */
                : "m" (sem->count), "a" (sem1)
-               : "%a0", "%d0", "%d1", "memory");
+               : "%a0", "memory");
 }
 
 #endif
index 9f06ee183089012d393d87951279b98bbbb680bc..a2d28c218a4ec37bb1ddcf439643e611194e2c3f 100644 (file)
@@ -1,7 +1,7 @@
-#ifndef _ASMm68k_SIGCONTEXT_H
-#define _ASMm68k_SIGCONTEXT_H
+#ifndef _ASM_M68k_SIGCONTEXT_H
+#define _ASM_M68k_SIGCONTEXT_H
 
-struct sigcontext_struct {
+struct sigcontext {
        unsigned long  sc_mask;         /* old sigmask */
        unsigned long  sc_usp;          /* old user stack pointer */
        unsigned long  sc_d0;
index fafe33befe3b4a94aa54f2b9d8c2ec61dd66da71..919520ff1397d49e27128a048b8e7245098850ae 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _M68K_STAT_H
 #define _M68K_STAT_H
 
-struct old_stat {
+struct __old_kernel_stat {
        unsigned short st_dev;
        unsigned short st_ino;
        unsigned short st_mode;
@@ -15,7 +15,7 @@ struct old_stat {
        unsigned long  st_ctime;
 };
 
-struct new_stat {
+struct stat {
        unsigned short st_dev;
        unsigned short __pad1;
        unsigned long st_ino;
diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h
new file mode 100644 (file)
index 0000000..50ff178
--- /dev/null
@@ -0,0 +1,799 @@
+#ifndef __M68K_UACCESS_H
+#define __M68K_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+/* We let the MMU do all checking */
+#define access_ok(type,addr,size) 1
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+       return access_ok(type,addr,size)?0:-EFAULT;
+}
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue.  No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path.  This means when everything is well,
+ * we don't even have to jump over them.  Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+       unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ */
+
+#define put_user(x, ptr)                               \
+({                                                     \
+    int __pu_err;                                      \
+    typeof(*(ptr)) __pu_val = (x);                     \
+    switch (sizeof (*(ptr))) {                         \
+    case 1:                                            \
+       __put_user_asm(__pu_err, __pu_val, ptr, b);     \
+       break;                                          \
+    case 2:                                            \
+       __put_user_asm(__pu_err, __pu_val, ptr, w);     \
+       break;                                          \
+    case 4:                                            \
+       __put_user_asm(__pu_err, __pu_val, ptr, l);     \
+       break;                                          \
+    default:                                           \
+       __pu_err = __put_user_bad();                    \
+       break;                                          \
+    }                                                  \
+    __pu_err;                                          \
+})
+#define __put_user(x, ptr) put_user(x, ptr)
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+#define __put_user_asm(err,x,ptr,bwl)                  \
+__asm__ __volatile__                                   \
+    ("21:moves" #bwl " %2,%1\n"                                \
+     "1:\n"                                            \
+     ".section .fixup,\"ax\"\n"                                \
+     "   .even\n"                                      \
+     "2: movel %3,%0\n"                                        \
+     "   jra 1b\n"                                     \
+     ".section __ex_table,\"a\"\n"                     \
+     "   .align 4\n"                                   \
+     "   .long 21b,2b\n"                               \
+     "   .long 1b,2b\n"                                        \
+     ".text"                                           \
+     : "=d"(err)                                       \
+     : "m"(*(ptr)), "r"(x), "i"(-EFAULT), "0"(0))
+
+#define get_user(x, ptr)                                       \
+({                                                             \
+    int __gu_err;                                              \
+    typeof(*(ptr)) __gu_val;                                   \
+    switch (sizeof(*(ptr))) {                                  \
+    case 1:                                                    \
+       __get_user_asm(__gu_err, __gu_val, ptr, b, "=d");       \
+       break;                                                  \
+    case 2:                                                    \
+       __get_user_asm(__gu_err, __gu_val, ptr, w, "=r");       \
+       break;                                                  \
+    case 4:                                                    \
+       __get_user_asm(__gu_err, __gu_val, ptr, l, "=r");       \
+       break;                                                  \
+    default:                                                   \
+       __gu_val = 0;                                           \
+       __gu_err = __get_user_bad();                            \
+       break;                                                  \
+    }                                                          \
+    (x) = __gu_val;                                            \
+    __gu_err;                                                  \
+})
+#define __get_user(x, ptr) get_user(x, ptr)
+
+extern int __get_user_bad(void);
+
+#define __get_user_asm(err,x,ptr,bwl,reg)      \
+__asm__ __volatile__                           \
+    ("1: moves" #bwl " %2,%1\n"                        \
+     "2:\n"                                    \
+     ".section .fixup,\"ax\"\n"                        \
+     "   .even\n"                              \
+     "3: movel %3,%0\n"                                \
+     "   sub" #bwl " %1,%1\n"                  \
+     "   jra 2b\n"                             \
+     ".section __ex_table,\"a\"\n"             \
+     "   .align 4\n"                           \
+     "   .long 1b,3b\n"                                \
+     ".text"                                   \
+     : "=d"(err), reg(x)                       \
+     : "m"(*(ptr)), "i" (-EFAULT), "0"(0))
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+    unsigned long tmp;
+    __asm__ __volatile__
+       ("   tstl %2\n"
+        "   jeq 2f\n"
+        "1: movesl (%1)+,%3\n"
+        "   movel %3,(%0)+\n"
+        "   subql #1,%2\n"
+        "   jne 1b\n"
+        "2: movel %4,%2\n"
+        "   bclr #1,%2\n"
+        "   jeq 4f\n"
+        "3: movesw (%1)+,%3\n"
+        "   movew %3,(%0)+\n"
+        "4: bclr #0,%2\n"
+        "   jeq 6f\n"
+        "5: movesb (%1)+,%3\n"
+        "   moveb %3,(%0)+\n"
+        "6:\n"
+        ".section .fixup,\"ax\"\n"
+        "   .even\n"
+        "7: lsll #2,%2\n"
+        "   addl %4,%2\n"
+        "   jra 6b\n"
+        "8: addql #2,%2\n"
+        "   jra 6b\n"
+        "9: addql #1,%2\n"
+        "   jra 6b\n"
+        ".section __ex_table,\"a\"\n"
+        "   .align 4\n"
+        "   .long 1b,7b\n"
+        "   .long 3b,8b\n"
+        "   .long 5b,9b\n"
+        ".text"
+        : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+        : "r"(n & 3), "0"(to), "1"(from), "2"(n/4)
+        : "d0", "memory");
+    return n;
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+    unsigned long tmp;
+    __asm__ __volatile__
+       ("   tstl %2\n"
+        "   jeq 3f\n"
+        "1: movel (%1)+,%3\n"
+        "22:movesl %3,(%0)+\n"
+        "2: subql #1,%2\n"
+        "   jne 1b\n"
+        "3: movel %4,%2\n"
+        "   bclr #1,%2\n"
+        "   jeq 4f\n"
+        "   movew (%1)+,%3\n"
+        "24:movesw %3,(%0)+\n"
+        "4: bclr #0,%2\n"
+        "   jeq 5f\n"
+        "   moveb (%1)+,%3\n"
+        "25:movesb %3,(%0)+\n"
+        "5:\n"
+        ".section .fixup,\"ax\"\n"
+        "   .even\n"
+        "6: lsll #2,%2\n"
+        "   addl %4,%2\n"
+        "   jra 5b\n"
+        "7: addql #2,%2\n"
+        "   jra 5b\n"
+        "8: addql #1,%2\n"
+        "   jra 5b\n"
+        ".section __ex_table,\"a\"\n"
+        "   .align 4\n"
+        "   .long 22b,6b\n"
+        "   .long 2b,6b\n"
+        "   .long 24b,7b\n"
+        "   .long 4b,7b\n"
+        "   .long 25b,8b\n"
+        "   .long 5b,8b\n"
+        ".text"
+        : "=a"(to), "=a"(from), "=d"(n), "=&d"(tmp)
+        : "r"(n & 3), "0"(to), "1"(from), "2"(n / 4));
+    return n;
+}
+
+#define __copy_from_user_big(to, from, n, fixup, copy) \
+    __asm__ __volatile__                               \
+       ("10: movesl (%1)+,%%d0\n"                      \
+        "    movel %%d0,(%0)+\n"                       \
+        "    subql #1,%2\n"                            \
+        "    jne 10b\n"                                \
+        ".section .fixup,\"ax\"\n"                     \
+        "    .even\n"                                  \
+        "11: lsll #2,%2\n"                             \
+        fixup "\n"                                     \
+        "    jra 12f\n"                                \
+        ".section __ex_table,\"a\"\n"                  \
+        "    .align 4\n"                               \
+        "    .long 10b,11b\n"                          \
+        ".text\n"                                      \
+        copy "\n"                                      \
+        ".text\n"                                      \
+        "12:"                                          \
+        : "=a"(to), "=a"(from), "=d"(n)                \
+        : "0"(to), "1"(from), "2"(n/4)                 \
+        : "d0", "memory")
+
+static inline unsigned long
+__constant_copy_from_user(void *to, const void *from, unsigned long n)
+{
+    switch (n) {
+    case 0:
+       break;
+    case 1:
+       __asm__ __volatile__
+           ("1: movesb (%1)+,%%d0\n"
+            "   moveb %%d0,(%0)+\n"
+            "2:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "3: addql #1,%2\n"
+            "   jra 2b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,3b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 2:
+       __asm__ __volatile__
+           ("1: movesw (%1)+,%%d0\n"
+            "   movew %%d0,(%0)+\n"
+            "2:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "3: addql #2,%2\n"
+            "   jra 2b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,3b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 3:
+       __asm__ __volatile__
+           ("1: movesw (%1)+,%%d0\n"
+            "   movew %%d0,(%0)+\n"
+            "2: movesb (%1)+,%%d0\n"
+            "   moveb %%d0,(%0)+\n"
+            "3:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "4: addql #2,%2\n"
+            "5: addql #1,%2\n"
+            "   jra 3b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,4b\n"
+            "   .long 2b,5b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 4:
+       __asm__ __volatile__
+           ("1: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "2:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "3: addql #4,%2\n"
+            "   jra 2b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,3b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 8:
+       __asm__ __volatile__
+           ("1: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "2: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "3:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "4: addql #4,%2\n"
+            "5: addql #4,%2\n"
+            "   jra 3b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,4b\n"
+            "   .long 2b,5b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 12:
+       __asm__ __volatile__
+           ("1: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "2: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "3: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "4:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "5: addql #4,%2\n"
+            "6: addql #4,%2\n"
+            "7: addql #4,%2\n"
+            "   jra 4b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,5b\n"
+            "   .long 2b,6b\n"
+            "   .long 3b,7b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 16:
+       __asm__ __volatile__
+           ("1: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "2: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "3: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "4: movesl (%1)+,%%d0\n"
+            "   movel %%d0,(%0)+\n"
+            "5:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "6: addql #4,%2\n"
+            "7: addql #4,%2\n"
+            "8: addql #4,%2\n"
+            "9: addql #4,%2\n"
+            "   jra 5b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 1b,6b\n"
+            "   .long 2b,7b\n"
+            "   .long 3b,8b\n"
+            "   .long 4b,9b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    default:
+       switch (n & 3) {
+       case 0:
+           __copy_from_user_big(to, from, n, "", "");
+           break;
+       case 1:
+           __copy_from_user_big(to, from, n,
+                                /* fixup */
+                                "1: addql #1,%2",
+                                /* copy */
+                                "2: movesb (%1)+,%%d0\n"
+                                "   moveb %%d0,(%0)+\n"
+                                ".section __ex_table,\"a\"\n"
+                                "   .long 2b,1b");
+           break;
+       case 2:
+           __copy_from_user_big(to, from, n,
+                                /* fixup */
+                                "1: addql #2,%2",
+                                /* copy */
+                                "2: movesw (%1)+,%%d0\n"
+                                "   movew %%d0,(%0)+\n"
+                                ".section __ex_table,\"a\"\n"
+                                "   .long 2b,1b");
+           break;
+       case 3:
+           __copy_from_user_big(to, from, n,
+                                /* fixup */
+                                "1: addql #2,%2"
+                                "2: addql #1,%2",
+                                /* copy */
+                                "3: movesw (%1)+,%%d0\n"
+                                "   movew %%d0,(%0)+\n"
+                                "4: movesb (%1)+,%%d0\n"
+                                "   moveb %%d0,(%0)+\n"
+                                ".section __ex_table,\"a\"\n"
+                                "   .long 3b,1b\n"
+                                "   .long 4b,2b");
+           break;
+       }
+       break;
+    }
+    return n;
+}
+
+#define __copy_to_user_big(to, from, n, fixup, copy)   \
+    __asm__ __volatile__                               \
+       ("10: movel (%1)+,%%d0\n"                       \
+        "31: movesl %%d0,(%0)+\n"                      \
+        "11: subql #1,%2\n"                            \
+        "    jne 10b\n"                                \
+        ".section .fixup,\"ax\"\n"                     \
+        "   .even\n"                                   \
+        "12: lsll #2,%2\n"                             \
+        fixup "\n"                                     \
+        "    jra 13f\n"                                \
+        ".section __ex_table,\"a\"\n"                  \
+        "    .align 4\n"                               \
+        "    .long 31b,12b\n"                          \
+        "    .long 11b,12b\n"                          \
+        ".text\n"                                      \
+        copy "\n"                                      \
+        ".text\n"                                      \
+        "13:"                                          \
+        : "=a"(to), "=a"(from), "=d"(n)                \
+        : "0"(to), "1"(from), "2"(n/4)                 \
+        : "d0")
+
+static inline unsigned long
+__constant_copy_to_user(void *to, const void *from, unsigned long n)
+{
+    switch (n) {
+    case 0:
+       break;
+    case 1:
+       __asm__ __volatile__
+           ("   moveb (%1)+,%%d0\n"
+            "21:movesb %%d0,(%0)+\n"
+            "1:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "2: addql #1,%2\n"
+            "   jra 1b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n  "
+            "   .long 21b,2b\n"
+            "   .long 1b,2b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 2:
+       __asm__ __volatile__
+           ("   movew (%1)+,%%d0\n"
+            "21:movesw %%d0,(%0)+\n"
+            "1:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "2: addql #2,%2\n"
+            "   jra 1b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,2b\n"
+            "   .long 1b,2b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 3:
+       __asm__ __volatile__
+           ("   movew (%1)+,%%d0\n"
+            "21:movesw %%d0,(%0)+\n"
+            "1: moveb (%1)+,%%d0\n"
+            "22:movesb %%d0,(%0)+\n"
+            "2:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "3: addql #2,%2\n"
+            "4: addql #1,%2\n"
+            "   jra 2b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,3b\n"
+            "   .long 1b,3b\n"
+            "   .long 22b,4b\n"
+            "   .long 2b,4b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 4:
+       __asm__ __volatile__
+           ("   movel (%1)+,%%d0\n"
+            "21:movesl %%d0,(%0)+\n"
+            "1:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "2: addql #4,%2\n"
+            "   jra 1b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,2b\n"
+            "   .long 1b,2b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 8:
+       __asm__ __volatile__
+           ("   movel (%1)+,%%d0\n"
+            "21:movesl %%d0,(%0)+\n"
+            "1: movel (%1)+,%%d0\n"
+            "22:movesl %%d0,(%0)+\n"
+            "2:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "3: addql #4,%2\n"
+            "4: addql #4,%2\n"
+            "   jra 2b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,3b\n"
+            "   .long 1b,3b\n"
+            "   .long 22b,4b\n"
+            "   .long 2b,4b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 12:
+       __asm__ __volatile__
+           ("   movel (%1)+,%%d0\n"
+            "21:movesl %%d0,(%0)+\n"
+            "1: movel (%1)+,%%d0\n"
+            "22:movesl %%d0,(%0)+\n"
+            "2: movel (%1)+,%%d0\n"
+            "23:movesl %%d0,(%0)+\n"
+            "3:\n"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "4: addql #4,%2\n"
+            "5: addql #4,%2\n"
+            "6: addql #4,%2\n"
+            "   jra 3b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,4b\n"
+            "   .long 1b,4b\n"
+            "   .long 22b,5b\n"
+            "   .long 2b,5b\n"
+            "   .long 23b,6b\n"
+            "   .long 3b,6b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    case 16:
+       __asm__ __volatile__
+           ("   movel (%1)+,%%d0\n"
+            "21:movesl %%d0,(%0)+\n"
+            "1: movel (%1)+,%%d0\n"
+            "22:movesl %%d0,(%0)+\n"
+            "2: movel (%1)+,%%d0\n"
+            "23:movesl %%d0,(%0)+\n"
+            "3: movel (%1)+,%%d0\n"
+            "24:movesl %%d0,(%0)+\n"
+            "4:"
+            ".section .fixup,\"ax\"\n"
+            "   .even\n"
+            "5: addql #4,%2\n"
+            "6: addql #4,%2\n"
+            "7: addql #4,%2\n"
+            "8: addql #4,%2\n"
+            "   jra 4b\n"
+            ".section __ex_table,\"a\"\n"
+            "   .align 4\n"
+            "   .long 21b,5b\n"
+            "   .long 1b,5b\n"
+            "   .long 22b,6b\n"
+            "   .long 2b,6b\n"
+            "   .long 23b,7b\n"
+            "   .long 3b,7b\n"
+            "   .long 24b,8b\n"
+            "   .long 4b,8b\n"
+            ".text"
+            : "=a"(to), "=a"(from), "=d"(n)
+            : "0"(to), "1"(from), "2"(0)
+            : "d0", "memory");
+       break;
+    default:
+       switch (n & 3) {
+       case 0:
+           __copy_to_user_big(to, from, n, "", "");
+           break;
+       case 1:
+           __copy_to_user_big(to, from, n,
+                              /* fixup */
+                              "1: addql #1,%2",
+                              /* copy */
+                              "   moveb (%1)+,%%d0\n"
+                              "22:movesb %%d0,(%0)+\n"
+                              "2:"
+                              ".section __ex_table,\"a\"\n"
+                              "   .long 22b,1b\n"
+                              "   .long 2b,1b");
+           break;
+       case 2:
+           __copy_to_user_big(to, from, n,
+                              /* fixup */
+                              "1: addql #2,%2",
+                              /* copy */
+                              "   movew (%1)+,%%d0\n"
+                              "22:movesw %%d0,(%0)+\n"
+                              "2:"
+                              ".section __ex_table,\"a\"\n"
+                              "   .long 22b,1b\n"
+                              "   .long 2b,1b");
+           break;
+       case 3:
+           __copy_to_user_big(to, from, n,
+                              /* fixup */
+                              "1: addql #2,%2"
+                              "2: addql #1,%2",
+                              /* copy */
+                              "   movew (%1)+,%%d0\n"
+                              "23:movesw %%d0,(%0)+\n"
+                              "3: moveb (%1)+,%%d0\n"
+                              "24:movesb %%d0,(%0)+\n"
+                              "4:"
+                              ".section __ex_table,\"a\"\n"
+                              "   .long 23b,1b\n"
+                              "   .long 3b,1b\n"
+                              "   .long 24b,2b\n"
+                              "   .long 4b,2b");
+           break;
+       }
+       break;
+    }
+    return n;
+}
+
+#define copy_from_user(to, from, n)            \
+(__builtin_constant_p(n) ?                     \
+ __constant_copy_from_user(to, from, n) :      \
+ __generic_copy_from_user(to, from, n))
+
+#define copy_to_user(to, from, n)              \
+(__builtin_constant_p(n) ?                     \
+ __constant_copy_to_user(to, from, n) :                \
+ __generic_copy_to_user(to, from, n))
+
+/*
+ * Copy a null terminated string from userspace.
+ */
+
+static inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+    long res;
+    if (count == 0) return count;
+    __asm__ __volatile__
+       ("1: movesb (%2)+,%%d0\n"
+        "12:moveb %%d0,(%1)+\n"
+        "   jeq 2f\n"
+        "   subql #1,%3\n"
+        "   jne 1b\n"
+        "2: subl %3,%0\n"
+        "3:\n"
+        ".section .fixup,\"ax\"\n"
+        "   .even\n"
+        "4: movel %4,%0\n"
+        "   jra 3b\n"
+        ".section __ex_table,\"a\"\n"
+        "   .align 4\n"
+        "   .long 1b,4b\n"
+        "   .long 12b,4b\n"
+        ".text"
+        : "=d"(res), "=a"(dst), "=a"(src), "=d"(count)
+        : "i"(-EFAULT), "0"(count), "1"(dst), "2"(src), "3"(count)
+        : "d0", "memory");
+    return res;
+}
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 for error
+ */
+static inline long strlen_user(const char * src)
+{
+    long res = (long) src;
+    __asm__ __volatile__
+       ("1: movesb (%1)+,%%d0\n"
+        "12:tstb %%d0\n"
+        "   jne 1b\n"
+        "   subl %1,%0\n"
+        "   negl %0\n"
+        "2:\n"
+        ".section .fixup,\"ax\"\n"
+        "   .even\n"
+        "3: moveq %2,%0\n"
+        "   jra 2b\n"
+        ".section __ex_table,\"a\"\n"
+        "   .align 4\n"
+        "   .long 1b,3b\n"
+        "   .long 12b,3b\n"
+        ".text"
+        : "=d"(res), "=a"(src)
+        : "i"(0), "0"(res), "1"(src)
+        : "d0", "memory");
+    return res;
+}
+
+/*
+ * Zero Userspace
+ */
+
+static inline unsigned long
+clear_user(void *to, unsigned long n)
+{
+    __asm__ __volatile__
+       ("   tstl %1\n"
+        "   jeq 3f\n"
+        "1: movesl %3,(%0)+\n"
+        "2: subql #1,%1\n"
+        "   jne 1b\n"
+        "3: movel %2,%1\n"
+        "   bclr #1,%1\n"
+        "   jeq 4f\n"
+        "24:movesw %3,(%0)+\n"
+        "4: bclr #0,%1\n"
+        "   jeq 5f\n"
+        "25:movesb %3,(%0)+\n"
+        "5:\n"
+        ".section .fixup,\"ax\"\n"
+        "   .even\n"
+        "6: lsll #2,%1\n"
+        "   addl %2,%1\n"
+        "   jra 5b\n"
+        "7: addql #2,%1\n"
+        "   jra 5b\n"
+        "8: addql #1,%1\n"
+        "   jra 5b\n"
+        ".section __ex_table,\"a\"\n"
+        "   .align 4\n"
+        "   .long 1b,6b\n"
+        "   .long 2b,6b\n"
+        "   .long 24b,7b\n"
+        "   .long 4b,7b\n"
+        "   .long 25b,8b\n"
+        "   .long 5b,8b\n"
+        ".text"
+        : "=a"(to), "=d"(n)
+        : "r"(n & 3), "r"(0), "0"(to), "1"(n/4));
+    return n;
+}
+
+#endif /* _M68K_UACCESS_H */
index 265494aec39b404ecb13f5a5265ed715b90c3bf9..b55f296a782cb6f923807838ea1bdd299d9fbbcf 100644 (file)
 #define __NR_sched_rr_get_interval     161
 #define __NR_nanosleep         162
 #define __NR_mremap            163
+#define __NR_setresuid         164
+#define __NR_getresuid         165
 
-#ifdef __ELF__
+/* 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); \
+               res = -1; \
+       } \
+       return (type) (res); \
+} while (0)
 
 #define _syscall0(type,name) \
 type name(void) \
@@ -178,223 +190,84 @@ type name(void) \
 register long __res __asm__ ("%d0") = __NR_##name; \
 __asm__ __volatile__ ("trap  #0" \
                       : "=g" (__res) \
-                      : "0" (__NR_##name) \
+                     : "0" (__res) \
                      : "%d0"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
+__syscall_return(type,__res); \
 }
 
 #define _syscall1(type,name,atype,a) \
 type name(atype a) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)) \
-                      : "%d0", "%d1"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+__asm__ __volatile__ ("trap  #0" \
+                     : "=d" (__res) \
+                     : "0" (__res), "d" (__a) \
+                     : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall2(type,name,atype,a,btype,b) \
 type name(atype a,btype b) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                     "movel %3,%/d2\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)) \
-                      : "%d0", "%d1", "%d2"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+__asm__ __volatile__ ("trap  #0" \
+                     : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b) \
+                     : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
 type name(atype a,btype b,ctype c) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                     "movel %3,%/d2\n\t" \
-                     "movel %4,%/d3\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)) \
-                      : "%d0", "%d1", "%d2", "%d3"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+__asm__ __volatile__ ("trap  #0" \
+                     : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b), \
+                       "d" (__c) \
+                     : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
 type name (atype a, btype b, ctype c, dtype d) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                     "movel %3,%/d2\n\t" \
-                     "movel %4,%/d3\n\t" \
-                     "movel %5,%/d4\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                         "g" ((long)(c)), \
-                                         "g" ((long)(d))  \
-                      : "%d0", "%d1", "%d2", "%d3", "%d4"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+__asm__ __volatile__ ("trap  #0" \
+                      : "=d" (__res) \
+                      : "0" (__res), "d" (__a), "d" (__b), \
+                       "d" (__c), "d" (__d)  \
+                     : "%d0"); \
+__syscall_return(type,__res); \
 }
 
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
 type name (atype a,btype b,ctype c,dtype d,etype e) \
 { \
 register long __res __asm__ ("%d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,%/d1\n\t" \
-                     "movel %3,%/d2\n\t" \
-                     "movel %4,%/d3\n\t" \
-                     "movel %5,%/d4\n\t" \
-                     "movel %6,%/d5\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                         "g" ((long)(c)), \
-                                         "g" ((long)(d)), \
-                                         "g" ((long)(e))  \
-                      : "%d0", "%d1", "%d2", "%d3", "%d4", "%d5"); \
-if (__res >= 0) \
-       return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#else /* not ELF; a.out */
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
+register long __a __asm__ ("%d1") = (long)(a); \
+register long __b __asm__ ("%d2") = (long)(b); \
+register long __c __asm__ ("%d3") = (long)(c); \
+register long __d __asm__ ("%d4") = (long)(d); \
+register long __e __asm__ ("%d5") = (long)(e); \
 __asm__ __volatile__ ("trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name) \
-                     : "d0"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall1(type,name,atype,a) \
-type name(atype a) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)) \
-                      : "d0", "d1"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)) \
-                      : "d0", "d1", "d2"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name(atype a,btype b,ctype c) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)) \
-                      : "d0", "d1", "d2", "d3"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
+                     : "=d" (__res) \
+                     : "0" (__res), "d" (__a), "d" (__b), \
+                       "d" (__c), "d" (__d), "d" (__e)  \
+                      : "%d0"); \
+__syscall_return(type,__res); \
 }
 
-#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "movel %5,d4\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)), \
-                                          "g" ((long)(d))  \
-                      : "d0", "d1", "d2", "d3", "d4"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
-{ \
-register long __res __asm__ ("d0") = __NR_##name; \
-__asm__ __volatile__ ("movel %2,d1\n\t" \
-                      "movel %3,d2\n\t" \
-                      "movel %4,d3\n\t" \
-                      "movel %5,d4\n\t" \
-                      "movel %6,d5\n\t" \
-                      "trap  #0" \
-                      : "=g" (__res) \
-                      : "0" (__NR_##name), "g" ((long)(a)), \
-                                          "g" ((long)(b)), \
-                                          "g" ((long)(c)), \
-                                          "g" ((long)(d)), \
-                                          "g" ((long)(e))  \
-                      : "d0", "d1", "d2", "d3", "d4", "d5"); \
-if (__res >= 0) \
-        return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#endif /* ELF or otherwise */
-
 #ifdef __KERNEL_SYSCALLS__
 
 /*
@@ -437,25 +310,25 @@ static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long f
 {
        register long retval __asm__ ("d0") = __NR_clone;
        register long clone_arg __asm__ ("d1") = flags | CLONE_VM;
-       unsigned short fs;
+       unsigned long fs;
 
        fs = get_fs();
        set_fs (KERNEL_DS);
 
        __asm__ __volatile__
-         ("movel %%sp,%%d2\n\t"
-          "trap #0\n\t"                /* Linux/m68k system call */
-          "cmpl %%sp,%%d2\n\t"         /* child or parent */
-          "jeq 1f\n\t"                 /* parent - jump */
+         ("trap #0\n\t"                /* Linux/m68k system call */
+          "tstl %0\n\t"                /* child or parent */
+          "jne 1f\n\t"                 /* parent - jump */
           "movel %3,%%sp@-\n\t"        /* push argument */
           "jsr %4@\n\t"                /* call fn */
+          "movel %0,%%d1\n\t"          /* pass exit value */
           "movel %2,%0\n\t"            /* exit */
           "trap #0\n"
           "1:"
           : "=d" (retval)
           : "0" (__NR_clone), "i" (__NR_exit),
             "r" (arg), "a" (fn), "d" (clone_arg)
-          : "d0", "d2");
+          : "d0");
 
        set_fs (fs);
        return retval;
index a1eaa4a791a87eaeecb66a5e4041cae1ed637bdb..126e2354898b6c2d6181983769d2a0e1fa2e5a14 100644 (file)
@@ -35,14 +35,30 @@ struct user_m68kfp_struct {
        unsigned long  fpcntl[3];       /* fp control regs */
 };
 
+/* This is the old layout of "struct pt_regs" as of Linux 1.x, and
+   is still the layout used by user (the new pt_regs doesn't have
+   all registers). */
+struct user_regs_struct {
+       long d1,d2,d3,d4,d5,d6,d7;
+       long a0,a1,a2,a3,a4,a5,a6;
+       long d0;
+       long usp;
+       long orig_d0;
+       short stkadj;
+       short sr;
+       long pc;
+       short fmtvec;
+       short __fill;
+};
+
+       
 /* When the kernel dumps core, it starts by dumping the user struct -
    this will be used by gdb to figure out where the data and stack segments
    are within the file, and what virtual addresses to use. */
 struct user{
 /* We start with the registers, to mimic the way that "memory" is returned
    from the ptrace(3,...) function.  */
-  struct pt_regs regs;         /* Where the registers are actually stored */
-  struct switch_stack regs2;   /* Backward compatibility, sort of */
+  struct user_regs_struct regs;        /* Where the registers are actually stored */
 /* ptrace does not yet supply these.  Someday.... */
   int u_fpvalid;               /* True if math co-processor being used. */
                                 /* for this mess. Not yet used. */
index b46acff494c350556b51e0ce9b4325e1dff77f6b..adfc4617ca483ec5e28be65f0a764a3b5d357876 100644 (file)
 #define PROD_BLIZZARD_1230_III (0x0D)  /* Blizzard 1230-III Turbo Board */
 #define PROD_BLIZZARD_1230_IV  (0x11)  /* Blizzard 1230-IV/1260 Turbo Board */
 #define PROD_BLIZZARD_2060SCSI (0x18)  /* Blizzard 2060 SCSI Controller */
-#define PROD_CYBERSTORM        (0x19)  /* CyberStorm */
+#define PROD_CYBERSTORM_II     (0x19)  /* CyberStorm Mk II */
 #define PROD_CYBERVISION       (0x22)  /* CyberVision64 Graphics Board */
 
 #define MANUF_DPS              (0x2169)        /* DPS */
index f957012ba2c8090fa29470f8e1a28affb56b70d4..6c424fbe9b1a3fbb7ad751e27274f5c189ffe699 100644 (file)
@@ -18,6 +18,7 @@ struct linux_binprm{
        unsigned long page[MAX_ARG_PAGES];
        unsigned long p;
        int sh_bang;
+       int java;               /* Java binary, prevent recursive invocation */
        struct inode * inode;
        int e_uid, e_gid;
        int argc, envc;
diff --git a/include/linux/linear.h b/include/linux/linear.h
deleted file mode 100644 (file)
index b690737..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
-  struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
-  struct linear_hash *hash_table; /* Dynamically allocated */
-  struct real_dev *smallest;
-  int nr_zones;
-};
-
-#endif
-
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-struct linear_hash
-{
-  struct real_dev *dev0, *dev1;
-};
-
-struct linear_data
-{
-  struct linear_hash *hash_table; /* Dynamically allocated */
-  struct real_dev *smallest;
-  int nr_zones;
-};
-
-#endif
index 12c1de0ecc8d10441eeeeffad4404c8a37399ec1..6af5f2401e916ff7f931caab372c07e0228ec2c8 100644 (file)
@@ -308,10 +308,12 @@ static inline int expand_stack(struct vm_area_struct * vma, unsigned long addres
        unsigned long grow;
 
        address &= PAGE_MASK;
+       grow = vma->vm_start - address;
        if (vma->vm_end - address
-           > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur)
+           > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur ||
+           (vma->vm_mm->total_vm << PAGE_SHIFT) + grow
+           > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
                return -ENOMEM;
-       grow = vma->vm_start - address;
        vma->vm_start = address;
        vma->vm_offset -= grow;
        vma->vm_mm->total_vm += grow >> PAGE_SHIFT;
index 7b773780297724ec83ac09bef5805b5e21a06bff..7924ecdecff0c28b4c8a4ca7aa00082a374ce911 100644 (file)
@@ -103,7 +103,7 @@ extern int nfs_proc_read_request(struct rpc_ioreq *, struct nfs_server *,
                                 unsigned long count, __u32 *buf);
 extern int nfs_proc_read_reply(struct rpc_ioreq *, struct nfs_fattr *);
 extern int *rpc_header(int *p, int procedure, int program, int version,
-                               int uid, int gid, int *groups);
+                               int uid, int gid, int ngroup, gid_t *groups);
 extern int *rpc_verify(int *p);
 
 /* linux/fs/nfs/sock.c */
index a07b18ec7316198cc70e0b390491b4b945ef67f8..4118dfdc01f7041c251490f367c3041c7f4c8cec 100644 (file)
 #define PCI_VENDOR_ID_S3               0x5333
 #define PCI_DEVICE_ID_S3_ViRGE         0x5631
 #define PCI_DEVICE_ID_S3_TRIO          0x8811
+#define PCI_DEVICE_ID_S3_AURORA64VP    0x8812
+#define PCI_DEVICE_ID_S3_TRIO64UVP     0x8814
 #define PCI_DEVICE_ID_S3_ViRGE_VX      0x883d
 #define PCI_DEVICE_ID_S3_868           0x8880
 #define PCI_DEVICE_ID_S3_928           0x88b0
index b0fff062db79f5153f99fbc35130c2ffcdb9b028..37ec93df3fac9b1b9098a4eb36ac17ed56d7b0ed 100644 (file)
@@ -200,7 +200,8 @@ struct task_struct {
        int session;
        /* boolean value for session group leader */
        int leader;
-       int     groups[NGROUPS];
+       int ngroups;
+       gid_t groups[NGROUPS];
        /* 
         * pointers to (original) parent process, youngest child, younger sibling,
         * older sibling, respectively.  (p->father can be replaced with 
@@ -290,7 +291,7 @@ struct task_struct {
 /* stack */    0,(unsigned long) &init_kernel_stack, \
 /* ec,brk... */        0,0,0,0,0, \
 /* pid etc.. */        0,0,0,0,0, \
-/* suppl grps*/ {NOGROUP,}, \
+/* suppl grps*/ 0, {0,}, \
 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
 /* uid etc */  0,0,0,0,0,0,0,0, \
 /* timeout */  0,SCHED_OTHER,0,0,0,0,0,0,0, \
index 4d29e6ff1f43f71a92777378ef2c18029cea1747..9c8e228dc2ff9eb7f4fd54c2822b9ed2e3173dd1 100644 (file)
@@ -157,6 +157,7 @@ extern __inline__ struct cmsghdr * cmsg_nxthdr(struct msghdr *mhdr,
 #define SOL_NETROM     259
 #define SOL_ROSE       260
 #define SOL_DECNET     261
+#define        SOL_X25         262
 #define SOL_TCP                6
 #define SOL_UDP                17
 
index 5689f1435f741eb9aa1b4bdf52a7421a4839059b..b16ddb71f103b8621ee3342b8ceedf16ef501eaa 100644 (file)
@@ -134,6 +134,11 @@ struct __sysctl_args {
 #define        NET_ROSE_ROUTING_CONTROL                        6
 
 /* /proc/sys/net/x25 */
+#define        NET_X25_RESTART_REQUEST_TIMEOUT                 1
+#define        NET_X25_CALL_REQUEST_TIMEOUT                    2
+#define        NET_X25_RESET_REQUEST_TIMEOUT                   3
+#define        NET_X25_CLEAR_REQUEST_TIMEOUT                   4
+#define        NET_X25_ACK_HOLDBACK_TIMEOUT                    5
 
 /* CTL_PROC names: */
 
index 45039a0c37bb2e247055da4efbe73d768f108d18..47ee2b18d8f95c7012f6678d186070ed27f5b8e7 100644 (file)
@@ -13,8 +13,8 @@ struct cdrom_device_info {
 /* specifications */
         kdev_t dev;                    /* device number */
        int mask;                       /* mask of capability: disables them */
-       const int speed;                /* maximum speed for reading data */
-       const int capacity;             /* number of discs in jukebox */
+       int speed;                      /* maximum speed for reading data */
+       int capacity;                   /* number of discs in jukebox */
 /* device-related storage */
        int options : 30;               /* options flags */
        unsigned mc_flags : 2;          /* media change buffer flags */
index 0d8ab37fa0c683034210e8b99104ca3e8c48d1a0..10aa486d474a0b7f5f16a1e86e6567e077b2605b 100644 (file)
@@ -49,6 +49,9 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>      /* struct sk_buff */
 #include <net/protocol.h>              /* struct inet_protocol */
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+#include <net/x25.h>
+#endif
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 #include <net/ax25.h>
 #if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
@@ -427,6 +430,9 @@ struct sock
                struct tcp_opt          af_tcp;
 #endif         
 #endif
+#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
+               x25_cb                  *x25;
+#endif
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
                ax25_cb                 *ax25;
 #if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
index 412943e4d1bc9ff91e7f9f0fa7bc28c55493b23e..2bce60f38fef2194bea92f83b20eaa7141ea0c60 100644 (file)
@@ -19,7 +19,7 @@ extern void                           tcpv6_init(void);
 
 extern int                             udpv6_connect(struct sock *sk,
                                                      struct sockaddr *uaddr,
-                                                     int addr_len);
+                                                     size_t addr_len);
 
 extern int                     datagram_recv_ctl(struct sock *sk,
                                                  struct msghdr *msg,
diff --git a/include/net/x25call.h b/include/net/x25call.h
new file mode 100644 (file)
index 0000000..7c478a1
--- /dev/null
@@ -0,0 +1,2 @@
+/* Separate to keep compilation of protocols.c simpler */
+extern void x25_proto_init(struct net_proto *pro);
index e12a1f30a2b3c30676aa95ec0dd66195017d0cd4..ec408ed623a1a7e7681c94f2e9966ba0ef85afbd 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -424,7 +424,11 @@ static int shm_map (struct vm_area_struct *shmd)
        do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
 
        /* add new mapping */
-       current->mm->total_vm += (shmd->vm_end - shmd->vm_start) >> PAGE_SHIFT;
+       tmp = shmd->vm_end - shmd->vm_start;
+       if((current->mm->total_vm << PAGE_SHIFT) + tmp
+          > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur)
+               return -ENOMEM;
+       current->mm->total_vm += tmp >> PAGE_SHIFT;
        insert_vm_struct(current->mm, shmd);
        merge_segments(current->mm, shmd->vm_start, shmd->vm_end);
 
index 71297a98882e538ea674a10b538fe549f76798e4..09cee93b78c056ba1ee8d9f025fc00997ce7f039 100644 (file)
@@ -106,7 +106,7 @@ sys_create_module(char *module_name, unsigned long size)
                return -EPERM;
        if (module_name == NULL || size == 0)
                return -EINVAL;
-       if ((error = get_mod_name(module_name, name)) != 0)
+       if ((error = get_mod_name(module_name, name)) < 0)
                return error;
        if (find_module(name) != NULL) {
                return -EEXIST;
@@ -168,7 +168,7 @@ sys_init_module(char *module_name, char *code, unsigned codesize,
                symtab = NULL;
        }
 #endif
-       if ((error = get_mod_name(module_name, name)) != 0)
+       if ((error = get_mod_name(module_name, name)) < 0)
                return error;
        pr_debug("initializing module `%s', %d (0x%x) bytes\n",
                name, codesize, codesize);
@@ -292,7 +292,7 @@ sys_delete_module(char *module_name)
                return -EPERM;
        /* else */
        if (module_name != NULL) {
-               if ((error = get_mod_name(module_name, name)) != 0)
+               if ((error = get_mod_name(module_name, name)) < 0)
                        return error;
                if ((mp = find_module(name)) == NULL)
                        return -ENOENT;
index 5a0ecada2f73e3714183102bba2a44b888348974..0fe9c5c31b945e8c71dde1cef0ec8084741848a3 100644 (file)
@@ -699,20 +699,15 @@ asmlinkage int sys_setsid(void)
 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
 {
        int i;
-       int * groups;
 
        if (gidsetsize < 0)
                return -EINVAL;
-       groups = current->groups;
-       for (i = 0 ; i < NGROUPS ; i++) {
-               if (groups[i] == NOGROUP)
-                       break;
-       }
+       i = current->ngroups;
        if (gidsetsize) {
                if (i > gidsetsize)
                        return -EINVAL;
-               if (copy_to_user(grouplist, groups, sizeof(*groups)*i))
-                               return -EFAULT;
+               if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
+                       return -EFAULT;
        }
        return i;
 }
@@ -723,32 +718,34 @@ asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
 
        if (!suser())
                return -EPERM;
-       if (gidsetsize > NGROUPS)
+       if ((unsigned) gidsetsize > NGROUPS)
                return -EINVAL;
        err = copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t));
        if (err) {
-               gidsetsize = err/sizeof(gid_t); /* +1? */       
-        err = -EFAULT;
-    } 
-       if (gidsetsize < NGROUPS)
-               current->groups[gidsetsize] = NOGROUP;
+               gidsetsize = 0;
+               err = -EFAULT;
+       } 
+       current->ngroups = gidsetsize;
        return err;
 }
 
 int in_group_p(gid_t grp)
 {
-       int     i;
-
-       if (grp == current->fsgid)
-               return 1;
-
-       for (i = 0; i < NGROUPS; i++) {
-               if (current->groups[i] == NOGROUP)
-                       break;
-               if (current->groups[i] == grp)
-                       return 1;
+       if (grp != current->fsgid) {
+               int i = current->ngroups;
+               if (i) {
+                       gid_t *groups = current->groups;
+                       do {
+                               if (*groups == grp)
+                                       goto out;
+                               groups++;
+                               i--;
+                       } while (i);
+               }
+               return 0;
        }
-       return 0;
+out:
+       return 1;
 }
 
 asmlinkage int sys_newuname(struct new_utsname * name)
index 2db109b4b2f468828e234871a36e4d37fbffe6bc..3d0fbf49be0d220cf577e3809fc96d56ca613b2e 100644 (file)
@@ -229,19 +229,23 @@ extern asmlinkage int sys_sysctl(struct __sysctl_args *args)
 /* Like in_group_p, but testing against egid, not fsgid */
 static int in_egroup_p(gid_t grp)
 {
-       int     i;
-
-       if (grp == current->euid)
-               return 1;
-
-       for (i = 0; i < NGROUPS; i++) {
-               if (current->groups[i] == NOGROUP)
-                       break;
-               if (current->groups[i] == grp)
-                       return 1;
+       if (grp != current->egid) {
+               int i = current->ngroups;
+               if (i) {
+                       gid_t *groups = current->groups;
+                       do {
+                               if (*groups == grp)
+                                       goto out;
+                               groups++;
+                               i--;
+                       } while (i);
+               }
+               return 0;
        }
-       return 0;
+out:
+       return 1;
 }
+
 /* ctl_perm does NOT grant the superuser all rights automatically, because
    some sysctl variables are readonly even to root. */
 static int test_perm(int mode, int op)
index 75a7d2ad7286166a2c3794bea1e9f912b8f42aae..ac245a17f9a60f2224dcd30f23402850ad229547 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -107,11 +107,11 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
        /*
         * Ok, looks good - let it rip.
         */
-       mm->brk = brk;
-       do_mmap(NULL, oldbrk, newbrk-oldbrk,
+       if(do_mmap(NULL, oldbrk, newbrk-oldbrk,
                PROT_READ|PROT_WRITE|PROT_EXEC,
-               MAP_FIXED|MAP_PRIVATE, 0);
-       return brk;
+                  MAP_FIXED|MAP_PRIVATE, 0) != oldbrk)
+               return mm->brk;
+       return mm->brk = brk;
 }
 
 /*
@@ -253,6 +253,13 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
 
        do_munmap(addr, len);   /* Clear old maps */
 
+       /* Check against address space limit. */
+       if ((mm->total_vm << PAGE_SHIFT) + len
+           > current->rlim[RLIMIT_AS].rlim_cur) {
+               kfree(vma);
+               return -ENOMEM;
+       }
+
        /* Private writable mapping? Check memory availability.. */
        if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) {
                if (!(flags & MAP_NORESERVE) &&
index 56da75cfea84fee59a250527f4d480be55b1f99b..a3e941055542b8c6d5c3e42f51916b6fb26ef323 100644 (file)
@@ -146,6 +146,7 @@ static inline unsigned long move_vma(struct vm_area_struct * vma,
                        insert_vm_struct(current->mm, new_vma);
                        merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end);
                        do_munmap(addr, old_len);
+                       current->mm->total_vm += new_len >> PAGE_SHIFT;
                        return new_addr;
                }
                kfree(new_vma);
@@ -192,6 +193,9 @@ asmlinkage unsigned long sys_mremap(unsigned long addr,
                if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
                        return -EAGAIN;
        }
+       if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
+           > current->rlim[RLIMIT_AS].rlim_cur)
+               return -ENOMEM;
 
        /* old_len exactly to the end of the area.. */
        if (old_len == vma->vm_end - addr &&
index 751f22bfd9fa2c84bceca9faf449acdf12275ea4..834001fdc4b1568c0c895851f83cfe19930a532f 100644 (file)
@@ -30,6 +30,7 @@ if [ "$CONFIG_AX25" != "n" ]; then
   dep_tristate 'Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+# tristate 'CCITT X.25 Packet Layer' CONFIG_X25
   bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
 fi
 endmenu
index 0603f7dd58429aceb0d72e6307f73f0132c7d2bf..d5c8322bab5899bc35a6de4b1a16b706dd817495 100644 (file)
@@ -279,8 +279,9 @@ static void ax25_kill_by_device(struct device *dev)
                        s->state  = AX25_STATE_0;
                        s->device = NULL;
                        if (s->sk != NULL) {
-                               s->sk->state = TCP_CLOSE;
-                               s->sk->err   = ENETUNREACH;
+                               s->sk->state     = TCP_CLOSE;
+                               s->sk->err       = ENETUNREACH;
+                               s->sk->shutdown |= SEND_SHUTDOWN;
                                if (!s->sk->dead)
                                        s->sk->state_change(s->sk);
                                s->sk->dead  = 1;
@@ -617,8 +618,9 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void *arg)
                                
                        ax25->state = AX25_STATE_0;
                        if (ax25->sk != NULL) {
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = ENETRESET;
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = ENETRESET;
+                               ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
                                ax25->sk->dead  = 1;
@@ -1295,6 +1297,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                switch (sk->protinfo.ax25->state) {
                        case AX25_STATE_0:
                                sk->state       = TCP_CLOSE;
+                               sk->shutdown   |= SEND_SHUTDOWN;
                                sk->state_change(sk);
                                sk->dead        = 1;
                                ax25_destroy_socket(sk->protinfo.ax25);
@@ -1304,6 +1307,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                                ax25_send_control(sk->protinfo.ax25, DISC, POLLON, C_COMMAND);
                                sk->protinfo.ax25->state = AX25_STATE_0;
                                sk->state                = TCP_CLOSE;
+                               sk->shutdown            |= SEND_SHUTDOWN;
                                sk->state_change(sk);
                                sk->dead                 = 1;
                                ax25_destroy_socket(sk->protinfo.ax25);
@@ -1316,6 +1320,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                                        ax25_send_control(sk->protinfo.ax25, DM, POLLON, C_RESPONSE);
                                sk->protinfo.ax25->state = AX25_STATE_0;
                                sk->state                = TCP_CLOSE;
+                               sk->shutdown            |= SEND_SHUTDOWN;
                                sk->state_change(sk);
                                sk->dead                 = 1;
                                ax25_destroy_socket(sk->protinfo.ax25);
@@ -1334,6 +1339,7 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                                sk->protinfo.ax25->t1timer = sk->protinfo.ax25->t1 = ax25_calculate_t1(sk->protinfo.ax25);
                                sk->protinfo.ax25->state   = AX25_STATE_2;
                                sk->state                  = TCP_CLOSE;
+                               sk->shutdown              |= SEND_SHUTDOWN;
                                sk->state_change(sk);
                                sk->dead                   = 1;
                                sk->destroy                = 1;
@@ -1344,8 +1350,9 @@ static int ax25_release(struct socket *sock, struct socket *peer)
                }
        } else {
                sk->state       = TCP_CLOSE;
+               sk->shutdown   |= SEND_SHUTDOWN;
                sk->state_change(sk);
-               sk->dead = 1;
+               sk->dead        = 1;
                ax25_destroy_socket(sk->protinfo.ax25);
        }
 
@@ -1965,8 +1972,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
        if (sk->zapped)
                return -EADDRNOTAVAIL;
                
-       if (sk->shutdown & SEND_SHUTDOWN)
-       {
+       if (sk->shutdown & SEND_SHUTDOWN) {
                send_sig(SIGPIPE, current, 0);
                return -EPIPE;
        }
@@ -2122,12 +2128,13 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n
                skb->h.raw = skb->data;
        }
 
-       copied=size;
-       if(copied>length)
-       {
-               copied = length;
-               msg->msg_flags|=MSG_TRUNC;
+       copied = length;
+
+       if (copied > size) {
+               copied = size;
+               msg->msg_flags |= MSG_TRUNC;
        }               
+
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
        
        if (sax) {
index e77378098ad659b31a4779470babaf89d7a453e9..b0c16dabe04acbcf8e74f4f7db6c9ef97797ea15 100644 (file)
@@ -243,12 +243,12 @@ static int ax25_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                                        ax25_clear_queues(ax25);
                                        ax25->state = AX25_STATE_0;
                                        if (ax25->sk != NULL) {
-                                               ax25->sk->state = TCP_CLOSE;
-                                               ax25->sk->err   = ECONNREFUSED;
+                                               ax25->sk->state     = TCP_CLOSE;
+                                               ax25->sk->err       = ECONNREFUSED;
                                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                                if (!ax25->sk->dead)
                                                        ax25->sk->state_change(ax25->sk);
-                                               ax25->sk->dead  = 1;
+                                               ax25->sk->dead      = 1;
                                        }
                                } else {
                                        ax25->modulus = MODULUS;
@@ -286,14 +286,13 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        if (ax25->dama_slave) {
                                ax25->state = AX25_STATE_0;
                                ax25_dama_off(ax25);
-
                                if (ax25->sk != NULL) {
-                                       ax25->sk->state = TCP_CLOSE;
-                                       ax25->sk->err   = 0;
+                                       ax25->sk->state     = TCP_CLOSE;
+                                       ax25->sk->err       = 0;
                                        ax25->sk->shutdown |= SEND_SHUTDOWN;
                                        if (!ax25->sk->dead)
                                                ax25->sk->state_change(ax25->sk);
-                                       ax25->sk->dead  = 1;
+                                       ax25->sk->dead      = 1;
                                }
                        }
                        break;
@@ -302,14 +301,13 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        if (pf) {
                                ax25->state = AX25_STATE_0;
                                ax25_dama_off(ax25);
-
                                if (ax25->sk != NULL) {
-                                       ax25->sk->state = TCP_CLOSE;
-                                       ax25->sk->err   = 0;
+                                       ax25->sk->state     = TCP_CLOSE;
+                                       ax25->sk->err       = 0;
                                        ax25->sk->shutdown |= SEND_SHUTDOWN;
                                        if (!ax25->sk->dead)
                                                ax25->sk->state_change(ax25->sk);
-                                       ax25->sk->dead  = 1;
+                                       ax25->sk->dead      = 1;
                                }
                        }
                        break;
@@ -318,14 +316,13 @@ static int ax25_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        if (pf) {
                                ax25->state = AX25_STATE_0;
                                ax25_dama_off(ax25);
-                                       
                                if (ax25->sk != NULL) {
-                                       ax25->sk->state = TCP_CLOSE;
-                                       ax25->sk->err   = 0;
-                                       ax25->sk->shutdown|=SEND_SHUTDOWN;
+                                       ax25->sk->state     = TCP_CLOSE;
+                                       ax25->sk->err       = 0;
+                                       ax25->sk->shutdown |= SEND_SHUTDOWN;
                                        if (!ax25->sk->dead)
                                                ax25->sk->state_change(ax25->sk);
-                                       ax25->sk->dead  = 1;
+                                       ax25->sk->dead      = 1;
                                }
                        }
                        break;
@@ -361,7 +358,6 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
        switch (frametype) {
                case SABM:
                        if (dama) ax25_dama_on(ax25);
-                               
                        ax25->modulus   = MODULUS;
                        ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
                        ax25_send_control(ax25, UA, pf, C_RESPONSE);
@@ -377,7 +373,6 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
 
                case SABME:
                        if (dama) ax25_dama_on(ax25);
-                               
                        ax25->modulus   = EMODULUS;
                        ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
                        ax25_send_control(ax25, UA, pf, C_RESPONSE);
@@ -397,14 +392,13 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        ax25->t3timer = 0;
                        ax25->state   = AX25_STATE_0;
                        ax25_dama_off(ax25);
-                       
                        if (ax25->sk != NULL) {
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = 0;
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = 0;
+                               ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
-                               ax25->sk->dead  = 1;
-                               ax25->sk->shutdown|=SEND_SHUTDOWN;
+                               ax25->sk->dead      = 1;
                        }
                        break;
 
@@ -413,13 +407,13 @@ static int ax25_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        ax25->t3timer = 0;
                        ax25->state   = AX25_STATE_0;
                        ax25_dama_off(ax25);
-                       if (ax25->sk) {
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = ECONNRESET;
+                       if (ax25->sk != NULL) {
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = ECONNRESET;
                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
-                               ax25->sk->dead         = 1;
+                               ax25->sk->dead      = 1;
                        }
                        break;
 
@@ -556,7 +550,6 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
        switch (frametype) {
                case SABM:
                        if (dama) ax25_dama_on(ax25);
-                               
                        ax25->dama_slave = dama;
                        ax25->modulus   = MODULUS;
                        ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_WINDOW);
@@ -574,7 +567,6 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
 
                case SABME:
                        if (dama) ax25_dama_on(ax25);
-                               
                        ax25->dama_slave = dama;
                        ax25->modulus   = EMODULUS;
                        ax25->window    = ax25_dev_get_value(ax25->device, AX25_VALUES_EWINDOW);
@@ -596,14 +588,13 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        ax25->t3timer = 0;
                        ax25->state   = AX25_STATE_0;
                        ax25_dama_off(ax25);
-                       
                        if (ax25->sk != NULL) {
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = 0;
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = 0;
                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
-                               ax25->sk->dead  = 1;
+                               ax25->sk->dead      = 1;
                        }
                        break;
 
@@ -612,14 +603,13 @@ static int ax25_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype
                        ax25->t3timer = 0;
                        ax25->state   = AX25_STATE_0;
                        ax25_dama_off(ax25);
-                       
                        if (ax25->sk != NULL) {
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = ECONNRESET;
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = ECONNRESET;
                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
-                               ax25->sk->dead  = 1;
+                               ax25->sk->dead      = 1;
                        }
                        break;
 
@@ -804,10 +794,8 @@ int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama
                return queued;
 
        if (ax25->state != AX25_STATE_1 && ax25->state != AX25_STATE_2 &&
-           ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4) {
-               printk("ax25_process_rx_frame: frame received - state = %d\n", ax25->state);
+           ax25->state != AX25_STATE_3 && ax25->state != AX25_STATE_4)
                return queued;
-       }
 
        del_timer(&ax25->timer);
 
index 4bc52bd5ddfa4fdb95e816b24f7714544112a82f..be265b344c57e542fd7a692e3ac1bf4fcfb71425 100644 (file)
@@ -257,11 +257,12 @@ void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
 
        if (ax25->device == NULL) {
                if (ax25->sk != NULL) {
-                       ax25->sk->state = TCP_CLOSE;
-                       ax25->sk->err   = ENETUNREACH;
+                       ax25->sk->state     = TCP_CLOSE;
+                       ax25->sk->err       = ENETUNREACH;
+                       ax25->sk->shutdown |= SEND_SHUTDOWN;
                        if (!ax25->sk->dead)
                                ax25->sk->state_change(ax25->sk);
-                       ax25->sk->dead  = 1;
+                       ax25->sk->dead      = 1;
                }
                return;
        }
index af5f83e4e8863f306198b5bf4e74cfce67b3f9ee..b4606111ec2271e5a054ca775fecf191fc744c9d 100644 (file)
@@ -556,10 +556,10 @@ void ax25_dev_device_up(struct device *dev)
        ax25_dev->values[AX25_VALUES_CONMODE]   = AX25_DEF_CONMODE;
        ax25_dev->values[AX25_VALUES_WINDOW]    = AX25_DEF_WINDOW;
        ax25_dev->values[AX25_VALUES_EWINDOW]   = AX25_DEF_EWINDOW;
-       ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1 * PR_SLOWHZ;
-       ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2 * PR_SLOWHZ;
-       ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3 * PR_SLOWHZ;
-       ax25_dev->values[AX25_VALUES_IDLE]      = AX25_DEF_IDLE * PR_SLOWHZ * 60;
+       ax25_dev->values[AX25_VALUES_T1]        = AX25_DEF_T1;
+       ax25_dev->values[AX25_VALUES_T2]        = AX25_DEF_T2;
+       ax25_dev->values[AX25_VALUES_T3]        = AX25_DEF_T3;
+       ax25_dev->values[AX25_VALUES_IDLE]      = AX25_DEF_IDLE;
        ax25_dev->values[AX25_VALUES_N2]        = AX25_DEF_N2;
        ax25_dev->values[AX25_VALUES_DIGI]      = AX25_DEF_DIGI;
        ax25_dev->values[AX25_VALUES_PACLEN]    = AX25_DEF_PACLEN;
index 0611daefa91fa250803ae4af4877a46718e45142..404f787a0851cb5e7f4e5896882c93178de83eda 100644 (file)
@@ -150,12 +150,12 @@ static void ax25_timer(unsigned long param)
                        if (ax25->sk != NULL) {
                                if (ax25->sk->debug)
                                        printk(KERN_DEBUG "AX.25 T3 Timeout\n");
-                               ax25->sk->state = TCP_CLOSE;
-                               ax25->sk->err   = ETIMEDOUT;
+                               ax25->sk->state     = TCP_CLOSE;
+                               ax25->sk->err       = ETIMEDOUT;
                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                if (!ax25->sk->dead)
                                        ax25->sk->state_change(ax25->sk);
-                               ax25->sk->dead  = 1;
+                               ax25->sk->dead      = 1;
                        }
 
                        ax25_reset_timer(ax25);
@@ -195,13 +195,13 @@ static void ax25_timer(unsigned long param)
                ax25->t1timer = ax25->t1 = ax25_calculate_t1(ax25);
 
                if (ax25->sk != NULL) {
-                       ax25->sk->state = TCP_CLOSE;
-                       ax25->sk->err = 0;
+                       ax25->sk->state     = TCP_CLOSE;
+                       ax25->sk->err       = 0;
                        ax25->sk->shutdown |= SEND_SHUTDOWN;
                        if (!ax25->sk->dead)
                                ax25->sk->state_change(ax25->sk);
-                       ax25->sk->dead = 1;
-                       ax25->sk->destroy = 1;
+                       ax25->sk->dead      = 1;
+                       ax25->sk->destroy   = 1;
                }
        }
                                                                                                                                                                                                                                                                                                                                                        
@@ -239,12 +239,12 @@ void ax25_t1_timeout(ax25_cb * ax25)
                                        ax25_clear_queues(ax25);
                                        ax25->state = AX25_STATE_0;
                                        if (ax25->sk != NULL) {
-                                               ax25->sk->state = TCP_CLOSE;
-                                               ax25->sk->err   = ETIMEDOUT;
+                                               ax25->sk->state     = TCP_CLOSE;
+                                               ax25->sk->err       = ETIMEDOUT;
                                                ax25->sk->shutdown |= SEND_SHUTDOWN;
                                                if (!ax25->sk->dead)
                                                        ax25->sk->state_change(ax25->sk);
-                                               ax25->sk->dead  = 1;
+                                               ax25->sk->dead      = 1;
                                        }
                                } else {
                                        ax25->modulus = MODULUS;
@@ -270,12 +270,12 @@ void ax25_t1_timeout(ax25_cb * ax25)
                                ax25_send_control(ax25, DISC, POLLON, C_COMMAND);
                                
                                if (ax25->sk != NULL) {
-                                       ax25->sk->state = TCP_CLOSE;
-                                       ax25->sk->err   = ETIMEDOUT;
+                                       ax25->sk->state     = TCP_CLOSE;
+                                       ax25->sk->err       = ETIMEDOUT;
                                        ax25->sk->shutdown |= SEND_SHUTDOWN;
                                        if (!ax25->sk->dead)
                                                ax25->sk->state_change(ax25->sk);
-                                       ax25->sk->dead  = 1;
+                                       ax25->sk->dead      = 1;
                                }
                        } else {
                                ax25->n2count++;
@@ -300,12 +300,12 @@ void ax25_t1_timeout(ax25_cb * ax25)
                                if (ax25->sk != NULL) {
                                        if (ax25->sk->debug)
                                                printk(KERN_DEBUG "AX.25 link Failure\n");
-                                       ax25->sk->state = TCP_CLOSE;
-                                       ax25->sk->err   = ETIMEDOUT;
+                                       ax25->sk->state     = TCP_CLOSE;
+                                       ax25->sk->err       = ETIMEDOUT;
                                        ax25->sk->shutdown |= SEND_SHUTDOWN;
                                        if (!ax25->sk->dead)
                                                ax25->sk->state_change(ax25->sk);
-                                       ax25->sk->dead  = 1;
+                                       ax25->sk->dead      = 1;
                                }
                        } else {
                                ax25->n2count++;
index 8f87877d4fc6878ca7f04bf966c9f601cbea712d..b8c7891e8ea9d9e2595dcdcfaaf83a9c9dfccb41 100644 (file)
@@ -387,7 +387,9 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
         */
 
        if (tot_len > dev->mtu)
+       {
                goto fragment;
+       }
 
        /*
         *      Add an IP checksum
@@ -478,6 +480,13 @@ no_device:
        goto out;
 
 fragment:
+       if ((iph->frag_off & htons(IP_DF)))
+       {
+               printk(KERN_DEBUG "sending pkt_too_big to self\n");
+               icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
+                         htonl(dev->mtu), dev);
+               goto out;
+       }
        ip_fragment(sk,skb,dev,0);
        goto out;
 }
index dfc372ad7e704084a6a1b066cd85e332322e5dca..e96089fab66e5168f9465e9dde53131c0625df24 100644 (file)
@@ -500,6 +500,7 @@ static void tcp_syn_recv_timer(unsigned long data)
 #endif
                                                (*conn->class->destructor)(conn);
                                                tcp_dec_slow_timer(TCP_SLT_SYNACK);
+                                               sk->ack_backlog--;
                                                kfree(conn);
 
                                                if (!tp->syn_wait_queue)
index ac87944961b38520bd1c1ea25abad9517ebdddbe..c300960cc961b7eb55d15f2ab28bff9af185fe4b 100644 (file)
@@ -491,11 +491,11 @@ static void sit_route_add(struct device *dev)
        }
        else
        {
-               rtmsg.rtmsg_prefixlen = 128;
+               rtmsg.rtmsg_prefixlen = 10;
                rtmsg.rtmsg_dst.s6_addr32[0] = __constant_htonl(0xfe800000);
                rtmsg.rtmsg_dst.s6_addr32[3] = dev->pa_dstaddr;
                rtmsg.rtmsg_metric = 1;
-               rtmsg.rtmsg_flags = RTF_HOST|RTF_UP;
+               rtmsg.rtmsg_flags = RTF_NEXTHOP|RTF_UP;
        }
 
        strcpy(rtmsg.rtmsg_device, dev->name);
index 7272e12c62141371439aff327498f6137ed9ecbf..2af3ceae978218727552476a5e62792163d129e2 100644 (file)
  *      2 of the License, or (at your option) any later version.
  */
 
+/*
+ *     Changes:
+ *
+ *     Masaki Hirabaru                 :       Fix for /proc info > pagesize
+ *     <masaki@merit.edu>
+ */
 
 #include <linux/config.h>
 #include <linux/errno.h>
@@ -101,7 +107,7 @@ typedef void (*f_pnode)(struct fib6_node *fn, void *);
 
 static void    rt6_walk_tree(f_pnode func, void * arg, int filter);
 static void    rt6_rt_timeout(struct fib6_node *fn, void *arg);
-static int     rt6_msgrcv(struct sk_buff *skb);
+static int     rt6_msgrcv(int unit, struct sk_buff *skb);
 
 struct rt6_statistics rt6_stats = {
        1, 0, 1, 1, 0
@@ -205,7 +211,7 @@ static __inline__ int addr_match(struct in6_addr *a1, struct in6_addr *a2,
                        return 0;
        }
 
-       return 1;       
+       return 1;
 }
 
 /*
@@ -374,7 +380,7 @@ static int fib6_add_1(struct rt6_info *rt)
 
                if (addr_match(&fn->leaf->rt_dst, addr, fn->fn_bit))
                {
-                       if (pbit == fn->fn_bit &&
+                       if (pbit == fn->fn_bit && pbit &&
                            addr_bit_equal(addr, &fn->leaf->rt_dst,
                                           rt->rt_prefixlen))
                        {
@@ -396,7 +402,7 @@ static int fib6_add_1(struct rt6_info *rt)
                                return 0;
                        }
 
-                       if (pbit > fn->fn_bit)
+                       if (pbit > fn->fn_bit || pbit == 0)
                        {
                                /* walk down on tree */
 
@@ -625,6 +631,7 @@ static void fib6_del_3(struct fib6_node *fn)
        if (children < 2)
        {
                struct fib6_node *child;
+               struct fib6_node *pn;
 
                child = dir ? fn->right : fn->left;
 
@@ -642,18 +649,22 @@ static void fib6_del_3(struct fib6_node *fn)
                        child->parent = fn->parent;
                }
 
-               /* 
+               /*
                 *      try to collapse on top
-                */                     
-               if ((fn->parent->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
+                */
+               pn = fn->parent;
+               fn->parent = NULL;
+               
+               if ((pn->fn_flags & (RTN_BACKTRACK | RTN_ROOT)) == 0)
                {
-                       if (fn->leaf)
+                       if (pn->leaf)
                        {
-                               rt_release(fn->leaf);
-                               fn->leaf = NULL;
+                               rt_release(pn->leaf);
+                               pn->leaf = NULL;
                        }
-                       fib6_del_3(fn->parent);
+                       fib6_del_3(pn);
                }
+
                if (fn->fn_flags & RTN_BACKTRACK)
                {
                        rt6_stats.fib_route_nodes--;
@@ -667,7 +678,9 @@ static void fib6_del_3(struct fib6_node *fn)
        
        fn->fn_bit = bit;
        fn->fn_flags &= ~RTN_BACKTRACK;
+       
        fn->leaf = fn->left->leaf;
+       atomic_inc(&fn->leaf->rt_ref);
 
        rt6_stats.fib_route_nodes--;
 }
@@ -726,11 +739,12 @@ static struct fib6_node * fib6_del_2(struct in6_addr *addr, __u32 prefixlen,
        return NULL;
 }
 
-static struct fib6_node * fib6_del_rt_2(struct in6_addr *addr, __u32 prefixlen,
-                                       struct rt6_info *rt)
+static struct fib6_node * fib6_del_rt_2(struct rt6_info *rt)
 {
        struct fib6_node *fn;
-
+       struct in6_addr *addr = &rt->rt_dst;
+       int prefixlen = rt->rt_prefixlen;
+       
        for (fn = &routing_table; fn;) 
        {
                int dir;
@@ -755,24 +769,24 @@ static struct fib6_node * fib6_del_rt_2(struct in6_addr *addr, __u32 prefixlen,
 
        if (fn)
        {
-               struct rt6_info *back = NULL;
+               struct rt6_info **back;
                struct rt6_info *lf;
 
+               back = &fn->leaf;
+               
                for(lf = fn->leaf; lf; lf=lf->next)
                {
                        if (rt == lf)
                        {
-                               /* delete this entry */
-                               if (back == NULL)
-                                       fn->leaf = lf->next;
-                               else
-                                       back->next = lf->next;
-
-                               lf->fib_node = NULL;
+                               /*
+                                *      delete this entry
+                                */
+                               
+                               *back = lf->next;
                                rt_release(lf);
                                return fn;
                        }
-                       back = lf;
+                       back = &lf->next;
                }
        }
 
@@ -801,7 +815,7 @@ int fib6_del_rt(struct rt6_info *rt)
 {
        struct fib6_node *fn;
 
-       fn = fib6_del_rt_2(&rt->rt_dst, rt->rt_prefixlen, rt);
+       fn = fib6_del_rt_2(rt);
 
        if (fn == NULL)
                return -ENOENT;
@@ -859,6 +873,12 @@ int ipv6_route_add(struct in6_rtmsg *rtmsg)
                
        memcpy(&rt->rt_dst, &rtmsg->rtmsg_dst, sizeof(struct in6_addr));
        rt->rt_prefixlen = rtmsg->rtmsg_prefixlen;
+
+       if (rt->rt_prefixlen == 0)
+       {
+               printk(KERN_DEBUG "ip6_fib: zero length route not allowed\n");
+               return -EINVAL;
+       }
        
        if (flags & (RTF_GATEWAY | RTF_NEXTHOP)) 
        {
@@ -867,7 +887,7 @@ int ipv6_route_add(struct in6_rtmsg *rtmsg)
                {
                        struct rt6_info *gw_rt;
 
-                       gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, NULL,
+                       gw_rt = fibv6_lookup(&rtmsg->rtmsg_gateway, dev,
                                             RTI_GATEWAY);
 
                        if (gw_rt == NULL)
@@ -937,11 +957,44 @@ int ipv6_route_add(struct in6_rtmsg *rtmsg)
 int ipv6_route_del(struct in6_rtmsg *rtmsg)
 {
        struct rt6_info * rt;
-
+       int res = -ENOENT;
+       
+       atomic_inc(&rt6_lock);
+       
        rt = fib6_lookup_1(&rtmsg->rtmsg_dst, 0);
-       if (!rt || (rt && (rt->rt_prefixlen != rtmsg->rtmsg_prefixlen)))
-               return -ENOENT;
-       return fib6_del_rt(rt);
+       
+       if (rt && (rt->rt_prefixlen == rtmsg->rtmsg_prefixlen))
+       {
+               int test;
+               
+               start_bh_atomic();
+               
+               test = (rt6_lock == 1);
+               
+               if (test)
+               {
+                       res = fib6_del_rt(rt);
+               }
+               end_bh_atomic();
+
+               if (!test)
+               {
+                       /*
+                        *      This function is called from user
+                        *      context only (at the moment).
+                        *      As we don't sleep we should never see
+                        *      a lock count > 1.
+                        *
+                        *      If this assumptions becomes invalid we'll
+                        *      just have to had a del request to the
+                        *      queue in this case.
+                        */
+                       res = -EBUSY;
+               }
+       }
+       
+       atomic_dec(&rt6_lock);
+       return res;
 }
 
 /*
@@ -954,6 +1007,8 @@ struct rt6_info * fibv6_lookup(struct in6_addr *addr, struct device *src_dev,
 {
        struct rt6_info *rt;
 
+       atomic_inc(&rt6_lock);
+       
        if ((rt = fib6_lookup_1(addr, flags)))
        {
                if (src_dev)
@@ -963,29 +1018,33 @@ struct rt6_info * fibv6_lookup(struct in6_addr *addr, struct device *src_dev,
                        for (sprt=rt; sprt; sprt=sprt->next)
                        {
                                if (sprt->rt_dev == src_dev)
-                                       return sprt;
+                               {
+                                       rt = sprt;
+                                       goto out;
+                               }
                        }
                        
                        if (flags & RTI_DEVRT)
                        {
-                               return NULL;
+                               rt = NULL;
                        }
                }
 
-               return rt;
+               goto out;
        }
 
        if (!(flags & RTI_GATEWAY))
        {
                if ((rt = dflt_rt_lookup()))
                {
-                       return rt;
+                       goto out;
                }
 
-               return last_resort_rt;
+               rt = last_resort_rt;
        }
-
-       return NULL;
+  out:
+       atomic_dec(&rt6_lock);
+       return rt;
 }
 
 /*
@@ -1713,11 +1772,12 @@ static void rt6_walk_tree(f_pnode func, void * arg, int filter)
 }
 
 #ifdef CONFIG_PROC_FS
-#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7)
+#define RT6_INFO_LEN (32 + 2 + 32 + 2 + 2 + 2 + 4 + 8 + 7 + 1)
 
 struct rt6_proc_arg {
        char *buffer;
        int offset;
+       int length;
        int skip;
        int len;
 };
@@ -1736,7 +1796,10 @@ static void rt6_info_node(struct fib6_node *fn, void *p_arg)
                        arg->skip++;
                        continue;
                }
-       
+
+               if (arg->len >= arg->length)
+                       return;
+               
                for (i=0; i<16; i++)
                {
                        sprintf(arg->buffer + arg->len, "%02x",
@@ -1775,6 +1838,7 @@ static int rt6_proc_info(char *buffer, char **start, off_t offset, int length,
        struct fib6_node sfn;
        arg.buffer = buffer;
        arg.offset = offset;
+       arg.length = length;
        arg.skip = 0;
        arg.len = 0;
 
@@ -1865,7 +1929,7 @@ void ipv6_route_cleanup(void)
  *     routing socket moral equivalent
  */
 
-static int rt6_msgrcv(struct sk_buff *skb)
+static int rt6_msgrcv(int unit, struct sk_buff *skb)
 {
        int count = 0;
        struct in6_rtmsg *rtmsg;
index 063f9a2c64976489adabaf8b5cefcbc60ec2321f..f96b62229869cf51bf72467e07e447bfb03164e9 100644 (file)
@@ -66,7 +66,8 @@ static struct enet_statistics *       sit_get_stats(struct device *dev);
 static void                    sit_err(int type, int code, 
                                        unsigned char *buff, __u32 info,
                                        __u32 daddr, __u32 saddr,
-                                       struct inet_protocol *protocol);
+                                       struct inet_protocol *protocol,
+                                       int len);
 
 static struct inet_protocol sit_protocol = {
        sit_rcv,
@@ -349,7 +350,8 @@ void sit_cleanup(void)
  */
 
 static void sit_err(int type, int code, unsigned char *buff, __u32 info,
-                   __u32 daddr, __u32 saddr, struct inet_protocol *protocol)
+                   __u32 daddr, __u32 saddr, struct inet_protocol *protocol,
+                   int len)
                    
 {
        if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
index 380122210f08a50169c2bc7657d2d9301db79903..595529d161abd41e22c547d1130856ec13e7dd44 100644 (file)
@@ -47,7 +47,7 @@ struct udp_mib udp_stats_in6;
  *
  */
 
-int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, size_t addr_len)
 {
        struct sockaddr_in6     *usin = (struct sockaddr_in6 *) uaddr;
        struct in6_addr         *daddr;
index b50051f4167716e679a3809584b29e39063e1315..3f86be2ee27d29f5f9e9e0cdc4f3c608d5ae3619 100644 (file)
@@ -122,6 +122,7 @@ static void nr_kill_by_device(struct device *dev)
                        s->protinfo.nr->device = NULL;
                        s->state               = TCP_CLOSE;
                        s->err                 = ENETUNREACH;
+                       s->shutdown           |= SEND_SHUTDOWN;
                        s->state_change(s);
                        s->dead                = 1;
                }
@@ -322,6 +323,7 @@ static int nr_ctl_ioctl(const unsigned int cmd, void *arg)
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
                        sk->err                = ENETRESET;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead               = 1;
@@ -728,6 +730,7 @@ static int nr_release(struct socket *sock, struct socket *peer)
 
                case NR_STATE_0:
                        sk->state     = TCP_CLOSE;
+                       sk->shutdown |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead      = 1;
                        nr_destroy_socket(sk);
@@ -736,6 +739,7 @@ static int nr_release(struct socket *sock, struct socket *peer)
                case NR_STATE_1:
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead               = 1;
                        nr_destroy_socket(sk);
@@ -745,6 +749,7 @@ static int nr_release(struct socket *sock, struct socket *peer)
                        nr_write_internal(sk, NR_DISCACK);
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
+                       sk->shutdown           = SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead               = 1;
                        nr_destroy_socket(sk);
@@ -759,6 +764,7 @@ static int nr_release(struct socket *sock, struct socket *peer)
                        sk->protinfo.nr->t4timer = 0;
                        sk->protinfo.nr->state   = NR_STATE_2;
                        sk->state                = TCP_CLOSE;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead                 = 1;
                        sk->destroy              = 1;
@@ -1139,6 +1145,11 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nobl
        if (sk->zapped)
                return -EADDRNOTAVAIL;
 
+       if (sk->shutdown & SEND_SHUTDOWN) {
+               send_sig(SIGPIPE, current, 0);
+               return -EPIPE;
+       }
+
        if (sk->protinfo.nr->device == NULL)
                return -ENETUNREACH;
                
@@ -1253,11 +1264,12 @@ static int nr_recvmsg(struct socket *sock, struct msghdr *msg, int size, int nob
        }
 
        copied = skb->len;
-       if(copied>size)
-       {
-               copied=size;
-               msg->msg_flags|=MSG_TRUNC;
+
+       if (copied > size) {
+               copied = size;
+               msg->msg_flags |= MSG_TRUNC;
        }
+
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
        
        if (sax != NULL) {
index 71c4e9dbb0a6d1d0615fbaf33b114c20b4e3f7a3..b3732441e3f47a1ada4b59273d703f3245ec5738 100644 (file)
@@ -123,6 +123,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
                        sk->err                = ECONNREFUSED;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead               = 1;
@@ -151,6 +152,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
                        sk->err                = 0;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead               = 1;
@@ -191,6 +193,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
                        sk->err                = 0;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead               = 1;
@@ -201,6 +204,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
                        sk->protinfo.nr->state = NR_STATE_0;
                        sk->state              = TCP_CLOSE;
                        sk->err                = ECONNRESET;
+                       sk->shutdown          |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead               = 1;
index 727cc62a6a193dd90512d3fe087ac92e610ae8c3..61935f30cc23c85e4e524377c92afa5ef64a6e84 100644 (file)
@@ -227,11 +227,12 @@ void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
        if (!nr_route_frame(skb, NULL)) {
                kfree_skb(skb, FREE_WRITE);
 
-               sk->state = TCP_CLOSE;
-               sk->err   = ENETUNREACH;
+               sk->state     = TCP_CLOSE;
+               sk->err       = ENETUNREACH;
+               sk->shutdown |= SEND_SHUTDOWN;
                if (!sk->dead)
                        sk->state_change(sk);
-               sk->dead  = 1;
+               sk->dead      = 1;
        }
 }
 
index deabe4168b2ba1ae49d6003e542efa014474f4cf..ac91b1a0e22c35699c15f4b0f91831fe2cbdea4a 100644 (file)
@@ -144,6 +144,7 @@ static void nr_timer(unsigned long param)
                                sk->protinfo.nr->state = NR_STATE_0;
                                sk->state              = TCP_CLOSE;
                                sk->err                = ETIMEDOUT;
+                               sk->shutdown          |= SEND_SHUTDOWN;
                                if (!sk->dead)
                                        sk->state_change(sk);
                                sk->dead               = 1;
@@ -159,6 +160,7 @@ static void nr_timer(unsigned long param)
                                sk->protinfo.nr->state = NR_STATE_0;
                                sk->state              = TCP_CLOSE;
                                sk->err                = ETIMEDOUT;
+                               sk->shutdown          |= SEND_SHUTDOWN;
                                if (!sk->dead)
                                        sk->state_change(sk);
                                sk->dead               = 1;
@@ -174,6 +176,7 @@ static void nr_timer(unsigned long param)
                                sk->protinfo.nr->state = NR_STATE_0;
                                sk->state              = TCP_CLOSE;
                                sk->err                = ETIMEDOUT;
+                               sk->shutdown          |= SEND_SHUTDOWN;
                                if (!sk->dead)
                                        sk->state_change(sk);
                                sk->dead               = 1;
index aa856d5deb76214cace9d936be13ba6ea6df2cde..22f253d63c91108d4b4f94b538d220d7c4f7cdb3 100644 (file)
@@ -60,10 +60,16 @@ extern void destroy_EII_client(struct datalink_proto *);
 extern void destroy_8023_client(struct datalink_proto *);
 #endif
 
+extern char *skb_push_errstr;
+extern char *skb_put_errstr;
 
 static struct symbol_table net_syms = {
 #include <linux/symtab_begin.h>
 
+       /* Skbuff symbols. */
+       X(skb_push_errstr),
+       X(skb_put_errstr),
+
        /* Socket layer registration */
        X(sock_register),
        X(sock_unregister),
index 9f4a53a67b09a5dfb51dbd1d34ccc386aa9d418b..d5090bc47e8a0b342d49cc7bcc3d087db1ffedbd 100644 (file)
@@ -28,6 +28,9 @@ extern void inet6_proto_init(struct net_proto *pro);
 #include <net/p8022call.h>
 #include <net/p8022trcall.h>
 #endif
+#ifdef CONFIG_X25
+#include <net/x25call.h>
+#endif
 #ifdef CONFIG_AX25
 #include <net/ax25call.h>
 #ifdef CONFIG_NETROM
index 8f14318c1a0a113577b0733180633c2196b2c398..0c845f2680d2419ee4638c45a1fc80d891ffc357 100644 (file)
@@ -139,6 +139,7 @@ static void rose_kill_by_device(struct device *dev)
                        s->protinfo.rose->device = NULL;
                        s->state                 = TCP_CLOSE;
                        s->err                   = ENETUNREACH;
+                       s->shutdown             |= SEND_SHUTDOWN;
                        s->state_change(s);
                        s->dead                  = 1;
                }
@@ -344,6 +345,7 @@ static int rose_ctl_ioctl(const unsigned int cmd, void *arg)
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = ENETRESET;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;
@@ -716,6 +718,7 @@ static int rose_release(struct socket *sock, struct socket *peer)
 
                case ROSE_STATE_0:
                        sk->state     = TCP_CLOSE;
+                       sk->shutdown |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead      = 1;
                        rose_destroy_socket(sk);
@@ -724,6 +727,7 @@ static int rose_release(struct socket *sock, struct socket *peer)
                case ROSE_STATE_1:
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead                 = 1;
                        rose_destroy_socket(sk);
@@ -732,6 +736,7 @@ static int rose_release(struct socket *sock, struct socket *peer)
                case ROSE_STATE_2:
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead                 = 1;
                        rose_destroy_socket(sk);
@@ -744,6 +749,7 @@ static int rose_release(struct socket *sock, struct socket *peer)
                        sk->protinfo.rose->timer = sk->protinfo.rose->t3;
                        sk->protinfo.rose->state = ROSE_STATE_2;
                        sk->state                = TCP_CLOSE;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        sk->state_change(sk);
                        sk->dead                 = 1;
                        sk->destroy              = 1;
@@ -1077,6 +1083,11 @@ static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
        if (sk->zapped)
                return -EADDRNOTAVAIL;
 
+       if (sk->shutdown & SEND_SHUTDOWN) {
+               send_sig(SIGPIPE, current, 0);
+               return -EPIPE;
+       }
+
        if (sk->protinfo.rose->device == NULL)
                return -ENETUNREACH;
                
@@ -1202,10 +1213,9 @@ static int rose_recvmsg(struct socket *sock, struct msghdr *msg, int size, int n
 
        copied = skb->len;
        
-       if(copied>size)
-       {
-               copied=size;
-               msg->msg_flags|=MSG_TRUNC;
+       if (copied > size) {
+               copied = size;
+               msg->msg_flags |= MSG_TRUNC;
        }
        
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
index 7634c4b5473cfebe8dfe423f0360dd3fae1c11e0..4aabfdc1eed8de70993181827055f2b1f2453bd4 100644 (file)
@@ -112,6 +112,7 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = ECONNREFUSED;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;
@@ -139,6 +140,7 @@ static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int framety
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = 0;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;
@@ -179,6 +181,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = 0;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;
@@ -281,6 +284,7 @@ static int rose_state4_machine(struct sock *sk, struct sk_buff *skb, int framety
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = 0;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;
index 5a1d3e510d83f3ea26fc14a0f4c28b5aae95b43a..ca960480f1168e423153a58d420e845d653bc527 100644 (file)
@@ -140,6 +140,7 @@ static void rose_timer(unsigned long param)
                        sk->protinfo.rose->state = ROSE_STATE_0;
                        sk->state                = TCP_CLOSE;
                        sk->err                  = ETIMEDOUT;
+                       sk->shutdown            |= SEND_SHUTDOWN;
                        if (!sk->dead)
                                sk->state_change(sk);
                        sk->dead                 = 1;