]> git.neil.brown.name Git - history.git/commitdiff
Import 1.1.75 1.1.75
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:47 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:47 +0000 (15:09 -0500)
69 files changed:
CREDITS
Makefile
arch/alpha/Makefile
arch/alpha/boot/head.S
arch/i386/Makefile
arch/i386/boot/head.S
drivers/block/ll_rw_blk.c
drivers/block/sbpcd.c
drivers/char/console.c
drivers/char/cyclades.c
drivers/char/kbd_kern.h
drivers/char/vt.c
drivers/net/slip.c
drivers/net/slip.h
drivers/scsi/buslogic.c
drivers/scsi/scsi.c
drivers/scsi/sd.c
drivers/scsi/ultrastor.c
fs/dcache.c
fs/isofs/inode.c
fs/msdos/Makefile
fs/msdos/buffer.c [new file with mode: 0644]
fs/msdos/dir.c
fs/msdos/fat.c
fs/msdos/file.c
fs/msdos/inode.c
fs/msdos/misc.c
fs/msdos/mmap.c [new file with mode: 0644]
fs/msdos/msbuffer.h [new file with mode: 0644]
fs/msdos/namei.c
fs/proc/array.c
fs/umsdos/file.c
fs/umsdos/inode.c
fs/umsdos/mangle.c
fs/umsdos/namei.c
include/asm-alpha/bugs.h [new file with mode: 0644]
include/asm-alpha/processor.h [new file with mode: 0644]
include/asm-alpha/system.h
include/asm-alpha/types.h
include/asm-generic/string.h [deleted file]
include/asm-i386/bugs.h [new file with mode: 0644]
include/asm-i386/processor.h [new file with mode: 0644]
include/asm-i386/system.h
include/asm-i386/types.h
include/asm-sparc/bugs.h [new file with mode: 0644]
include/asm-sparc/openprom.h
include/asm-sparc/types.h
include/linux/blkdev.h
include/linux/config.h
include/linux/in.h
include/linux/interrupt.h
include/linux/msdos_fs.h
include/linux/proc_fs.h
include/linux/resource.h
include/linux/sched.h
include/linux/string.h
include/linux/tqueue.h
include/linux/types.h
init/main.c
kernel/fork.c
kernel/ksyms.c
kernel/sched.c
kernel/traps.c
kernel/vm86.c
lib/string.c
mm/memory.c
net/inet/ip.c
net/inet/proc.c
net/inet/tcp.c

diff --git a/CREDITS b/CREDITS
index 23ceb1d67e6b322383b0ba934d39d0486263e3ff..72cb5d1514da762fa21c16bd83b17fb55f9ada0a 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -546,6 +546,16 @@ S: Boterkorfhoek 34
 S: 7546 JA  Enschede
 S: Netherlands
 
+N: David S. Miller
+E: davem@caip.rutgers.edu
+D: Sparc hacker
+D: New Linux-Activists maintainer
+D: Linux Emacs elf/qmagic support + other libc/gcc things
+D: Yee bore de yee bore! ;-)
+S: 2 Bristol Court
+S: East Brunswick, New Jersey 08816
+S: USA
+
 N: Rick Miller
 E: rick@discus.mil.wi.us
 D: Linux Device Registrar (Major/minor numbers), "au-play", "bwBASIC"
index de9113fbeac48971452586b572de6c60647209d7..8b799fdf07e6edf989ac9592fb74b04436c1afba 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,9 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 74
+SUBLEVEL = 75
 
 ARCH = i386
 
-all:   Version zImage
-
 .EXPORT_ALL_VARIABLES:
 
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -13,6 +11,8 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
          else echo sh; fi ; fi)
 TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
 
+all:   do-it-all
+
 #
 # Make "config" the default target if there is no configuration file or
 # "depend" the target if there is no top-level dependency information.
@@ -21,11 +21,14 @@ ifeq (.config,$(wildcard .config))
 include .config
 ifeq (.depend,$(wildcard .depend))
 include .depend
+do-it-all:     Version arch-all
 else
 CONFIGURATION = depend
+do-it-all:     depend
 endif
 else
 CONFIGURATION = config
+do-it-all:     config
 endif
 
 #
@@ -55,7 +58,7 @@ SVGA_MODE=    -DSVGA_MODE=NORMAL_VGA
 # standard CFLAGS
 #
 
-CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe
+CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 
 ifdef CONFIG_CPP
 CFLAGS := $(CFLAGS) -x c++
@@ -156,6 +159,7 @@ boot/head.s: boot/head.S $(CONFIGURE) include/linux/tasks.h
        $(CPP) -traditional $< -o $@
 
 tools/version.o: tools/version.c include/linux/version.h
+       $(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o tools/version.o tools/version.c
 
 init/main.o: $(CONFIGURE) init/main.c
        $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $<
index 35800431acb39955746f3d86dcdff471cb5edea9..ace120d8e809809d6fffd64271b62c53f82c1ea7 100644 (file)
@@ -17,22 +17,7 @@ CPP     =$(CC) -E
 AR      =ar
 STRIP   =strip
 
-zBoot/zSystem: zBoot/*.c zBoot/*.S tools/zSystem
-       $(MAKE) -C zBoot
-
-zImage: $(CONFIGURE) boot/bootsect boot/setup zBoot/zSystem tools/build
-       tools/build boot/bootsect boot/setup zBoot/zSystem $(ROOT_DEV) > zImage
-       sync
-
-zdisk: zImage
-       dd bs=8192 if=zImage of=/dev/fd0
-
-zlilo: $(CONFIGURE) zImage
-       if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
-       if [ -f $(INSTALL_PATH)/zSystem.map ]; then mv $(INSTALL_PATH)/zSystem.map $(INSTALL_PATH)/zSystem.old; fi
-       cat zImage > $(INSTALL_PATH)/vmlinuz
-       cp zSystem.map $(INSTALL_PATH)/
-       if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
+arch-all: tools/system
 
 tools/system:  boot/head.o init/main.o tools/version.o linuxsubdirs
        $(LD) $(LOWLDFLAGS) boot/head.o init/main.o tools/version.o \
@@ -44,24 +29,6 @@ tools/system:        boot/head.o init/main.o tools/version.o linuxsubdirs
                nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
                sort > System.map
 
-boot/setup.o: boot/setup.s
-       $(AS) -o $@ $<
-
-boot/setup.s: boot/setup.S $(CONFIGURE) include/linux/config.h Makefile
-       $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
-
-boot/bootsect.s: boot/bootsect.S $(CONFIGURE) include/linux/config.h Makefile
-       $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
-
-tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs
-       $(LD) $(HIGHLDFLAGS) boot/head.o init/main.o tools/version.o \
-               $(ARCHIVES) \
-               $(FILESYSTEMS) \
-               $(DRIVERS) \
-               $(LIBS) \
-               -o tools/zSystem
-       nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \
-               sort > zSystem.map
 
 #
 # Leave these dummy entries for now to tell people that they are going away..
@@ -74,4 +41,4 @@ lilo:
        @exit 1
 
 archclean:
-       rm -f boot/bootsect boot/setup
+       @rm -f boot/head.o
index 03a2a90108bedfa493d224291012e0ffa949a3f4..ab1a48d09e7ee663dcdc08e4dbbb8e418413e22e 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <asm/system.h>
 
+#undef halt
 #define halt .long PAL_halt
 
 /*
index 0003cfd24e2132f082ff2c55cbf085c88fe0df57..586a451cc72f188683dd228629da9b1a8d174f83 100644 (file)
@@ -19,6 +19,8 @@ CPP     =$(CC) -E
 AR      =ar
 STRIP   =strip
 
+CFLAGS := $(CFLAGS) -pipe
+
 ifdef CONFIG_M486
 CFLAGS := $(CFLAGS) -m486
 else
@@ -29,6 +31,8 @@ CFLAGS := $(CFLAGS) -m386
 endif
 endif
 
+arch-all: zImage
+
 zBoot/zSystem: zBoot/*.c zBoot/*.S tools/zSystem
        $(MAKE) -C zBoot
 
index 4327b375698ab526312b0da70049cce0a5bcf732..db54704565e95d660d8931c9ff39ae649b488b1d 100644 (file)
@@ -37,7 +37,7 @@ startup_32:
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
-       lss _stack_start,%esp
+       lss stack_start,%esp
 /*
  * Clear BSS first so that there are no surprises...
  */
@@ -164,7 +164,7 @@ is386:      pushl %ecx              # restore original EFLAGS
        mov %ax,%es
        mov %ax,%fs
        mov %ax,%gs
-       lss _stack_start,%esp
+       lss stack_start,%esp
        xorl %eax,%eax
        lldt %ax
        pushl %eax              # These are the parameters to main :-)
@@ -294,6 +294,10 @@ _empty_zero_page:
  */
 _floppy_track_buffer:
        .fill 512*2*MAX_BUFFER_SECTORS,1,0
+       
+stack_start:
+       .long _init_user_stack+4096
+       .long KERNEL_DS
 
 /* This is the default interrupt "handler" :-) */
 int_msg:
index 621f84a91974a4adbbacbcc0badf6742cac5a911..be30b6af9733790aadb4f0bf1263991056743489 100644 (file)
@@ -71,6 +71,20 @@ int * blk_size[MAX_BLKDEV] = { NULL, NULL, };
  */
 int * blksize_size[MAX_BLKDEV] = { NULL, NULL, };
 
+/*
+ * hardsect_size contains the size of the hardware sector of a device.
+ *
+ * hardsect_size[MAJOR][MINOR]
+ *
+ * if (!hardsect_size[MAJOR])
+ *             then 512 bytes is assumed.
+ * else
+ *             sector_size is hardsect_size[MAJOR][MINOR]
+ * This is currently set by some scsi device and read by the msdos fs driver
+ * This might be a some uses later.
+ */
+int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
+
 /*
  * look for a free request in the first N entries.
  * NOTE: interrupts must be disabled on the way in, and will still
index f38f15b7308d6c62584e499ca14dd0f603f15bf5..e209e97b28643ce71fd7ff0a0a1385fa100f7d34 100644 (file)
  *  2.9  Fulfilled the Longshine LCS-7260 support; with great help and
  *       experiments by Serge Robyns.
  *       First attempts to support the TEAC CD-55A drives; but still not
- *       useable yet.
+ *       usable yet.
  *       Implemented the CDROMMULTISESSION and CDROMMULTISESSION_SYS ioctls;
  *       this is an attempt to handle multi session CDs more "transparent"
  *       (redirection handling has to be done within the isofs routines, and
                                   * linux/fs/isofs/inode.c
                                   * if set to 0 here
                                   */
-#define TEAC 0 /* if 1: enable TEAC CD-55A support (not useable yet) */
+#define TEAC 0 /* if 1: enable TEAC CD-55A support (not usable yet) */
 #define JUKEBOX 1 /* tray control: eject tray if no disk is in */
 #define EJECT 1 /* tray control: eject tray after last use */
 #define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
@@ -625,7 +625,7 @@ static void sbpcd_dprintf(int level, char *fmt, ...)
 }
 
 /*
- * DDI interface: runtime trace bit pattern maintainance
+ * DDI interface: runtime trace bit pattern maintenance
  */
 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
 {
index aaf9b66a2f66857c742e9fe2590bcb71ed1d3b35..0348940ca0d860dbf444c832e8634435c15946f6 100644 (file)
@@ -2337,15 +2337,16 @@ int do_screendump(int arg, int mode)
 #endif
        switch(mode) {
            case 0:
-       sptr = (char *) origin;
+                       sptr = (char *) origin;
                        for (l=chcount; l>0 ; l--, sptr++)
-               put_fs_byte(*sptr++,buf++);     
+                               put_fs_byte(*sptr++,buf++);     
                        break;
            case 1:
                        put_fs_byte((char)x,buf++); put_fs_byte((char)y,buf++); 
                        memcpy_tofs(buf,(char *)origin,2*chcount);
                        break;
            case 2:
+                       gotoxy(currcons, get_fs_byte(buf+2), get_fs_byte(buf+3));
                        buf+=4; /* ioctl#, console#, x,y */
                        memcpy_fromfs((char *)origin,buf,2*chcount);
                        break;
@@ -2445,9 +2446,12 @@ static inline int atedge(const int p)
 }
 
 /* constrain v such that v <= u */
-static inline short limit(const unsigned short v, const unsigned short u)
+static inline unsigned short limit(const unsigned short v, const unsigned short u)
 {
-       return ((v > u) ? u : v);
+/* gcc miscompiles the ?: operator, so don't use it.. */
+       if (v > u)
+               return u;
+       return v;
 }
 
 /* invoked via ioctl(TIOCLINUX) */
index 2e49035397e805c36e8f3cf9f767b1f7a7e141a8..63d0799e1010f3be68b3f86e9778242216cc102e 100644 (file)
@@ -16,7 +16,7 @@ static char rcsid[] =
  *
  * $Log: cyclades.c,v $
  * Revision 1.35  1994/12/16  13:54:18  steffen
- * addditional patch by Marcio Saito for board detection
+ * additional patch by Marcio Saito for board detection
  * Accidently left out in 1.34
  *
  * Revision 1.34  1994/12/10  12:37:12  steffen
@@ -304,7 +304,7 @@ static unsigned char *tmp_buf = 0;
 static struct semaphore tmp_buf_sem = MUTEX;
 
 /*
- * This is used to look up the divsor speeds and the timeouts
+ * This is used to look up the divisor speeds and the timeouts
  * We're normally limited to 15 distinct baud rates.  The extra
  * are accessed via settings in info->flags.
  *         0,     1,     2,     3,     4,     5,     6,     7,     8,     9,
@@ -326,7 +326,7 @@ static char baud_bpr[] = {  /* 25 MHz baud rate period table */
         0x00,  0xf5,  0xa3,  0x6f,  0x5c,  0x51,  0xf5,  0xa3,  0x51,  0xa3,
         0x6d,  0x51,  0xa3,  0x51,  0xa3,  0x51,  0x36,  0x29,  0x1b,  0x15};
 
-static char baud_cor3[] = {  /* receive threashold */
+static char baud_cor3[] = {  /* receive threshold */
         0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,  0x0a,
         0x0a,  0x0a,  0x0a,  0x08,  0x04,  0x02,  0x01,  0x01,  0x01,  0x01};
 
@@ -1925,7 +1925,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
         case TIOCMSET:
             ret_val = set_modem_info(info, cmd, (unsigned int *) arg);
 
-/* The following commands are imcompletely implemented!!! */
+/* The following commands are incompletely implemented!!! */
         case TIOCGSOFTCAR:
             error = verify_area(VERIFY_WRITE, (void *) arg
                                 ,sizeof(unsigned int *));
@@ -2038,7 +2038,7 @@ cy_close(struct tty_struct * tty, struct file * filp)
        info->count = 1;
     }
 #ifdef SERIAL_DEBUG_COUNT
-    printk("cyc: %d: decrmenting count to %d\n", __LINE__, info->count - 1);
+    printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
 #endif
     if (--info->count < 0) {
        printk("cy_close: bad serial port count for ttys%d: %d\n",
@@ -2204,7 +2204,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
 #endif
     info->count--;
 #ifdef SERIAL_DEBUG_COUNT
-    printk("cyc: %d: decrmenting count to %d\n", __LINE__, info->count);
+    printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
 #endif
     info->blocked_open++;
 
@@ -2263,7 +2263,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
     if (!tty_hung_up_p(filp)){
        info->count++;
 #ifdef SERIAL_DEBUG_COUNT
-    printk("cyc: %d: incrmenting count to %d\n", __LINE__, info->count);
+    printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
 #endif
     }
     info->blocked_open--;
@@ -2279,7 +2279,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
 
 /*
  * This routine is called whenever a serial port is opened.  It
- * performs the serial-specific initalization for the tty structure.
+ * performs the serial-specific initialization for the tty structure.
  */
 int
 cy_open(struct tty_struct *tty, struct file * filp)
@@ -2304,7 +2304,7 @@ cy_open(struct tty_struct *tty, struct file * filp)
 #endif
     info->count++;
 #ifdef SERIAL_DEBUG_COUNT
-    printk("cyc: %d: incrmenting count to %d\n", __LINE__, info->count);
+    printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
 #endif
     tty->driver_data = info;
     info->tty = tty;
index 440b0d5bb5ebaac64b589c26546dddffdab49bd5..db4a9158a6a751dc1f355cafc03c888e00b2fe3b 100644 (file)
@@ -2,8 +2,6 @@
 #define _KBD_KERN_H
 
 #include <linux/interrupt.h>
-#define set_leds() mark_bh(KEYBOARD_BH)
-
 #include <linux/keyboard.h>
 
 extern char *func_table[MAX_NR_FUNC];
@@ -66,6 +64,14 @@ extern unsigned long kbd_init(unsigned long);
 extern unsigned char getledstate(void);
 extern void setledstate(struct kbd_struct *kbd, unsigned int led);
 
+extern inline void set_leds(void)
+{
+       /* con_init calls (indirectly) set_leds before kbd_init
+          has been called; ignore these early calls */
+       if (bh_base[KEYBOARD_BH].routine)
+               mark_bh(KEYBOARD_BH);
+}
+
 extern inline int vc_kbd_mode(struct kbd_struct * kbd, int flag)
 {
        return ((kbd->modeflags >> flag) & 1);
index ddd4bf56ac4cea996ac5251dd520978bb091c90c..b6b5b3de2dbdcda68f92a0b52cc0f329fc4d2cb9 100644 (file)
@@ -129,7 +129,7 @@ kd_mksound(unsigned int count, unsigned int ticks)
 int vt_ioctl(struct tty_struct *tty, struct file * file,
             unsigned int cmd, unsigned long arg)
 {
-       int i;
+       int i, perm;
        unsigned int console;
        unsigned char ucval;
        struct kbd_struct * kbd;
@@ -140,13 +140,25 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
        if (!vc_cons_allocated(console))        /* impossible? */
                return -ENOIOCTLCMD;
 
+       /*
+        * To have permissions to do most of the vt ioctls, we either have
+        * to be the owner of the tty, or super-user.
+        */
+       perm = 0;
+       if (current->tty == tty || suser())
+               perm = 1;
+
        kbd = kbd_table + console;
        switch (cmd) {
        case KIOCSOUND:
+               if (!perm)
+                       return -EPERM;
                kd_mksound((unsigned int)arg, 0);
                return 0;
 
        case KDMKTONE:
+               if (!perm)
+                       return -EPERM;
        {
                unsigned int ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
 
@@ -190,7 +202,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                 * doesn't do a whole lot. i'm not sure if it should do any
                 * restoration of modes or what...
                 */
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                switch (arg) {
                case KD_GRAPHICS:
@@ -232,7 +244,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                return -EINVAL;
 
        case KDSKBMODE:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                switch(arg) {
                  case K_RAW:
@@ -313,7 +325,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                struct kbkeycode * const a = (struct kbkeycode *)arg;
                unsigned int sc, kc;
 
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbkeycode));
                if (i)
@@ -354,7 +366,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                u_char s;
                u_short v;
 
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbentry));
                if (i)
@@ -445,7 +457,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                u_char *p;
                char *q;
 
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_READ, (void *)a, sizeof(struct kbsentry));
                if (i)
@@ -530,7 +542,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                struct kbdiacrs *a = (struct kbdiacrs *)arg;
                unsigned int ct;
 
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_READ, (void *) a, sizeof(struct kbdiacrs));
                if (i)
@@ -554,7 +566,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                return 0;
 
        case KDSKBLED:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                if (arg & ~0x77)
                        return -EINVAL;
@@ -582,7 +594,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                struct vt_mode *vtmode = (struct vt_mode *)arg;
                char mode;
 
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_WRITE, (void *)vtmode, sizeof(struct vt_mode));
                if (i)
@@ -659,7 +671,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
         * to preserve sanity).
         */
        case VT_ACTIVATE:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                if (arg == 0 || arg > MAX_NR_CONSOLES)
                        return -ENXIO;
@@ -674,7 +686,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
         * wait until the specified VT has been activated
         */
        case VT_WAITACTIVE:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                if (arg == 0 || arg > MAX_NR_CONSOLES)
                        return -ENXIO;
@@ -697,7 +709,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
         *      2:      completed switch-to OK
         */
        case VT_RELDISP:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                if (vt_cons[console]->vt_mode.mode != VT_PROCESS)
                        return -EINVAL;
@@ -747,7 +759,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
          * Disallocate memory associated to VT (but leave VT1)
          */
         case VT_DISALLOCATE:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                if (arg > MAX_NR_CONSOLES)
                        return -ENXIO;
@@ -776,7 +788,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
        {
                struct vt_sizes *vtsizes = (struct vt_sizes *) arg;
                ushort ll,cc;
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                i = verify_area(VERIFY_READ, (void *)vtsizes, sizeof(struct vt_sizes));
                if (i)
@@ -787,7 +799,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
        }
 
        case PIO_FONT:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                return con_set_font((char *)arg);
                /* con_set_font() defined in console.c */
@@ -797,7 +809,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                /* con_get_font() defined in console.c */
 
        case PIO_SCRNMAP:
-               if (!suser())
+               if (!perm)
                        return -EPERM;
                return con_set_trans((char *)arg);
                /* con_set_trans() defined in console.c */
index de49f494084e626924c3a10453b18146df5b2278..1193fbb65facbfc9d5eef055a5d25e301137d6a3 100644 (file)
@@ -27,7 +27,7 @@
  *     Dmitry Gorodchanin      :       SLIP memory leaks
  *      Dmitry Gorodchanin      :       Code cleanup. Reduce tty driver
  *                                      buffering from 4096 to 256 bytes.
- *                                      Improving SLIP responce time.
+ *                                      Improving SLIP response time.
  *                                      CONFIG_SLIP_MODE_SLIP6.
  *                                      ifconfig sl? up & down now works correctly.
  *                                     Modularization.
index 92b3c12ca055ab836a5c0b393bf0d7ba6a947545..b60c1cb041de31c4d920705332f77f3e4cae0811 100644 (file)
@@ -54,7 +54,7 @@ struct slip {
   unsigned long                rx_packets;     /* inbound frames counter       */
   unsigned long         tx_packets;     /* outbound frames counter      */
   unsigned long         rx_errors;      /* Parity, etc. errors          */
-  unsigned long         tx_errors;      /* Palnned stuff                */
+  unsigned long         tx_errors;      /* Planned stuff                */
   unsigned long         rx_dropped;     /* No memory for skb            */
   unsigned long         tx_dropped;     /* When MTU change              */
   unsigned long         rx_over_errors; /* Frame bigger then SLIP buf.  */
index 77f837e642786edf1de049ee0d3725cc6360bd70..14ec86b8de534b5a25fb69b5ae1cb1f5811fd1fd 100644 (file)
    with a MIDI card, which frequently also uses 0x330.
 
    This can also be overridden on the command line to the kernel, via LILO or
-   LODLIN. */
+   LOADLIN. */
 static unsigned short bases[7] = {
 #ifdef BUSLOGIC_PORT_OVERRIDE
     BUSLOGIC_PORT_OVERRIDE,
index 6c4f46da10cd24906a6e15c6524ee62b56b831f4..3a655c56d353fa8b944f5998b4cb79c144a530bc 100644 (file)
@@ -165,6 +165,8 @@ static struct blist blacklist[] =
    {"MEDIAVIS","CDR-H93MV","1.31"},  /* Locks up if polled for lun != 0 */
    {"SANKYO", "CP525","6.64"},  /* causes failed REQ SENSE, extra reset */
    {"HP", "C1750A", "3226"},    /* scanjet iic */
+   {"HP", "C1790A", ""},       /* scanjet iip */
+   {"HP", "C2500A", ""},       /* scanjet iicx */
    {NULL, NULL, NULL}};        
 
 static int blacklisted(unsigned char * response_data){
@@ -2188,7 +2190,7 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
 }
 
 /*
- * Similarily, this entry point should be called by a loadable module if it
+ * Similarly, this entry point should be called by a loadable module if it
  * is trying to remove a low level scsi driver from the system.
  */
 static void scsi_unregister_host(Scsi_Host_Template * tpnt)
index 253f8d2dca03177dc312a6f59d2de47545273abf..6acb7bb5d327c65e4373bca2034bc1f723e5af91 100644 (file)
@@ -49,6 +49,7 @@ struct hd_struct * sd;
 Scsi_Disk * rscsi_disks;
 static int * sd_sizes;
 static int * sd_blocksizes;
+static int * sd_hardsizes;             /* Hardware sector size */
 
 extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 
@@ -994,6 +995,21 @@ static int sd_init_onedisk(int i)
            return i;
          };
        }
+    {
+       /*
+          The msdos fs need to know the hardware sector size
+          So I have created this table. See ll_rw_blk.c
+          Jacques Gelinas (Jacques@solucorp.qc.ca)
+       */
+       int m;
+       int hard_sector = rscsi_disks[i].sector_size;
+       /* There is 16 minor allocated for each devices */
+       for (m=i<<4; m<((i+1)<<4); m++){
+         sd_hardsizes[m] = hard_sector;
+       }
+       printk ("SCSI Hardware sector size is %d bytes on device sd%c\n"
+         ,hard_sector,i+'a');
+    }
       if(rscsi_disks[i].sector_size == 1024)
        rscsi_disks[i].capacity <<= 1;  /* Change this into 512 byte sectors */
       if(rscsi_disks[i].sector_size == 256)
@@ -1042,9 +1058,14 @@ static void sd_init()
 
        sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
                                                 sizeof(int));
-       for(i=0;i<(sd_template.dev_max << 4);i++) sd_blocksizes[i] = 1024;
+       sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
+                                                sizeof(int));
+       for(i=0;i<(sd_template.dev_max << 4);i++){
+               sd_blocksizes[i] = 1024;
+               sd_hardsizes[i] = 512;
+       }
        blksize_size[MAJOR_NR] = sd_blocksizes;
-
+       hardsect_size[MAJOR_NR] = sd_hardsizes;
        sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
                                                   sizeof(struct hd_struct));
 
index 9d7dca68c821bae34b3dc09615ce2d99b44d1d25..323c3a86aceeccf4d7eeee139dc7eea20041118f 100644 (file)
@@ -290,11 +290,14 @@ static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
 static inline int find_and_clear_bit_16(unsigned short *field)
 {
   int rv;
+  unsigned long flags;
+
+  save_flags(flags);
   cli();
   if (*field == 0) panic("No free mscp");
   asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
       : "=&r" (rv), "=m" (*field) : "1" (*field));
-  sti();
+  restore_flags(flags);
   return rv;
 }
 
index a40bdf31606592b3c7514f99b90c8710d0e070dc..b236a5cdb30f8b1481c92bb6689945fb5777fca4 100644 (file)
@@ -29,7 +29,7 @@
  * to be short.
  */
 #define DCACHE_NAME_LEN        15
-#define DCACHE_SIZE 64
+#define DCACHE_SIZE 128
 
 struct hash_list {
        struct dir_cache_entry * next;
index b272ba11eac5cced6b39641b9e4b720109ca1b86..89853271d56032e48b381b3ffc638ab00371c45e 100644 (file)
 #include <linux/malloc.h>
 #include <linux/errno.h>
 
-#define MULTISESSION /* emoenke@gwdg.de */
-#ifdef MULTISESSION
-#include <linux/cdrom.h>
-#endif MULTISESSION
-
 #include <asm/system.h>
 #include <asm/segment.h>
 
@@ -150,14 +145,6 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
        unsigned int blocksize_bits;
        int high_sierra;
        int dev=s->s_dev;
-#ifdef MULTISESSION
-       int i;
-       unsigned int vol_desc_start;
-       unsigned int *p_vol_desc_start=&vol_desc_start;
-       struct inode inode_fake;
-       struct file file_fake;
-       extern struct file_operations * get_blkfops(unsigned int);
-#endif MULTISESSION
        struct iso_volume_descriptor *vdp;
        struct hs_volume_descriptor *hdp;
 
@@ -197,27 +184,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
 
        s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
 
-#ifdef MULTISESSION
-       /*
-        * look if the driver can tell the multi session redirection
-         * value; this allows to do the redirection if we are looking
-         * for the volume descriptor, and to avoid it during "raw" access.
-         */
-       vol_desc_start=0;
-       inode_fake.i_rdev=dev;
-       i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
-                                        &file_fake,
-                                        CDROMMULTISESSION_SYS,
-                                        (unsigned long) p_vol_desc_start);
-       if (i!=0) vol_desc_start=0;
-#if 0
-       printk("isofs.inode: CDROMMULTISESSION_SYS rc=%d\n",i);
-       printk("isofs.inode: vol_desc_start = %d\n", vol_desc_start);
-#endif
-       for (iso_blknum = vol_desc_start+16; iso_blknum < vol_desc_start+100; iso_blknum++) {
-#else
        for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
-#endif MULTISESSION
                if (!(bh = bread(dev, iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits), opt.blocksize))) {
                        s->s_dev=0;
                        printk("isofs_read_super: bread failed, dev 0x%x iso_blknum %d\n",
index 2c690d3ea0fc7847fae04e4fb248746ae5f6f9b1..479332dc3fe60219850243a670873686a9a8aaaa 100644 (file)
@@ -18,7 +18,7 @@ endif
 .s.o:
        $(AS) -o $*.o $<
 
-OBJS=  namei.o inode.o file.o dir.o misc.o fat.o
+OBJS=  buffer.o namei.o inode.o file.o dir.o misc.o fat.o mmap.o
 
 msdos.o: $(OBJS)
        $(LD) -r -o msdos.o $(OBJS)
diff --git a/fs/msdos/buffer.c b/fs/msdos/buffer.c
new file mode 100644 (file)
index 0000000..8bb34ed
--- /dev/null
@@ -0,0 +1,144 @@
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/msdos_fs.h>
+
+struct buffer_head *msdos_bread (
+       struct super_block *sb,
+       int block)
+{
+       struct buffer_head *ret = NULL;
+       if (sb->s_blocksize == 512){
+               ret = bread (sb->s_dev,block,512);
+       }else{
+               struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
+               if (real != NULL){
+                       ret = (struct buffer_head *)kmalloc (sizeof(struct buffer_head)
+                               ,GFP_KERNEL);
+                       if (ret != NULL){
+                               /* #Specification: msdos / strategy / special device / dummy blocks
+                                       Many special device (Scsi optical disk for one) use
+                                       larger hardware sector size. This allows for higher
+                                       capacity.
+
+                                       Most of the time, the MsDOS file system that sit
+                                       on this device is totally unaligned. It use logically
+                                       512 bytes sector size, with logical sector starting
+                                       in the middle of a hardware block. The bad news is
+                                       that a hardware sector may hold data own by two
+                                       different files. This means that the hardware sector
+                                       must be read, patch and written allmost all the time.
+
+                                       Needless to say that it kills write performance
+                                       on all OS.
+
+                                       Internally the linux msdos fs is using 512 bytes
+                                       logical sector. When accessing such a device, we
+                                       allocate dummy buffer cache blocks, that we stuff
+                                       with the information of a real one (1k large).
+
+                                       This strategy is used to hide this difference to
+                                       the core of the msdos fs. The slowdown is not
+                                       hidden though!
+                               */
+                               /*
+                                       THe memset is there only to catch errors. The msdos
+                                       fs is only unsing b_data
+                               */
+                               memset (ret,0,sizeof(*ret));
+                               ret->b_data = real->b_data;
+                               if (block & 1) ret->b_data += 512;
+                               ret->b_next = real;
+                       }else{
+                               brelse (real);
+                       }
+               }
+       }
+       return ret;
+}
+struct buffer_head *msdos_getblk (
+       struct super_block *sb,
+       int block)
+{
+       struct buffer_head *ret = NULL;
+       if (sb->s_blocksize == 512){
+               ret = getblk (sb->s_dev,block,512);
+       }else{
+               /* #Specification: msdos / special device / writing
+                       A write is always preceded by a read of the complete block
+                       (large hardware sector size). This defeat write performance.
+                       There is a possibility to optimize this when writing large
+                       chunk by making sure we are filling large block. Volunter ?
+               */
+               ret = msdos_bread (sb,block);
+       }
+       return ret;
+}
+
+void msdos_brelse (
+       struct super_block *sb,
+       struct buffer_head *bh)
+{
+       if (bh != NULL){
+               if (sb->s_blocksize == 512){
+                       brelse (bh);
+               }else{
+                       brelse (bh->b_next);
+                       /* We can free the dummy because a new one is allocated at
+                               each msdos_getblk() and msdos_bread().
+                       */
+                       kfree (bh);
+               }
+       }
+}
+       
+void msdos_mark_buffer_dirty (
+       struct super_block *sb,
+       struct buffer_head *bh,
+       int dirty_val)
+{
+       if (sb->s_blocksize != 512){
+               bh = bh->b_next;
+       }
+       mark_buffer_dirty (bh,dirty_val);
+}
+
+void msdos_set_uptodate (
+       struct super_block *sb,
+       struct buffer_head *bh,
+       int val)
+{
+       if (sb->s_blocksize != 512){
+               bh = bh->b_next;
+       }
+       bh->b_uptodate = val;
+}
+int msdos_is_uptodate (
+       struct super_block *sb,
+       struct buffer_head *bh)
+{
+       if (sb->s_blocksize != 512){
+               bh = bh->b_next;
+       }
+       return bh->b_uptodate;
+}
+
+void msdos_ll_rw_block (
+       struct super_block *sb,
+       int opr,
+       int nbreq,
+       struct buffer_head *bh[32])
+{
+       if (sb->s_blocksize == 512){
+               ll_rw_block(opr,nbreq,bh);
+       }else{
+               struct buffer_head *tmp[32];
+               int i;
+               for (i=0; i<nbreq; i++){
+                       tmp[i] = bh[i]->b_next;
+               }
+               ll_rw_block(opr,nbreq,tmp);
+       }
+}
+
index 2138b8778c5293d1ea556e45c45cf3b0acfbf09c..77bd05c224d48b7f50fb891cd89f9d52f8e151a6 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 
+#include "msbuffer.h"
+
 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
 #define ROUND_UP(x) (((x)+3) & ~3)
 
@@ -62,6 +64,7 @@ int msdos_readdir(
        struct dirent *dirent,  /* dirent in user space */
        int count)
 {
+       struct super_block *sb = inode->i_sb;
        int ino,i,i2,last;
        char c,*walk;
        struct buffer_head *bh;
index 651e58b2446171125238bdfe6d244378efb41e59..0e4526599aa54532e434ef78cc73733bae08ff38 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 
+#include "msbuffer.h"
 
 static struct fat_cache *fat_cache,cache[FAT_CACHE];
 
@@ -28,16 +29,16 @@ int fat_access(struct super_block *sb,int nr,int new_value)
                first = nr*3/2;
                last = first+1;
        }
-       if (!(bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(first >>
-           SECTOR_BITS)))) {
+       if (!(bh = bread(sb->s_dev,MSDOS_SB(sb)->fat_start+(first >>
+           SECTOR_BITS),SECTOR_SIZE))) {
                printk("bread in fat_access failed\n");
                return 0;
        }
        if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS))
                bh2 = bh;
        else {
-               if (!(bh2 = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(last
-                   >> SECTOR_BITS)))) {
+               if (!(bh2 = bread(sb->s_dev,MSDOS_SB(sb)->fat_start+(last
+                   >> SECTOR_BITS),SECTOR_SIZE))) {
                        brelse(bh);
                        printk("bread in fat_access failed\n");
                        return 0;
@@ -74,16 +75,16 @@ int fat_access(struct super_block *sb,int nr,int new_value)
                }
                mark_buffer_dirty(bh, 1);
                for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) {
-                       if (!(c_bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->
+                       if (!(c_bh = bread(sb->s_dev,MSDOS_SB(sb)->
                            fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)->
-                           fat_length*copy))) break;
+                           fat_length*copy,SECTOR_SIZE))) break;
                        memcpy(c_bh->b_data,bh->b_data,SECTOR_SIZE);
                        mark_buffer_dirty(c_bh, 1);
                        if (bh != bh2) {
-                               if (!(c_bh2 = msdos_sread(sb->s_dev,
+                               if (!(c_bh2 = bread(sb->s_dev,
                                    MSDOS_SB(sb)->fat_start+(first >>
                                    SECTOR_BITS)+MSDOS_SB(sb)->fat_length*copy
-                                   +1))) {
+                                   +1,SECTOR_SIZE))) {
                                        brelse(c_bh);
                                        break;
                                }
index fb41fff21d7d04301061c2056945b69d91e68a4b..0580b83e7429ea6f149aa178dec04f59a4df3953 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 
+#include "msbuffer.h"
+
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
 
@@ -55,6 +57,52 @@ struct inode_operations msdos_file_inode_operations = {
        NULL,                   /* permission */
        NULL                    /* smap */
 };
+/* #Specification: msdos / special devices / mmap      
+       Mmapping does work because a special mmap is provide in that case.
+       Note that it is much less efficient than the generic_mmap normally
+       used since it allocate extra buffer. generic_mmap is used for
+       normal device (512 bytes hardware sectors).
+*/
+static struct file_operations msdos_file_operations_1024 = {
+       NULL,                   /* lseek - default */
+       msdos_file_read,        /* read */
+       msdos_file_write,       /* write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* select - default */
+       NULL,                   /* ioctl - default */
+       msdos_mmap,             /* mmap */
+       NULL,                   /* no special open is needed */
+       NULL,                   /* release */
+       file_fsync              /* fsync */
+};
+
+/* #Specification: msdos / special devices / swap file
+       Swap file can't work on special devices with a large sector
+       size (1024 bytes hard sector). Those devices have a weird
+       MsDOS filesystem layout. Generally a single hardware sector
+       may contain 2 unrelated logical sector. This mean that there is
+       no easy way to do a mapping between disk sector of a file and virtual
+       memory. So swap file is difficult (not available right now)
+       on those devices. Off course, Ext2 does not have this problem.
+*/
+struct inode_operations msdos_file_inode_operations_1024 = {
+       &msdos_file_operations_1024,    /* default file operations */
+       NULL,                   /* create */
+       NULL,                   /* lookup */
+       NULL,                   /* link */
+       NULL,                   /* unlink */
+       NULL,                   /* symlink */
+       NULL,                   /* mkdir */
+       NULL,                   /* rmdir */
+       NULL,                   /* mknod */
+       NULL,                   /* rename */
+       NULL,                   /* readlink */
+       NULL,                   /* follow_link */
+       NULL,                   /* bmap */
+       msdos_truncate,         /* truncate */
+       NULL,                   /* permission */
+       NULL                    /* smap */
+};
 
 #define MSDOS_PREFETCH 32
 struct msdos_pre {
@@ -72,6 +120,7 @@ static void msdos_prefetch (
        struct msdos_pre *pre,
        int nb)         /* How many must be prefetch at once */
 {
+       struct super_block *sb = inode->i_sb;
        struct buffer_head *bhreq[MSDOS_PREFETCH];      /* Buffers not */
                                                                                                /* already read */
        int nbreq=0;                    /* Number of buffers in bhreq */
@@ -85,12 +134,12 @@ static void msdos_prefetch (
                        bh = getblk(inode->i_dev,sector,SECTOR_SIZE);
                        if (bh == NULL) break;
                        pre->bhlist[pre->nblist++] = bh;
-                       if (!bh->b_uptodate) bhreq[nbreq++] = bh;
+                       if (!msdos_is_uptodate(sb,bh)) bhreq[nbreq++] = bh;
                }else{
                        break;
                }
        }
-       if (nbreq > 0) ll_rw_block (READ,nbreq,bhreq);
+       if (nbreq > 0) msdos_ll_rw_block (sb,READ,nbreq,bhreq);
        for (i=pre->nblist; i<MSDOS_PREFETCH; i++) pre->bhlist[i] = NULL;
 }
 
@@ -103,6 +152,7 @@ int msdos_file_read(
        char *buf,
        int count)
 {
+       struct super_block *sb = inode->i_sb;
        char *start = buf;
        char *end   = buf + count;
        int i;
@@ -172,7 +222,7 @@ int msdos_file_read(
                }
                PRINTK (("file_read pos %ld nblist %d %d %d\n",filp->f_pos,pre.nblist,pre.fetched,count));
                wait_on_buffer(bh);
-               if (!bh->b_uptodate){
+               if (!msdos_is_uptodate(sb,bh)){
                        /* read error  ? */
                        brelse (bh);
                        break;
@@ -216,6 +266,7 @@ int msdos_file_write(
        char *buf,
        int count)
 {
+       struct super_block *sb = inode->i_sb;
        int sector,offset,size,left,written;
        int error,carry;
        char *start,*to,ch;
@@ -258,7 +309,7 @@ int msdos_file_write(
                                error = -EIO;
                                break;
                        }
-               }else if (!(bh = msdos_sread(inode->i_dev,sector))) {
+               }else if (!(bh = bread(inode->i_dev,sector,SECTOR_SIZE))) {
                        error = -EIO;
                        break;
                }
@@ -292,7 +343,7 @@ int msdos_file_write(
                        inode->i_size = filp->f_pos;
                        inode->i_dirt = 1;
                }
-               bh->b_uptodate = 1;
+               msdos_set_uptodate(sb,bh,1);
                mark_buffer_dirty(bh, 0);
                brelse(bh);
        }
index d8de491bdbc1990b377a18c067232d4f6b92add3..35bee66036bcaa9eb96c1d1fb06fee845a9b97f8 100644 (file)
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/major.h>
+#include <linux/blkdev.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
 
+#include "msbuffer.h"
+
 #ifdef MODULE
        #include <linux/module.h>
        #include <linux/version.h>
@@ -79,7 +82,8 @@ static struct super_operations msdos_sops = {
 
 
 static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
-    gid_t *gid,int *umask,int *debug,int *fat,int *quiet)
+    gid_t *gid,int *umask,int *debug,int *fat,int *quiet,
+       int *blksize)
 {
        char *this_char,*value;
 
@@ -145,6 +149,14 @@ static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
                        if (value) return 0;
                        *quiet = 1;
                }
+               else if (!strcmp(this_char,"blocksize")) {
+                       *blksize = simple_strtoul(value,&value,0);
+                       if (*value)
+                               return 0;
+                       if (*blksize != 512 && *blksize != 1024){
+                               printk ("MSDOS FS: Invalid blocksize (512 or 1024)\n");
+                       }
+               }
                else return 0;
        }
        return 1;
@@ -153,7 +165,7 @@ static int parse_options(char *options,char *check,char *conversion,uid_t *uid,
 
 /* Read the super block of an MS-DOS FS. */
 
-struct super_block *msdos_read_super(struct super_block *s,void *data,
+struct super_block *msdos_read_super(struct super_block *sb,void *data,
                                     int silent)
 {
        struct buffer_head *bh;
@@ -164,28 +176,34 @@ struct super_block *msdos_read_super(struct super_block *s,void *data,
        uid_t uid;
        gid_t gid;
        int umask;
-
+       int blksize = 512;
+       if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
+               blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
+               if (blksize != 512){
+                       printk ("MSDOS: Hardware sector size is %d\n",blksize);
+               }
+       }
        if (!parse_options((char *) data,&check,&conversion,&uid,&gid,&umask,
-           &debug,&fat,&quiet)) {
-               s->s_dev = 0;
+           &debug,&fat,&quiet,&blksize)
+               || (blksize != 512 && blksize != 1024)) {
+               sb->s_dev = 0;
                return NULL;
        }
        cache_init();
-       lock_super(s);
-       set_blocksize(s->s_dev, SECTOR_SIZE);
-       bh = bread(s->s_dev, 0, SECTOR_SIZE);
-       unlock_super(s);
-       if (bh == NULL) {
-               s->s_dev = 0;
+       lock_super(sb);
+       /* The first read is always 1024 bytes */
+       sb->s_blocksize = 1024;
+       set_blocksize(sb->s_dev, 1024);
+       bh = bread(sb->s_dev, 0, 1024);
+       unlock_super(sb);
+       if (bh == NULL || !msdos_is_uptodate(sb,bh)) {
+               brelse (bh);
+               sb->s_dev = 0;
                printk("MSDOS bread failed\n");
                return NULL;
        }
        b = (struct msdos_boot_sector *) bh->b_data;
-       s->s_blocksize = 512;   /* Using this small block size solve the */
-                               /* the misfit with buffer cache and cluster */
-                               /* because cluster (DOS) are often aligned */
-                               /* on odd sector */
-       s->s_blocksize_bits = 9;        /* we cannot handle anything else yet */
+       set_blocksize(sb->s_dev, blksize);
 /*
  * The DOS3 partition size limit is *not* 32M as many people think.  
  * Instead, it is 64K sectors (with the usual sector size being
@@ -206,75 +224,85 @@ struct super_block *msdos_read_super(struct super_block *s,void *data,
 
        logical_sector_size = CF_LE_W(*(unsigned short *) &b->sector_size);
        sector_mult = logical_sector_size >> SECTOR_BITS;
-       MSDOS_SB(s)->cluster_size = b->cluster_size*sector_mult;
-       MSDOS_SB(s)->fats = b->fats;
-       MSDOS_SB(s)->fat_start = CF_LE_W(b->reserved)*sector_mult;
-       MSDOS_SB(s)->fat_length = CF_LE_W(b->fat_length)*sector_mult;
-       MSDOS_SB(s)->dir_start = (CF_LE_W(b->reserved)+b->fats*CF_LE_W(
+       MSDOS_SB(sb)->cluster_size = b->cluster_size*sector_mult;
+       MSDOS_SB(sb)->fats = b->fats;
+       MSDOS_SB(sb)->fat_start = CF_LE_W(b->reserved)*sector_mult;
+       MSDOS_SB(sb)->fat_length = CF_LE_W(b->fat_length)*sector_mult;
+       MSDOS_SB(sb)->dir_start = (CF_LE_W(b->reserved)+b->fats*CF_LE_W(
            b->fat_length))*sector_mult;
-       MSDOS_SB(s)->dir_entries = CF_LE_W(*((unsigned short *) &b->dir_entries
+       MSDOS_SB(sb)->dir_entries = CF_LE_W(*((unsigned short *) &b->dir_entries
            ));
-       MSDOS_SB(s)->data_start = MSDOS_SB(s)->dir_start+ROUND_TO_MULTIPLE((
-           MSDOS_SB(s)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
+       MSDOS_SB(sb)->data_start = MSDOS_SB(sb)->dir_start+ROUND_TO_MULTIPLE((
+           MSDOS_SB(sb)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
            sector_mult);
        data_sectors = (CF_LE_W(*((unsigned short *) &b->sectors)) ?
            CF_LE_W(*((unsigned short *) &b->sectors)) :
-           CF_LE_L(b->total_sect))*sector_mult-MSDOS_SB(s)->data_start;
+           CF_LE_L(b->total_sect))*sector_mult-MSDOS_SB(sb)->data_start;
        error = !b->cluster_size || !sector_mult;
        if (!error) {
-               MSDOS_SB(s)->clusters = b->cluster_size ? data_sectors/
+               MSDOS_SB(sb)->clusters = b->cluster_size ? data_sectors/
                    b->cluster_size/sector_mult : 0;
-               MSDOS_SB(s)->fat_bits = fat ? fat : MSDOS_SB(s)->clusters >
+               MSDOS_SB(sb)->fat_bits = fat ? fat : MSDOS_SB(sb)->clusters >
                    MSDOS_FAT12 ? 16 : 12;
-               error = !MSDOS_SB(s)->fats || (MSDOS_SB(s)->dir_entries &
-                   (MSDOS_DPS-1)) || MSDOS_SB(s)->clusters+2 > MSDOS_SB(s)->
-                   fat_length*SECTOR_SIZE*8/MSDOS_SB(s)->fat_bits ||
+               error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries &
+                   (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > MSDOS_SB(sb)->
+                   fat_length*SECTOR_SIZE*8/MSDOS_SB(sb)->fat_bits ||
                    (logical_sector_size & (SECTOR_SIZE-1)) || !b->secs_track ||
                    !b->heads;
        }
        brelse(bh);
+       /*
+               This must be done after the brelse because the bh is a dummy
+               allocated by msdos_bread (see buffer.c)
+       */
+       sb->s_blocksize = blksize;      /* Using this small block size solve the */
+                               /* the misfit with buffer cache and cluster */
+                               /* because cluster (DOS) are often aligned */
+                               /* on odd sector */
+       sb->s_blocksize_bits = blksize == 512 ? 9 : 10;
        if (error || debug) {
                /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
                printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
-                   "uid=%d,gid=%d,umask=%03o%s]\n",MSDOS_SB(s)->fat_bits,check,
-                   conversion,uid,gid,umask,MSDOS_CAN_BMAP(MSDOS_SB(s)) ?
+                   "uid=%d,gid=%d,umask=%03o%s]\n",MSDOS_SB(sb)->fat_bits,check,
+                   conversion,uid,gid,umask,MSDOS_CAN_BMAP(MSDOS_SB(sb)) ?
                    ",bmap" : "");
                printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,"
-                   "se=%d,ts=%ld,ls=%d]\n",b->media,MSDOS_SB(s)->cluster_size,
-                   MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start,MSDOS_SB(s)->
-                   fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries,
-                   MSDOS_SB(s)->data_start,CF_LE_W(*(unsigned short *) &b->
+                   "se=%d,ts=%ld,ls=%d]\n",b->media,MSDOS_SB(sb)->cluster_size,
+                   MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,MSDOS_SB(sb)->
+                   fat_length,MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
+                   MSDOS_SB(sb)->data_start,CF_LE_W(*(unsigned short *) &b->
                    sectors),b->total_sect,logical_sector_size);
+               printk ("Transaction block size = %d\n",blksize);
        }
        if (error) {
                if (!silent)
                        printk("VFS: Can't find a valid MSDOS filesystem on dev 0x%04x.\n",
-                                  s->s_dev);
-               s->s_dev = 0;
+                                  sb->s_dev);
+               sb->s_dev = 0;
                return NULL;
        }
-       s->s_magic = MSDOS_SUPER_MAGIC;
-       MSDOS_SB(s)->name_check = check;
-       MSDOS_SB(s)->conversion = conversion;
+       sb->s_magic = MSDOS_SUPER_MAGIC;
+       MSDOS_SB(sb)->name_check = check;
+       MSDOS_SB(sb)->conversion = conversion;
        /* set up enough so that it can read an inode */
-       s->s_op = &msdos_sops;
-       MSDOS_SB(s)->fs_uid = uid;
-       MSDOS_SB(s)->fs_gid = gid;
-       MSDOS_SB(s)->fs_umask = umask;
-       MSDOS_SB(s)->quiet = quiet;
-       MSDOS_SB(s)->free_clusters = -1; /* don't know yet */
-       MSDOS_SB(s)->fat_wait = NULL;
-       MSDOS_SB(s)->fat_lock = 0;
-       MSDOS_SB(s)->prev_free = 0;
-       if (!(s->s_mounted = iget(s,MSDOS_ROOT_INO))) {
-               s->s_dev = 0;
+       sb->s_op = &msdos_sops;
+       MSDOS_SB(sb)->fs_uid = uid;
+       MSDOS_SB(sb)->fs_gid = gid;
+       MSDOS_SB(sb)->fs_umask = umask;
+       MSDOS_SB(sb)->quiet = quiet;
+       MSDOS_SB(sb)->free_clusters = -1; /* don't know yet */
+       MSDOS_SB(sb)->fat_wait = NULL;
+       MSDOS_SB(sb)->fat_lock = 0;
+       MSDOS_SB(sb)->prev_free = 0;
+       if (!(sb->s_mounted = iget(sb,MSDOS_ROOT_INO))) {
+               sb->s_dev = 0;
                printk("get root inode failed\n");
                return NULL;
        }
        #ifdef MODULE
                MOD_INC_USE_COUNT;
        #endif
-       return s;
+       return sb;
 }
 
 
@@ -321,6 +349,7 @@ int msdos_bmap(struct inode *inode,int block)
 
 void msdos_read_inode(struct inode *inode)
 {
+       struct super_block *sb = inode->i_sb;
        struct buffer_head *bh;
        struct msdos_dir_entry *raw_entry;
        int nr;
@@ -384,7 +413,9 @@ void msdos_read_inode(struct inode *inode)
                inode->i_mode = MSDOS_MKMODE(raw_entry->attr,(IS_NOEXEC(inode)
                    ? S_IRUGO|S_IWUGO : S_IRWXUGO) & ~MSDOS_SB(inode->i_sb)->fs_umask) |
                    S_IFREG;
-               inode->i_op = &msdos_file_inode_operations;     /* Now can always bmap */
+               inode->i_op = sb->s_blocksize == 1024
+                       ? &msdos_file_inode_operations_1024
+                       : &msdos_file_inode_operations;
                MSDOS_I(inode)->i_start = CF_LE_W(raw_entry->start);
                inode->i_nlink = 1;
                inode->i_size = CF_LE_L(raw_entry->size);
@@ -404,6 +435,7 @@ void msdos_read_inode(struct inode *inode)
 
 void msdos_write_inode(struct inode *inode)
 {
+       struct super_block *sb = inode->i_sb;
        struct buffer_head *bh;
        struct msdos_dir_entry *raw_entry;
 
index 630198afa2859a406cfa85feee4921f9e691bff6..79ccbe23bccd3038d95f31e692a91ce69160494a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 
+#include "msbuffer.h"
 
 #define PRINTK(x)
 /* Well-known binary file extensions */
@@ -111,6 +112,7 @@ void unlock_fat(struct super_block *sb)
 
 int msdos_add_cluster(struct inode *inode)
 {
+       struct super_block *sb = inode->i_sb;
        int count,nr,limit,last,current,sector,last_sector;
        struct buffer_head *bh;
        int cluster_size = MSDOS_SB(inode->i_sb)->cluster_size;
@@ -173,7 +175,7 @@ if (last) printk("next set to %d\n",fat_access(inode->i_sb,last,-1));
                        printk("getblk failed\n");
                else {
                        memset(bh->b_data,0,SECTOR_SIZE);
-                       bh->b_uptodate = 1;
+                       msdos_set_uptodate(sb,bh,1);
                        mark_buffer_dirty(bh, 1);
                        brelse(bh);
                }
@@ -255,6 +257,7 @@ void date_unix2dos(int unix_date,unsigned short *time,
 int msdos_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
     struct msdos_dir_entry **de)
 {
+       struct super_block *sb = dir->i_sb;
        int sector,offset;
 
        while (1) {
@@ -269,7 +272,7 @@ int msdos_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
                if (*bh)
                        brelse(*bh);
                PRINTK (("get_entry sector apres brelse\n"));
-               if (!(*bh = msdos_sread(dir->i_dev,sector))) {
+               if (!(*bh = bread(dir->i_dev,sector,SECTOR_SIZE))) {
                        printk("Directory sread (sector %d) failed\n",sector);
                        continue;
                }
@@ -343,7 +346,7 @@ static int raw_scan_sector(struct super_block *sb,int sector,char *name,
        struct inode *inode;
        int entry,start,done;
 
-       if (!(bh = msdos_sread(sb->s_dev,sector))) return -EIO;
+       if (!(bh = bread(sb->s_dev,sector,SECTOR_SIZE))) return -EIO;
        data = (struct msdos_dir_entry *) bh->b_data;
        for (entry = 0; entry < MSDOS_DPS; entry++) {
                if (name) RSS_NAME
diff --git a/fs/msdos/mmap.c b/fs/msdos/mmap.c
new file mode 100644 (file)
index 0000000..da188a3
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *     fs/msdos/mmap.c
+ *
+ *     Written by Jacques Gelinas (jacques@solucorp.qc.ca)
+ *     Inspired by fs/nfs/mmap.c (Jaon Tombs 15 Aug 1993)
+ *
+ *     msdos mmap handling
+ */
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <linux/mman.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <linux/msdos_fs.h>
+
+/*
+ * Fill in the supplied page for mmap
+ */
+static unsigned long msdos_file_mmap_nopage(
+       struct vm_area_struct * area,
+       unsigned long address,
+       unsigned long page,
+       int error_code)
+{
+       struct inode * inode = area->vm_inode;
+       unsigned int clear;
+       int pos;
+       long gap;       /* distance from eof to pos */
+
+       address &= PAGE_MASK;
+       pos = address - area->vm_start + area->vm_offset;
+
+       clear = 0;
+       gap = inode->i_size - pos;
+       if (gap <= 0){
+               /* mmaping beyond end of file */
+               clear = PAGE_SIZE;
+       }else{
+               int cur_read;
+               int need_read;
+               struct file filp;
+               if (gap < PAGE_SIZE){
+                       clear = PAGE_SIZE - gap;
+               }
+               filp.f_reada = 0;
+               filp.f_pos = pos;
+               need_read = PAGE_SIZE - clear;
+               {
+                       unsigned long cur_fs = get_fs();
+                       set_fs (KERNEL_DS);
+                       cur_read = msdos_file_read (inode,&filp,(char*)page
+                               ,need_read);
+                       set_fs (cur_fs);
+               }
+               if (cur_read != need_read){
+                       printk ("MSDOS: Error while reading an mmap file %d <> %d\n"
+                               ,cur_read,need_read);
+               }
+       }
+       if (clear > 0){
+               memset ((char*)page+PAGE_SIZE-clear,0,clear);
+       }
+       return page;
+}
+
+struct vm_operations_struct msdos_file_mmap = {
+       NULL,                   /* open */
+       NULL,                   /* close */
+       NULL,                   /* unmap */
+       NULL,                   /* protect */
+       NULL,                   /* sync */
+       NULL,                   /* advise */
+       msdos_file_mmap_nopage, /* nopage */
+       NULL,                   /* wppage */
+       NULL,                   /* swapout */
+       NULL,                   /* swapin */
+};
+
+/*
+ * This is used for a general mmap of an msdos file
+ * Returns 0 if ok, or a negative error code if not.
+ */
+int msdos_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
+{
+       if (vma->vm_page_prot & PAGE_RW)        /* only PAGE_COW or read-only supported now */
+               return -EINVAL;
+       if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
+               return -EINVAL;
+       if (!inode->i_sb || !S_ISREG(inode->i_mode))
+               return -EACCES;
+       if (!IS_RDONLY(inode)) {
+               inode->i_atime = CURRENT_TIME;
+               inode->i_dirt = 1;
+       }
+
+       vma->vm_inode = inode;
+       inode->i_count++;
+       vma->vm_ops = &msdos_file_mmap;
+       return 0;
+}
+
diff --git a/fs/msdos/msbuffer.h b/fs/msdos/msbuffer.h
new file mode 100644 (file)
index 0000000..50d62d7
--- /dev/null
@@ -0,0 +1,22 @@
+/* buffer.c 13/12/94 20.19.10 */
+struct buffer_head *msdos_bread (struct super_block *sb, int block);
+struct buffer_head *msdos_getblk (struct super_block *sb, int block);
+void msdos_brelse (struct super_block *sb, struct buffer_head *bh);
+void msdos_mark_buffer_dirty (struct super_block *sb,
+        struct buffer_head *bh,
+        int dirty_val);
+void msdos_set_uptodate (struct super_block *sb,
+        struct buffer_head *bh,
+        int val);
+int msdos_is_uptodate (struct super_block *sb, struct buffer_head *bh);
+void msdos_ll_rw_block (struct super_block *sb, int opr,
+       int nbreq, struct buffer_head *bh[32]);
+
+/* These macros exist to avoid modifying all the code */
+/* They should be removed one day I guess */
+
+#define brelse(b)                              msdos_brelse(sb,b)
+#define bread(d,b,s)                   msdos_bread(sb,b)
+#define getblk(d,b,s)                  msdos_getblk(sb,b)
+#define mark_buffer_dirty(b,v) msdos_mark_buffer_dirty(sb,b,v)
+
index ad3b9c8bc528d039835c1a1b8f314a086fb4adcd..0ce78f1e4fd907f16c2185e34cbce69d1edb0be9 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/string.h>
 #include <linux/stat.h>
 
+#include "msbuffer.h"
+
 #define PRINTK(x)
 
 /* MS-DOS "device special files" */
@@ -107,6 +109,7 @@ static int msdos_find(struct inode *dir,const char *name,int len,
 int msdos_lookup(struct inode *dir,const char *name,int len,
     struct inode **result)
 {
+       struct super_block *sb = dir->i_sb;
        int ino,res;
        struct msdos_dir_entry *de;
        struct buffer_head *bh;
@@ -173,6 +176,7 @@ int msdos_lookup(struct inode *dir,const char *name,int len,
 static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
     struct inode **result)
 {
+       struct super_block *sb = dir->i_sb;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
        int res,ino;
@@ -209,6 +213,7 @@ static int msdos_create_entry(struct inode *dir,char *name,int is_dir,
 int msdos_create(struct inode *dir,const char *name,int len,int mode,
        struct inode **result)
 {
+       struct super_block *sb = dir->i_sb;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
        char msdos_name[MSDOS_NAME];
@@ -256,6 +261,7 @@ static void dump_fat(struct super_block *sb,int start)
 
 int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
 {
+       struct super_block *sb = dir->i_sb;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
        struct inode *inode,*dot;
@@ -313,6 +319,7 @@ mkdir_error:
 
 static int msdos_empty(struct inode *dir)
 {
+       struct super_block *sb = dir->i_sb;
        loff_t pos;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
@@ -338,6 +345,7 @@ static int msdos_empty(struct inode *dir)
 
 int msdos_rmdir(struct inode *dir,const char *name,int len)
 {
+       struct super_block *sb = dir->i_sb;
        int res,ino;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
@@ -379,6 +387,7 @@ static int msdos_unlinkx(
        int len,
        int nospc)      /* Flag special file ? */
 {
+       struct super_block *sb = dir->i_sb;
        int res,ino;
        struct buffer_head *bh;
        struct msdos_dir_entry *de;
@@ -425,6 +434,7 @@ static int rename_same_dir(struct inode *old_dir,char *old_name,
     struct inode *new_dir,char *new_name,struct buffer_head *old_bh,
     struct msdos_dir_entry *old_de,int old_ino)
 {
+       struct super_block *sb = old_dir->i_sb;
        struct buffer_head *new_bh;
        struct msdos_dir_entry *new_de;
        struct inode *new_inode,*old_inode;
@@ -476,6 +486,7 @@ static int rename_diff_dir(struct inode *old_dir,char *old_name,
     struct inode *new_dir,char *new_name,struct buffer_head *old_bh,
     struct msdos_dir_entry *old_de,int old_ino)
 {
+       struct super_block *sb = old_dir->i_sb;
        struct buffer_head *new_bh,*free_bh,*dotdot_bh;
        struct msdos_dir_entry *new_de,*free_de,*dotdot_de;
        struct inode *old_inode,*new_inode,*free_inode,*dotdot_inode,*walk;
@@ -594,6 +605,7 @@ rename_done:
 int msdos_rename(struct inode *old_dir,const char *old_name,int old_len,
        struct inode *new_dir,const char *new_name,int new_len)
 {
+       struct super_block *sb = old_dir->i_sb;
        char old_msdos_name[MSDOS_NAME],new_msdos_name[MSDOS_NAME];
        struct buffer_head *old_bh;
        struct msdos_dir_entry *old_de;
index 8458d40bc927a40994b2d9076fa60c697e2f9855..4499bbd0dc4d1604c9f9f5a651370321f0aee1d2 100644 (file)
@@ -243,17 +243,16 @@ static int get_version(char * buffer)
 
 static int get_cpuinfo(char * buffer)
 {
-       /* to conserve memory, we define the strins yes and no in
-          advance */
-       char *yes="yes";
-       char *no="no";
        char *model[2][9]={{"DX","SX","DX/2","4","SX/2","6",
                                "7","DX/4"},
                        {"Pentium 60/66","Pentium 90/100","3",
                                "4","5","6","7","8"}};
+       char mask[2];
+       mask[0] = x86_mask+'@';
+       mask[1] = '\0';
        return sprintf(buffer,"cpu\t\t: %c86\n"
                              "model\t\t: %s\n"
-                             "mask\t\t: %c\n"
+                             "mask\t\t: %s\n"
                              "vid\t\t: %s\n"
                              "fdiv_bug\t: %s\n"
                              "math\t\t: %s\n"
@@ -269,20 +268,20 @@ static int get_cpuinfo(char * buffer)
                              "CMPXCHGB8B\t: %s\n",
                              x86+'0', 
                              x86_model ? model[x86-4][x86_model-1] : "Unknown",
-                             x86_mask+'@',
+                             x86_mask ? mask : "Unknown",
                              x86_vendor_id,
-                             fdiv_bug ? yes : no,
-                             hard_math ? yes : no,
-                             hlt_works_ok ? yes : no,
-                             wp_works_ok ? yes : no,
-                             x86_capability & 1 ? yes : no,
-                             x86_capability & 2 ? yes : no,
-                             x86_capability & 4 ? yes : no,
-                             x86_capability & 8 ? yes : no,
-                             x86_capability & 16 ? yes : no,
-                             x86_capability & 32 ? yes : no,
-                             x86_capability & 128 ? yes : no,
-                             x86_capability & 256 ? yes : no
+                             fdiv_bug ? "yes" : "no",
+                             hard_math ? "yes" : "no",
+                             hlt_works_ok ? "yes" : "no",
+                             wp_works_ok ? "yes" : "no",
+                             x86_capability & 1 ? "yes" : "no",
+                             x86_capability & 2 ? "yes" : "no",
+                             x86_capability & 4 ? "yes" : "no",
+                             x86_capability & 8 ? "yes" : "no",
+                             x86_capability & 16 ? "yes" : "no",
+                             x86_capability & 32 ? "yes" : "no",
+                             x86_capability & 128 ? "yes" : "no",
+                             x86_capability & 256 ? "yes" : "no"
                              );
 }
 
@@ -431,7 +430,7 @@ static int get_stat(int pid, char * buffer)
        else
                tty_pgrp = -1;
        return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
-%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %u %lu %lu %lu %lu %lu %lu \
+%lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu\n",
                pid,
                (*p)->comm,
index d292ea3c23ec23707940b754778e3b34dc1d2deb..224d976ba4949b7909414964c08b4ad502cdd9dd 100644 (file)
@@ -58,16 +58,8 @@ static void UMSDOS_truncate(struct inode *inode)
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
        inode->i_dirt = 1;
 }
-/*
-       See inode.c
-       
-       Some entry point are filled dynamically with function pointers
-       from the msdos file_operations and file_inode_operations.
-       
-       The idea is to have the code as independent as possible from
-       the msdos file system.
-*/
 
+/* Function for normal file system (512 bytes hardware sector size) */
 struct file_operations umsdos_file_operations = {
        NULL,                           /* lseek - default */
        UMSDOS_file_read,       /* read */
@@ -94,10 +86,41 @@ struct inode_operations umsdos_file_inode_operations = {
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
-       NULL,                   /* bmap */
+       msdos_bmap,             /* bmap */
        UMSDOS_truncate,/* truncate */
        NULL,                   /* permission */
        msdos_smap              /* smap */
 };
+/* For other with larger and unaligned file system */
+struct file_operations umsdos_file_operations_no_bmap = {
+       NULL,                           /* lseek - default */
+       UMSDOS_file_read,       /* read */
+       UMSDOS_file_write,      /* write */
+       NULL,                           /* readdir - bad */
+       NULL,                           /* select - default */
+       NULL,                           /* ioctl - default */
+       msdos_mmap,                     /* mmap */
+       NULL,                           /* no special open is needed */
+       NULL,                           /* release */
+       file_fsync                      /* fsync */
+};
 
+struct inode_operations umsdos_file_inode_operations_no_bmap = {
+       &umsdos_file_operations_no_bmap,        /* default file operations */
+       NULL,                   /* create */
+       NULL,                   /* lookup */
+       NULL,                   /* link */
+       NULL,                   /* unlink */
+       NULL,                   /* symlink */
+       NULL,                   /* mkdir */
+       NULL,                   /* rmdir */
+       NULL,                   /* mknod */
+       NULL,                   /* rename */
+       NULL,                   /* readlink */
+       NULL,                   /* follow_link */
+       NULL,                   /* bmap */
+       UMSDOS_truncate,/* truncate */
+       NULL,                   /* permission */
+       NULL,                   /* smap */
+};
 
index aa01c3d58e817a50cb60fc441d0f8898faed5e8c..d639b8f6e3e4b984d7d87caa61be42671a853aba 100644 (file)
@@ -45,6 +45,9 @@ void UMSDOS_put_inode(struct inode *inode)
        PRINTK (("put inode %x owner %x pos %d dir %x\n",inode
                ,inode->u.umsdos_i.i_emd_owner,inode->u.umsdos_i.pos
                ,inode->u.umsdos_i.i_emd_dir));
+       if (inode != NULL && inode == pseudo_root){
+               printk ("Umsdos: Oops releasing pseudo_root. Notify jacques@solucorp.qc.ca\n");
+       }
        msdos_put_inode(inode);
 }
 
@@ -152,18 +155,11 @@ void umsdos_patch_inode (
        if (!umsdos_isinit(inode)){
                inode->u.umsdos_i.i_emd_dir = 0;
                if (S_ISREG(inode->i_mode)){
-                       static char is_init = 0;
-                       if (!is_init){
-                               /*
-                                       I don't want to change the msdos file system code
-                                       so I get the address of some subroutine dynamically
-                                       once.
-                               */
-                               umsdos_file_inode_operations.bmap = inode->i_op->bmap;
+                       if (inode->i_op->bmap != NULL){
                                inode->i_op = &umsdos_file_inode_operations;
-                               is_init = 1;
+                       }else{
+                               inode->i_op = &umsdos_file_inode_operations_no_bmap;
                        }
-                       inode->i_op = &umsdos_file_inode_operations;
                }else if (S_ISDIR(inode->i_mode)){
                        if (dir != NULL){
                                umsdos_setup_dir_inode(inode);
@@ -409,7 +405,7 @@ struct super_block *UMSDOS_read_super(
                msdos directory, with all limitation of msdos.
        */
        struct super_block *sb = msdos_read_super(s,data,silent);
-       printk ("UMSDOS Alpha 0.5a (compatibility level %d.%d, fast msdos)\n"
+       printk ("UMSDOS Beta 0.6 (compatibility level %d.%d, fast msdos)\n"
                ,UMSDOS_VERSION,UMSDOS_RELEASE);
        if (sb != NULL){
                sb->s_op = &umsdos_sops;
index 1f59447e94b1f627ba50be5750330d40bc9f9d95..0fe3b54644231e39cd032fc65f551f32eeacdb0d 100644 (file)
@@ -222,13 +222,15 @@ int umsdos_parse (
                                                                with a special character as the first character
                                                                of the extension will be mangled. This solve the
                                                                following problem:
-                               
+
+                                                               #
                                                                touch FILE
                                                                # FILE is invalid for DOS, so mangling is applied
                                                                # file.{_1 is created in the DOS directory
                                                                touch file.{_1
                                                                # To UMSDOS file point to a single DOS entry.
                                                                # So file.{_1 has to be mangled.
+                                                               #
                                                        */      
                                                        static char special[]={
                                                                SPECIAL_MANGLING,'\0'
@@ -270,7 +272,9 @@ int umsdos_parse (
                                Control character are converted to #.
                                Space are converted to #.
                                The following character are also converted to #.
+                               #
                                        " * + , / : ; < = > ? [ \ ] | ~
+                               #
 
                                Sometime, the problem is not in MsDOS itself but in
                                command.com.
@@ -316,10 +320,12 @@ int umsdos_parse (
 
                                Here is the list of DOS pseudo devices:
 
+                               #
                                        "prn","con","aux","nul",
                                        "lpt1","lpt2","lpt3","lpt4",
                                        "com1","com2","com3","com4",
                                        "clock$"
+                               #
 
                                and some standard ones for common DOS programs
 
index 567039e144f7fcbc760d1741ff188a13d1635289..2a59bf813a8f6d9dfc35042d2cbf5e1ede60c139 100644 (file)
@@ -483,6 +483,7 @@ int UMSDOS_link (
                
                Given a file /foo/file
 
+               #
                        ln /foo/file /tmp/file2
 
                        become internally
@@ -490,6 +491,7 @@ int UMSDOS_link (
                        mv /foo/file /foo/-LINK1
                        ln -s /foo/-LINK1 /foo/file
                        ln -s /foo/-LINK1 /tmp/file2
+               #
 
                Using this strategy, we can operate on /foo/file or /foo/file2.
                We can remove one and keep the other, like a normal Unix hard link.
@@ -502,6 +504,7 @@ int UMSDOS_link (
                The strategy for hard link introduces a side effect that
                may or may not be acceptable. Here is the sequence
 
+               #
                mkdir subdir1
                touch subdir1/file
                mkdir subdir2
@@ -509,6 +512,7 @@ int UMSDOS_link (
                rm    subdir1/file
                rmdir subdir1
                rmdir: subdir1: Directory not empty
+               #
 
                This happen because there is an invisible file (--link) in
                subdir1 which is referenced by subdir2/file.
@@ -519,12 +523,14 @@ int UMSDOS_link (
                Another weakness of hard link come from the fact that
                it is based on hidden symbolic links. Here is an example.
 
+               #
                mkdir /subdir1
                touch /subdir1/file
                mkdir /subdir2
                ln    /subdir1/file subdir2/file
                mv    /subdir1 subdir3
                ls -l /subdir2/file
+               #
 
                Since /subdir2/file is a hidden symbolic link
                to /subdir1/..hlinkNNN, accessing it will fail since
@@ -765,6 +771,7 @@ int UMSDOS_rmdir(
                but you rapidly get iput() all around. Here is an exemple
                of what I am trying to avoid.
 
+               #
                if (a){
                        ...
                        if(b){
@@ -783,10 +790,12 @@ int UMSDOS_rmdir(
                }
                // Was iput finally done ?
                return status;
+               #
 
                Here is the style I am using. Still sometime I do the
                first when things are very simple (or very complicated :-( )
 
+               #
                if (a){
                        if (b){
                                ...
@@ -797,6 +806,7 @@ int UMSDOS_rmdir(
                        ...
                }
                return status;
+               #
 
                Again, while this help clarifying the code, I often get a lot
                of iput(), unlike the first style, where I can place few 
@@ -812,6 +822,7 @@ int UMSDOS_rmdir(
                where an iput() is done, the inode is simply nulled, disabling
                the last one.
 
+               #
                if (a){
                        if (b){
                                ...
@@ -824,6 +835,7 @@ int UMSDOS_rmdir(
                }
                iput (dir);
                return status;
+               #
 
                Note that the umsdos_lockcreate() and umsdos_unlockcreate() function
                pair goes against this practice of "forgetting" the inode as soon
diff --git a/include/asm-alpha/bugs.h b/include/asm-alpha/bugs.h
new file mode 100644 (file)
index 0000000..78030d1
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ *  include/asm-alpha/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *     void check_bugs(void);
+ */
+
+/*
+ * I don't know of any alpha bugs yet.. Nice chip
+ */
+
+static void check_bugs(void)
+{
+}
diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
new file mode 100644 (file)
index 0000000..b9d29d9
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * include/asm-i386/processor.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+#ifndef __ASM_I386_PROCESSOR_H
+#define __ASM_I386_PROCESSOR_H
+
+/*
+ * Bus types
+ */
+extern int EISA_bus;
+#define MCA_bus 0
+
+struct thread_struct {
+       unsigned long ksp;
+       unsigned long usp;
+       unsigned long ptbr;
+       unsigned int pcc;
+       unsigned int asn;
+       unsigned long unique;
+       unsigned long flags;
+       unsigned long res1, res2;
+};
+
+#define INIT_TSS  { \
+       0, 0, 0, \
+       0, 0, 0, \
+       0, 0, 0, \
+}
+
+#endif /* __ASM_I386_PROCESSOR_H */
index 54a83bdb3541c49353935b282bb0722f18ae69da..a83952d2591bfee057ec3c05c06e43b9203be563 100644 (file)
 #define PAL_rtsys      61
 #define PAL_rti                63
 
+#define halt() __asm__ __volatile__(".long 0");
+#define move_to_user_mode() halt()
+#define switch_to(x) halt()
+
 #ifndef mb
 #define mb() __asm__ __volatile__("mb": : :"memory")
 #endif
@@ -77,4 +81,44 @@ __asm__ __volatile__( \
        : "$0", "$1", "$16", "$22", "$23", "$24", "$25"); \
 __old_ipl; })
 
+#define cli()                  swpipl(7)
+#define sti()                  swpipl(0)
+#define save_flags(flags)      do { flags = swpipl(7); } while (0)
+#define restore_flags(flags)   swpipl(flags)
+
+extern inline unsigned long xchg_u32(int * m, unsigned long val)
+{
+       unsigned long dummy, dummy2;
+
+       __asm__ __volatile__(
+               "\n1:\t"
+               "ldl_l %0,%1\n\t"
+               "bis %2,%2,%3\n\t"
+               "stl_c %3,%1\n\t"
+               "beq %3,1b\n"
+               : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2)
+               : "1" (*m), "2" (val));
+       return val;
+}
+
+extern inline unsigned long xchg_u64(long * m, unsigned long val)
+{
+       unsigned long dummy, dummy2;
+
+       __asm__ __volatile__(
+               "\n1:\t"
+               "ldq_l %0,%1\n\t"
+               "bis %2,%2,%3\n\t"
+               "stq_c %3,%1\n\t"
+               "beq %3,1b\n"
+               : "=r" (val), "=m" (*m), "=r" (dummy), "=r" (dummy2)
+               : "1" (*m), "2" (val));
+       return val;
+}
+
+extern inline void * xchg_ptr(void *m, void *val)
+{
+       return (void *) xchg_u64((long *) m, (unsigned long) val);
+}
+
 #endif
index 602747914ea0877649244fe23ad29295c2093da6..6a4098ab1aee43d9baae770da42dd4353305a17c 100644 (file)
@@ -21,13 +21,13 @@ typedef long ptrdiff_t;
  * header files exported to user space
  */
 
-typedef signed char __s8;
+typedef __signed__ char __s8;
 typedef unsigned char __u8;
 
-typedef signed short __s16;
+typedef __signed__ short __s16;
 typedef unsigned short __u16;
 
-typedef signed int __s32;
+typedef __signed__ int __s32;
 typedef unsigned int __u32;
 
 /*
@@ -35,14 +35,14 @@ typedef unsigned int __u32;
  */
 #if ((~0UL) == 0xffffffff)
 
-#ifndef __STRICT_ANSI__
-typedef signed long long __s64;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
 typedef unsigned long long __u64;
 #endif
 
 #else
 
-typedef signed long __s64;
+typedef __signed__ long __s64;
 typedef unsigned long __u64;
 
 #endif
diff --git a/include/asm-generic/string.h b/include/asm-generic/string.h
deleted file mode 100644 (file)
index 03fd632..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * include/asm-generic/string.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_GENERIC_STRING_H_
-#define _ASM_GENERIC_STRING_H_
-
-/*
- * Portable string functions. These are not complete:
- * memcpy() and memmove() are still missing.
- */ 
-
-#ifdef __USE_PORTABLE_strcpy
-extern inline char * strcpy(char * dest,const char *src)
-{
-  char *xdest = dest;
-                       
-  while(*dest++ = *src++);
-
-  return xdest;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strncpy
-extern inline char * strncpy(char * dest,const char *src,size_t count)
-{
-  char *xdest = dest;
-             
-  while((*dest++ = *src++) && --count);
-
-  return dest;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strcat
-extern inline char * strcat(char * dest, const char * src)
-{
-       char *tmp = dest;
-
-       while (*dest)
-               dest++;
-       while ((*dest++ = *src++))
-               ;
-
-       return tmp;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strncat
-extern inline char * strncat(char *dest, const char *src, size_t count)
-{
-       char *tmp = dest;
-
-       if (count) {
-               while (*dest)
-                       dest++;
-               while ((*dest++ = *src++)) {
-                       if (--count == 0)
-                               break;
-               }
-       }
-
-       return tmp;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strcmp
-extern int strcmp(const char * cs,const char * ct)
-{
-  register char __res;
-
-  while(1) {
-    if(__res = *cs - *ct++ && *cs++)
-      break;
-    }
-
-  return __res;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strncmp
-extern inline int strncmp(const char * cs,const char * ct,size_t count)
-{
-  register char __res;
-
-  while(count) {
-    if(__res = *cs - *ct++ || !*cs++)
-      break;
-    count--;
-    }
-
-  return __res;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strchr
-extern inline char * strchr(const char * s,char c)
-{
-  const char ch = c;
-  
-  for(; *s != ch; ++s)
-    if (*s == '\0')
-      return( NULL );
-  return( (char *) s);
-}
-#endif
-
-#ifdef __USE_PORTABLE_strlen
-extern inline size_t strlen(const char * s)
-{
-  const char *sc;
-  for (sc = s; *sc != '\0'; ++sc) ;
-  return(sc - s);
-}
-#endif
-
-#ifdef __USE_PORTABLE_strspn
-extern inline size_t strspn(const char *s, const char *accept)
-{
-  const char *p;
-  const char *a;
-  size_t count = 0;
-
-  for (p = s; *p != '\0'; ++p)
-    {
-      for (a = accept; *a != '\0'; ++a)
-        if (*p == *a)
-          break;
-      if (*a == '\0')
-        return count;
-      else
-        ++count;
-    }
-
-  return count;
-}
-#endif
-
-#ifdef __USE_PORTABLE_strpbrk
-extern inline char * strpbrk(const char * cs,const char * ct)
-{
-  const char *sc1,*sc2;
-  
-  for( sc1 = cs; *sc1 != '\0'; ++sc1)
-    for( sc2 = ct; *sc2 != '\0'; ++sc2)
-      if (*sc1 == *sc2)
-       return((char *) sc1);
-  return( NULL );
-}
-#endif
-
-#ifdef __USE_PORTABLE_strtok
-extern inline char * strtok(char * s,const char * ct)
-{
-  char *sbegin, *send;
-  static char *ssave = NULL;
-  
-  sbegin  = s ? s : ssave;
-  if (!sbegin) {
-         return NULL;
-  }
-  sbegin += strspn(sbegin,ct);
-  if (*sbegin == '\0') {
-    ssave = NULL;
-    return( NULL );
-  }
-  send = strpbrk( sbegin, ct);
-  if (send && *send != '\0')
-    *send++ = '\0';
-  ssave = send;
-  return (sbegin);
-}
-#endif
-
-#ifdef __USE_PORTABLE_memset
-extern inline void * memset(void * s,char c,size_t count)
-{
-  void *xs = s;
-
-  while(n--)
-    *s++ = c;
-
-  return xs;
-}
-#endif
-
-#ifdef __USE_PORTABLE_memcpy
-#error "Portable memcpy() not implemented yet"
-#endif
-
-#ifdef __USE_PORTABLE_memmove
-#error "Portable memmove() not implemented yet"
-#endif
-
-#ifdef __USE_PORTABLE_memcmp
-extern inline int memcmp(const void * cs,const void * ct,size_t count)
-{
-  const unsigned char *su1, *su2;
-
-  for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
-    if (*su1 != *su2)
-      return((*su1 < *su2) ? -1 : +1);
-  return(0);
-}
-#endif
-
-#endif /* _ASM_GENERIC_STRING_H_ */
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
new file mode 100644 (file)
index 0000000..f038269
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  include/asm-i386/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *     void check_bugs(void);
+ */
+
+#define CONFIG_BUGi386
+
+static void no_halt(char *s, int *ints)
+{
+       hlt_works_ok = 0;
+}
+
+static void no_387(char *s, int *ints)
+{
+       hard_math = 0;
+       __asm__("movl %%cr0,%%eax\n\t"
+               "orl $0xE,%%eax\n\t"
+               "movl %%eax,%%cr0\n\t" : : : "ax");
+}
+
+static char fpu_error = 0;
+
+static void copro_timeout(void)
+{
+       fpu_error = 1;
+       timer_table[COPRO_TIMER].expires = jiffies+100;
+       timer_active |= 1<<COPRO_TIMER;
+       printk("387 failed: trying to reset\n");
+       send_sig(SIGFPE, last_task_used_math, 1);
+       outb_p(0,0xf1);
+       outb_p(0,0xf0);
+}
+
+static void check_fpu(void)
+{
+       static double x = 4195835.0;
+       static double y = 3145727.0;
+       unsigned short control_word;
+
+       if (!hard_math) {
+#ifndef CONFIG_MATH_EMULATION
+               printk("No coprocessor found and no math emulation present.\n");
+               printk("Giving up.\n");
+               for (;;) ;
+#endif
+               return;
+       }
+       /*
+        * check if exception 16 works correctly.. This is truly evil
+        * code: it disables the high 8 interrupts to make sure that
+        * the irq13 doesn't happen. But as this will lead to a lockup
+        * if no exception16 arrives, it depends on the fact that the
+        * high 8 interrupts will be re-enabled by the next timer tick.
+        * So the irq13 will happen eventually, but the exception 16
+        * should get there first..
+        */
+       printk("Checking 386/387 coupling... ");
+       timer_table[COPRO_TIMER].expires = jiffies+50;
+       timer_table[COPRO_TIMER].fn = copro_timeout;
+       timer_active |= 1<<COPRO_TIMER;
+       __asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
+       control_word &= 0xffc0;
+       __asm__("fldcw %0 ; fwait": :"m" (*&control_word));
+       outb_p(inb_p(0x21) | (1 << 2), 0x21);
+       __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
+       timer_active &= ~(1<<COPRO_TIMER);
+       if (fpu_error)
+               return;
+       if (!ignore_irq13) {
+               printk("Ok, fpu using old IRQ13 error reporting\n");
+               return;
+       }
+       __asm__("fninit\n\t"
+               "fldl %1\n\t"
+               "fdivl %2\n\t"
+               "fmull %2\n\t"
+               "fldl %1\n\t"
+               "fsubp %%st,%%st(1)\n\t"
+               "fistpl %0\n\t"
+               "fwait\n\t"
+               "fninit"
+               : "=m" (*&fdiv_bug)
+               : "m" (*&x), "m" (*&y));
+       if (!fdiv_bug) {
+               printk("Ok, fpu using exception 16 error reporting.\n");
+               return;
+
+       }
+       printk("Ok, FDIV bug i%c86 system\n", '0'+x86);
+}
+
+static void check_hlt(void)
+{
+       printk("Checking 'hlt' instruction... ");
+       if (!hlt_works_ok) {
+               printk("disabled\n");
+               return;
+       }
+       __asm__ __volatile__("hlt ; hlt ; hlt ; hlt");
+       printk("Ok.\n");
+}
+
+static void check_bugs(void)
+{
+       check_fpu();
+       check_hlt();
+       system_utsname.machine[1] = '0' + x86;
+}
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
new file mode 100644 (file)
index 0000000..fd3ae78
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * include/asm-i386/processor.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+#ifndef __ASM_I386_PROCESSOR_H
+#define __ASM_I386_PROCESSOR_H
+
+/*
+ * System setup and hardware bug flags..
+ */
+extern char hard_math;
+extern char x86;               /* lower 4 bits */
+extern char x86_vendor_id[13];
+extern char x86_model;         /* lower 4 bits */
+extern char x86_mask;          /* lower 4 bits */
+extern int  x86_capability;    /* field of flags */
+extern int  fdiv_bug;          
+extern char ignore_irq13;
+extern char wp_works_ok;               /* doesn't work on a 386 */
+extern char hlt_works_ok;      /* problems on some 486Dx4's and old 386's */
+
+#define start_bh_atomic() \
+__asm__ __volatile__("incl _intr_count")
+
+#define end_bh_atomic() \
+__asm__ __volatile__("decl _intr_count")
+
+/*
+ * Bus types (default is ISA, but people can check others with these..)
+ * MCA_bus hardcoded to 0 for now.
+ */
+extern int EISA_bus;
+#define MCA_bus 0
+
+/*
+ * User space process size: 3GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE      0xc0000000
+
+/*
+ * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
+ */
+#define IO_BITMAP_SIZE 32
+
+struct i387_hard_struct {
+       long    cwd;
+       long    swd;
+       long    twd;
+       long    fip;
+       long    fcs;
+       long    foo;
+       long    fos;
+       long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
+};
+
+struct i387_soft_struct {
+       long    cwd;
+       long    swd;
+       long    twd;
+       long    fip;
+       long    fcs;
+       long    foo;
+       long    fos;
+       long    top;
+       struct fpu_reg  regs[8];        /* 8*16 bytes for each FP-reg = 128 bytes */
+       unsigned char   lookahead;
+       struct info     *info;
+       unsigned long   entry_eip;
+};
+
+union i387_union {
+       struct i387_hard_struct hard;
+       struct i387_soft_struct soft;
+};
+
+struct thread_struct {
+       unsigned short  back_link,__blh;
+       unsigned long   esp0;
+       unsigned short  ss0,__ss0h;
+       unsigned long   esp1;
+       unsigned short  ss1,__ss1h;
+       unsigned long   esp2;
+       unsigned short  ss2,__ss2h;
+       unsigned long   cr3;
+       unsigned long   eip;
+       unsigned long   eflags;
+       unsigned long   eax,ecx,edx,ebx;
+       unsigned long   esp;
+       unsigned long   ebp;
+       unsigned long   esi;
+       unsigned long   edi;
+       unsigned short  es, __esh;
+       unsigned short  cs, __csh;
+       unsigned short  ss, __ssh;
+       unsigned short  ds, __dsh;
+       unsigned short  fs, __fsh;
+       unsigned short  gs, __gsh;
+       unsigned short  ldt, __ldth;
+       unsigned short  trace, bitmap;
+       unsigned long   io_bitmap[IO_BITMAP_SIZE+1];
+       unsigned long   tr;
+       unsigned long   cr2, trap_no, error_code;
+/* floating point info */
+       union i387_union i387;
+/* virtual 86 mode info */
+       struct vm86_struct * vm86_info;
+       unsigned long screen_bitmap;
+       unsigned long v86flags, v86mask, v86mode;
+};
+
+#define INIT_TSS  { \
+       0,0, \
+       sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
+       KERNEL_DS, 0, \
+       0,0,0,0,0,0, \
+       (long) &swapper_pg_dir, \
+       0,0,0,0,0,0,0,0,0,0, \
+       USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
+       _LDT(0),0, \
+       0, 0x8000, \
+       {~0, }, /* ioperm */ \
+       _TSS(0), 0, 0,0, \
+       { { 0, }, },  /* 387 state */ \
+       NULL, 0, 0, 0, 0 /* vm86_info */ \
+}
+
+#endif /* __ASM_I386_PROCESSOR_H */
index ce5bd75e566790ccce2c4b291fda40e66e1ac0df..2c56926c63a9f62ead20d991237e96ce72664599 100644 (file)
@@ -18,6 +18,125 @@ __asm__ __volatile__ ("movl %%esp,%%eax\n\t" \
        "mov %%ax,%%gs" \
        : /* no outputs */ :"i" (USER_DS), "i" (USER_CS):"ax")
 
+/*
+ * Entry into gdt where to find first TSS. GDT layout:
+ *   0 - nul
+ *   1 - kernel code segment
+ *   2 - kernel data segment
+ *   3 - user code segment
+ *   4 - user data segment
+ * ...
+ *   8 - TSS #0
+ *   9 - LDT #0
+ *  10 - TSS #1
+ *  11 - LDT #1
+ */
+#define FIRST_TSS_ENTRY 8
+#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
+#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
+#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
+#define load_TR(n) __asm__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
+#define load_ldt(n) __asm__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
+#define store_TR(n) \
+__asm__("str %%ax\n\t" \
+       "subl %2,%%eax\n\t" \
+       "shrl $4,%%eax" \
+       :"=a" (n) \
+       :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
+
+/* This special macro can be used to load a debugging register */
+
+#define loaddebug(register) \
+               __asm__("movl %0,%%edx\n\t" \
+                       "movl %%edx,%%db" #register "\n\t" \
+                       : /* no output */ \
+                       :"m" (current->debugreg[register]) \
+                       :"dx");
+
+
+/*
+ *     switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ * This also clears the TS-flag if the task we switched to has used
+ * the math co-processor latest.
+ *
+ * It also reloads the debug regs if necessary..
+ */
+#define switch_to(tsk) do { \
+__asm__("cli\n\t" \
+       "xchgl %%ecx,_current\n\t" \
+       "ljmp %0\n\t" \
+       "sti\n\t" \
+       "cmpl %%ecx,_last_task_used_math\n\t" \
+       "jne 1f\n\t" \
+       "clts\n" \
+       "1:" \
+       : /* no output */ \
+       :"m" (*(((char *)&tsk->tss.tr)-4)), \
+        "c" (tsk) \
+       :"cx"); \
+       /* Now maybe reload the debug registers */ \
+       if(current->debugreg[7]){ \
+               loaddebug(0); \
+               loaddebug(1); \
+               loaddebug(2); \
+               loaddebug(3); \
+               loaddebug(6); \
+       } \
+} while (0)
+
+#define _set_base(addr,base) \
+__asm__("movw %%dx,%0\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %%dl,%1\n\t" \
+       "movb %%dh,%2" \
+       : /* no output */ \
+       :"m" (*((addr)+2)), \
+        "m" (*((addr)+4)), \
+        "m" (*((addr)+7)), \
+        "d" (base) \
+       :"dx")
+
+#define _set_limit(addr,limit) \
+__asm__("movw %%dx,%0\n\t" \
+       "rorl $16,%%edx\n\t" \
+       "movb %1,%%dh\n\t" \
+       "andb $0xf0,%%dh\n\t" \
+       "orb %%dh,%%dl\n\t" \
+       "movb %%dl,%1" \
+       : /* no output */ \
+       :"m" (*(addr)), \
+        "m" (*((addr)+6)), \
+        "d" (limit) \
+       :"dx")
+
+#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
+#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
+
+static inline unsigned long _get_base(char * addr)
+{
+       unsigned long __base;
+       __asm__("movb %3,%%dh\n\t"
+               "movb %2,%%dl\n\t"
+               "shll $16,%%edx\n\t"
+               "movw %1,%%dx"
+               :"=&d" (__base)
+               :"m" (*((addr)+2)),
+                "m" (*((addr)+4)),
+                "m" (*((addr)+7)));
+       return __base;
+}
+
+#define get_base(ldt) _get_base( ((char *)&(ldt)) )
+
+static inline unsigned long get_limit(unsigned long segment)
+{
+       unsigned long __limit;
+       __asm__("lsll %1,%0"
+               :"=r" (__limit):"r" (segment));
+       return __limit+1;
+}
+
 #define nop() __asm__ __volatile__ ("nop")
 
 /*
@@ -34,12 +153,32 @@ __asm__ __volatile__ ( \
        :"ax")
 
 
+extern inline unsigned long xchg_u8(char * m, unsigned long val)
+{
+       __asm__("xchgb %b0,%1":"=q" (val),"=m" (*m):"0" (val):"memory");
+       return val;
+}
+
+extern inline unsigned long xchg_u16(short * m, unsigned long val)
+{
+       __asm__("xchgw %w0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
+       return val;
+}
+
+extern inline unsigned long xchg_u32(long * m, unsigned long val)
+{
+       __asm__("xchgl %0,%1":"=r" (val),"=m" (*m):"0" (val):"memory");
+       return val;
+}
+
 extern inline int tas(char * m)
 {
-       char res;
+       return xchg_u8(m,1);
+}
 
-       __asm__("xchgb %0,%1":"=q" (res),"=m" (*m):"0" (0x1));
-       return res;
+extern inline void * xchg_ptr(void * m, void * val)
+{
+       return (void *) xchg_u32(m, (unsigned long) val);
 }
 
 #define sti() __asm__ __volatile__ ("sti": : :"memory")
@@ -104,5 +243,10 @@ __asm__ __volatile__ ("movw $" #limit ",%1\n\t" \
 #define set_ldt_desc(n,addr,size) \
        _set_tssldt_desc(((char *) (n)),((int)(addr)),((size << 3) - 1),"0x82")
 
+/*
+ * This is the ldt that every process will get unless we need
+ * something other than this.
+ */
+extern struct desc_struct default_ldt;
 
 #endif
index 1f26e39f5d02a43368d8bb28029be57f37a63833..ba25ec4a06afcdfe61b5592a775fbd0e9c98b296 100644 (file)
@@ -30,7 +30,7 @@ typedef unsigned short __u16;
 typedef __signed__ long __s32;
 typedef unsigned long __u32;
 
-#ifndef __STRICT_ANSI__
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 typedef __signed__ long long __s64;
 typedef unsigned long long __u64;
 #endif
diff --git a/include/asm-sparc/bugs.h b/include/asm-sparc/bugs.h
new file mode 100644 (file)
index 0000000..c334954
--- /dev/null
@@ -0,0 +1,46 @@
+/*  include/asm-sparc/bugs.h:  Sparc probes for various bugs.
+ *
+ *  Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *     void check_bugs(void);
+ */
+
+#define CONFIG_BUGSPARC
+
+#include <asm/openprom.h>
+
+extern struct promvec *romvec;
+extern int tbase_needs_unmapping;   /* We do the bug workaround in pagetables.c */
+
+static void check_mmu()
+{
+  register struct promvec *romvec;
+  register int root_node;
+  register unsigned int present;
+
+  root_node = (*(romvec->pv_nodeops->no_nextnode))(0);
+  tbase_needs_unmapping=0;
+
+  present = 0;
+  (*(romvec->pv_nodeops->no_getprop))(root_node, "buserr-type", 
+                                     (char *) &present);
+  if(present == 1)
+    {
+      tbase_needs_unmapping=1;
+      printk("MMU bug found: not allowing trapbase to be cached\n");
+    }
+
+  return;
+}
+
+
+static void 
+check_bugs(void)
+{
+  check_mmu();
+}
index c90c3b366b6daecb30f731268ef5e05db97c5162..a810167112ce7e54830445d2b6d22dd9e7b62626 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef _SPARC_OPENPROM_H
+#define _SPARC_OPENPROM_H
+
 /* openprom.h:  Prom structures and defines for access to the OPENBOOT
                 prom routines and data areas.
 
@@ -16,7 +19,7 @@
 #define        LINUX_OPPROM_MAGIC      0x10010407
 
 /* The device functions structure for the v0 prom. Nice and neat, open,
-   close, read & write divied up between net + block + char devices. We
+   close, read & write divvied up between net + block + char devices. We
    also have a seek routine only usable for block devices. The divide
    and conquer strategy of this struct becomes unnecessary for v2.
 
@@ -51,7 +54,7 @@ struct linux_dev_v0_funcs {
    the time can be a pain in the rear after a while. Why v2 has memory
    allocations in here are beyond me. Perhaps they figure that if you
    are going to use only the prom's device drivers then your memory
-   management is either non-existant or pretty sad. :-)
+   management is either non-existent or pretty sad. :-)
 */
 
 struct linux_dev_v2_funcs {
@@ -64,7 +67,7 @@ struct linux_dev_v2_funcs {
        caddr_t (*v2_dumb_mem_alloc)(caddr_t va, unsigned sz);
        void    (*v2_dumb_mem_free)(caddr_t va, unsigned sz);
 
-       /* "dumb" mmap() munmap(), copy on write? whats that? */
+       /* "dumb" mmap() munmap(), copy on write? what's that? */
        caddr_t (*v2_dumb_mmap)(caddr_t virta, int asi, unsigned prot, unsigned sz);
        void    (*v2_dumb_munmap)(caddr_t virta, unsigned size);
 
@@ -103,7 +106,7 @@ struct linux_mem_v0 {
        struct  linux_mlist_v0 **v0_available;  /* what phys. is left over */
 };
 
-/* Arguements sent to the kernel from the boot prompt. */
+/* Arguments sent to the kernel from the boot prompt. */
 
 struct linux_arguments_v0 {
        char    *argv[8];               /* argv format for boot string */
@@ -260,3 +263,5 @@ struct nodeops {
        int     (*no_setprop)(int node, caddr_t name, caddr_t val, int len);
        caddr_t (*no_nextprop)(int node, caddr_t name);
 };
+
+#endif /* !(_SPARC_OPENPROM_H) */
index 8b7c794b86fbf9f671a95042ad813c897ba8d8d5..51868e24ac1013b7fb485c21ea68d1a1c3eed97f 100644 (file)
  *       however this won't be for a while.
  */
 
-typedef signed char __s8;
+typedef __signed__ char __s8;
 typedef unsigned char __u8;
 
-typedef signed short __s16;
+typedef __signed__ short __s16;
 typedef unsigned short __u16;
 
-typedef signed int __s32;
+typedef __signed__ int __s32;
 typedef unsigned int __u32;
 
 /* Only 32-bit sparcs for now so.... */
 
-typedef signed long long __s64;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
 typedef unsigned long long __s64;
+#endif
 
 #ifdef __KERNEL__
 
index 84b48d93c82da9923e76c3461d18c9ac005cbdfd..1e0b17c8168a18c0d3890bed12e5bec7bd860639 100644 (file)
@@ -44,4 +44,6 @@ extern int * blk_size[MAX_BLKDEV];
 
 extern int * blksize_size[MAX_BLKDEV];
 
+extern int * hardsect_size[MAX_BLKDEV];
+
 #endif
index a22241e912298f8d14a3c51f64177c72b1fd18c9..b830c00a2d7a49bba479216630912ff2f52d9add 100644 (file)
@@ -9,12 +9,13 @@
 #ifndef UTS_SYSNAME
 #define UTS_SYSNAME "Linux"
 #endif
-#ifndef UTS_NODENAME
-#define UTS_NODENAME "(none)"  /* set by sethostname() */
-#endif
 
 #ifndef UTS_MACHINE
-#define UTS_MACHINE "i386"     /* hardware type */
+#define UTS_MACHINE "unknown"
+#endif
+
+#ifndef UTS_NODENAME
+#define UTS_NODENAME "(none)"  /* set by sethostname() */
 #endif
 
 #ifndef UTS_DOMAINNAME
index 96910e9713064d05b417f99d1ec72390e86d54d4..16cbe03b842ec25068b1682f0f2eb187a322511c 100644 (file)
@@ -124,6 +124,11 @@ extern unsigned short int  ntohs(unsigned short int);
 extern unsigned long int       htonl(unsigned long int);
 extern unsigned short int      htons(unsigned short int);
 
+extern unsigned long int       __ntohl(unsigned long int);
+extern unsigned short int      __ntohs(unsigned short int);
+extern unsigned long int       __constant_ntohl(unsigned long int);
+extern unsigned short int      __constant_ntohs(unsigned short int);
+
 extern __inline__ unsigned long int
 __ntohl(unsigned long int x)
 {
index 4fd8585c45116c9b6c73b04a9a9773d1f4bbe9d7..8bc7b4fcf83a52a01c833c9bb1917a72d5b0b541 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _LINUX_INTERRUPT_H
 #define _LINUX_INTERRUPT_H
 
+#include <asm/bitops.h>
+
 struct bh_struct {
        void (*routine)(void *);
        void *data;
@@ -27,17 +29,17 @@ enum {
 
 extern inline void mark_bh(int nr)
 {
-       __asm__ __volatile__("orl %1,%0":"=m" (bh_active):"ir" (1<<nr));
+       set_bit(nr, &bh_active);
 }
 
 extern inline void disable_bh(int nr)
 {
-       __asm__ __volatile__("andl %1,%0":"=m" (bh_mask):"ir" (~(1<<nr)));
+       clear_bit(nr, &bh_mask);
 }
 
 extern inline void enable_bh(int nr)
 {
-       __asm__ __volatile__("orl %1,%0":"=m" (bh_mask):"ir" (1<<nr));
+       set_bit(nr, &bh_mask);
 }
 
 #endif
index dd6699a0d85310cc0987c7709a4be9c6eca939b5..b914a29ee4cbbb5ff512feba4555ba2b8a396af6 100644 (file)
@@ -110,12 +110,6 @@ struct fat_cache {
 
 #ifdef __KERNEL__
 
-static inline struct buffer_head *msdos_sread(int dev,int sector)
-{
-       return bread(dev,sector,SECTOR_SIZE);
-}
-
-
 /* misc.c */
 
 extern void fs_panic(struct super_block *s,char *msg);
@@ -180,6 +174,7 @@ extern int msdos_readdir (struct inode *inode, struct file *filp,
 /* file.c */
 
 extern struct inode_operations msdos_file_inode_operations;
+extern struct inode_operations msdos_file_inode_operations_1024;
 extern int msdos_file_read(struct inode *, struct file *, char *, int);
 extern int msdos_file_write(struct inode *, struct file *, char *, int);
 extern struct inode_operations msdos_file_inode_operations_no_bmap;
index 6d22ce0c9f5bd35c1ef032128e5b77eb5972bc0d..1e4007bc46c4dc7fef6e2d082dd89f2472e5a402 100644 (file)
@@ -27,7 +27,7 @@ enum root_directory_inos {
        PROC_KSYMS,
        PROC_DMA,       
        PROC_IOPORTS,
-       PROC_PROFILE /* wether enabled or not */
+       PROC_PROFILE /* whether enabled or not */
 };
 
 enum pid_directory_inos {
index 93db09bc9f10adefe574ff1c041535e0b1c670df..d3f1c05633fc602d91275c7ac059379e2405a87b 100644 (file)
@@ -57,8 +57,8 @@ struct        rusage {
 #define RLIM_INFINITY  ((long)(~0UL>>1))
 
 struct rlimit {
-       int     rlim_cur;
-       int     rlim_max;
+       long    rlim_cur;
+       long    rlim_max;
 };
 
 #define        PRIO_MIN        (-99)
index a6fc83cfcdcaca13e484b11f80669d91092c33f0..0030c80c0beef5ae50d0b23e8ccf24b137be610a 100644 (file)
 
 #define HZ 100
 
-/*
- * System setup and hardware bug flags..
- */
-extern char hard_math;
-extern char x86;               /* lower 4 bits */
-extern char x86_vendor_id[13];
-extern char x86_model;         /* lower 4 bits */
-extern char x86_mask;          /* lower 4 bits */
-extern int  x86_capability;    /* field of flags */
-extern int  fdiv_bug;          
-extern char ignore_irq13;
-extern char wp_works_ok;               /* doesn't work on a 386 */
-extern char hlt_works_ok;      /* problems on some 486Dx4's and old 386's */
-
 extern unsigned long intr_count;
 extern unsigned long event;
 
-#define start_bh_atomic() \
-__asm__ __volatile__("incl _intr_count")
-
-#define end_bh_atomic() \
-__asm__ __volatile__("decl _intr_count")
-
-/*
- * Bus types (default is ISA, but people can check others with these..)
- * MCA_bus hardcoded to 0 for now.
- */
-extern int EISA_bus;
-#define MCA_bus 0
-
 #include <linux/binfmts.h>
 #include <linux/personality.h>
 #include <linux/tasks.h>
 #include <asm/system.h>
 
-/*
- * User space process size: 3GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#define TASK_SIZE      0xc0000000
-
-/*
- * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
- */
-#define IO_BITMAP_SIZE 32
-
 /*
  * These are the constant used to fake the fixed-point load-average
  * counting. Some notes:
@@ -98,6 +60,8 @@ extern unsigned long avenrun[];               /* Load averages */
 #include <linux/math_emu.h>
 #include <linux/ptrace.h>
 
+#include <asm/processor.h>
+
 #define TASK_RUNNING           0
 #define TASK_INTERRUPTIBLE     1
 #define TASK_UNINTERRUPTIBLE   2
@@ -119,82 +83,6 @@ asmlinkage void schedule(void);
 
 #endif /* __KERNEL__ */
 
-struct i387_hard_struct {
-       long    cwd;
-       long    swd;
-       long    twd;
-       long    fip;
-       long    fcs;
-       long    foo;
-       long    fos;
-       long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
-};
-
-struct i387_soft_struct {
-       long    cwd;
-       long    swd;
-       long    twd;
-       long    fip;
-       long    fcs;
-       long    foo;
-       long    fos;
-       long    top;
-       struct fpu_reg  regs[8];        /* 8*16 bytes for each FP-reg = 128 bytes */
-       unsigned char   lookahead;
-       struct info     *info;
-       unsigned long   entry_eip;
-};
-
-union i387_union {
-       struct i387_hard_struct hard;
-       struct i387_soft_struct soft;
-};
-
-struct tss_struct {
-       unsigned short  back_link,__blh;
-       unsigned long   esp0;
-       unsigned short  ss0,__ss0h;
-       unsigned long   esp1;
-       unsigned short  ss1,__ss1h;
-       unsigned long   esp2;
-       unsigned short  ss2,__ss2h;
-       unsigned long   cr3;
-       unsigned long   eip;
-       unsigned long   eflags;
-       unsigned long   eax,ecx,edx,ebx;
-       unsigned long   esp;
-       unsigned long   ebp;
-       unsigned long   esi;
-       unsigned long   edi;
-       unsigned short  es, __esh;
-       unsigned short  cs, __csh;
-       unsigned short  ss, __ssh;
-       unsigned short  ds, __dsh;
-       unsigned short  fs, __fsh;
-       unsigned short  gs, __gsh;
-       unsigned short  ldt, __ldth;
-       unsigned short  trace, bitmap;
-       unsigned long   io_bitmap[IO_BITMAP_SIZE+1];
-       unsigned long   tr;
-       unsigned long   cr2, trap_no, error_code;
-       union i387_union i387;
-};
-
-#define INIT_TSS  { \
-       0,0, \
-       sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
-       KERNEL_DS, 0, \
-       0,0,0,0,0,0, \
-       (long) &swapper_pg_dir, \
-       0,0,0,0,0,0,0,0,0,0, \
-       USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
-       _LDT(0),0, \
-       0, 0x8000, \
-       {~0, }, /* ioperm */ \
-       _TSS(0), 0, 0,0, \
-       { { 0, }, }  /* 387 state */ \
-}
-
 struct files_struct {
        int count;
        fd_set close_on_exec;
@@ -286,10 +174,6 @@ struct task_struct {
        struct rlimit rlim[RLIM_NLIMITS]; 
        unsigned short used_math;
        char comm[16];
-/* virtual 86 mode stuff */
-       struct vm86_struct * vm86_info;
-       unsigned long screen_bitmap;
-       unsigned long v86flags, v86mask, v86mode;
 /* file system info */
        int link_count;
        struct tty_struct *tty; /* NULL if no tty */
@@ -298,7 +182,7 @@ struct task_struct {
 /* ldt for this task - used by Wine.  If NULL, default_ldt is used */
        struct desc_struct *ldt;
 /* tss for this task */
-       struct tss_struct tss;
+       struct thread_struct tss;
 /* filesystem information */
        struct fs_struct fs[1];
 /* open file information */
@@ -345,7 +229,6 @@ struct task_struct {
                  {       0, LONG_MAX}, {LONG_MAX, LONG_MAX}}, \
 /* math */     0, \
 /* comm */     "swapper", \
-/* vm86_info */        NULL, 0, 0, 0, 0, \
 /* fs info */  0,NULL, \
 /* ipc */      NULL, \
 /* ldt */      NULL, \
@@ -381,79 +264,6 @@ extern int in_group_p(gid_t grp);
 extern int request_irq(unsigned int irq,void (*handler)(int), unsigned long flags, const char *device);
 extern void free_irq(unsigned int irq);
 
-/*
- * Entry into gdt where to find first TSS. GDT layout:
- *   0 - nul
- *   1 - kernel code segment
- *   2 - kernel data segment
- *   3 - user code segment
- *   4 - user data segment
- * ...
- *   8 - TSS #0
- *   9 - LDT #0
- *  10 - TSS #1
- *  11 - LDT #1
- */
-#define FIRST_TSS_ENTRY 8
-#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
-#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
-#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
-#define load_TR(n) __asm__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
-#define load_ldt(n) __asm__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
-#define store_TR(n) \
-__asm__("str %%ax\n\t" \
-       "subl %2,%%eax\n\t" \
-       "shrl $4,%%eax" \
-       :"=a" (n) \
-       :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
-/*
- *     switch_to(n) should switch tasks to task nr n, first
- * checking that n isn't the current task, in which case it does nothing.
- * This also clears the TS-flag if the task we switched to has used
- * tha math co-processor latest.
- */
-#define switch_to(tsk) \
-__asm__("cli\n\t" \
-       "xchgl %%ecx,_current\n\t" \
-       "ljmp %0\n\t" \
-       "sti\n\t" \
-       "cmpl %%ecx,_last_task_used_math\n\t" \
-       "jne 1f\n\t" \
-       "clts\n" \
-       "1:" \
-       : /* no output */ \
-       :"m" (*(((char *)&tsk->tss.tr)-4)), \
-        "c" (tsk) \
-       :"cx")
-
-#define _set_base(addr,base) \
-__asm__("movw %%dx,%0\n\t" \
-       "rorl $16,%%edx\n\t" \
-       "movb %%dl,%1\n\t" \
-       "movb %%dh,%2" \
-       : /* no output */ \
-       :"m" (*((addr)+2)), \
-        "m" (*((addr)+4)), \
-        "m" (*((addr)+7)), \
-        "d" (base) \
-       :"dx")
-
-#define _set_limit(addr,limit) \
-__asm__("movw %%dx,%0\n\t" \
-       "rorl $16,%%edx\n\t" \
-       "movb %1,%%dh\n\t" \
-       "andb $0xf0,%%dh\n\t" \
-       "orb %%dh,%%dl\n\t" \
-       "movb %%dl,%1" \
-       : /* no output */ \
-       :"m" (*(addr)), \
-        "m" (*((addr)+6)), \
-        "d" (limit) \
-       :"dx")
-
-#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
-#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
-
 /*
  * The wait-queues are circular lists, and you have to be *very* sure
  * to keep them correct. Use only these two functions to add/remove
@@ -556,30 +366,6 @@ extern inline void up(struct semaphore * sem)
        wake_up(&sem->wait);
 }      
 
-static inline unsigned long _get_base(char * addr)
-{
-       unsigned long __base;
-       __asm__("movb %3,%%dh\n\t"
-               "movb %2,%%dl\n\t"
-               "shll $16,%%edx\n\t"
-               "movw %1,%%dx"
-               :"=&d" (__base)
-               :"m" (*((addr)+2)),
-                "m" (*((addr)+4)),
-                "m" (*((addr)+7)));
-       return __base;
-}
-
-#define get_base(ldt) _get_base( ((char *)&(ldt)) )
-
-static inline unsigned long get_limit(unsigned long segment)
-{
-       unsigned long __limit;
-       __asm__("lsll %1,%0"
-               :"=r" (__limit):"r" (segment));
-       return __limit+1;
-}
-
 #define REMOVE_LINKS(p) do { unsigned long flags; \
        save_flags(flags) ; cli(); \
        (p)->next_task->prev_task = (p)->prev_task; \
@@ -609,21 +395,6 @@ static inline unsigned long get_limit(unsigned long segment)
 #define for_each_task(p) \
        for (p = &init_task ; (p = p->next_task) != &init_task ; )
 
-/*
- * This is the ldt that every process will get unless we need
- * something other than this.
- */
-extern struct desc_struct default_ldt;
-
-/* This special macro can be used to load a debugging register */
-
-#define loaddebug(register) \
-               __asm__("movl %0,%%edx\n\t" \
-                       "movl %%edx,%%db" #register "\n\t" \
-                       : /* no output */ \
-                       :"m" (current->debugreg[register]) \
-                       :"dx");
-
 #endif /* __KERNEL__ */
 
 #endif
index 13e8da56e2cfad8dad01efd18e7a19319bb29fb2..81c6a76a8650400ca91fa6ffcfb59f95cad2530d 100644 (file)
 extern "C" {
 #endif
 
+extern char * strcpy(char *,const char *);
+extern char * strncpy(char *,const char *,size_t);
+extern char * strcat(char *, const char *);
+extern char * strncat(char *, const char *, size_t);
+extern char * strchr(const char *,char);
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern size_t strlen(const char *);
+extern size_t strspn(const char *,const char *);
+extern int strcmp(const char *,const char *);
+extern int strncmp(const char *,const char *,size_t);
+
+extern void * memset(void *,char,size_t);
+extern void * memcpy(void *,const void *,size_t);
+extern void * memmove(void *,const void *,size_t);
+extern int memcmp(const void *,const void *,size_t);
+
 /*
  * Include machine specific inline routines
  */
 #include <asm/string.h>
 
-#ifdef __USE_PORTABLE_STRINGS_H_
-/*
- * include/generic/string.h imports all the string functions,
- * for which no appropriate assembler replacements have been provided.
- */
-#include <asm-generic/string.h>
-#endif
-
 #ifdef __cplusplus
 }
 #endif
index d264495e3a7801cb9fd747439cffea936b131b3c..593af79b3f29dd6e2d51ca829b8a87b6b1874311 100644 (file)
@@ -143,9 +143,7 @@ _INLINE_ void run_task_queue(task_queue *list)
        void (*f) (void *);
 
        while(1) {
-               p = &tq_last;
-               __asm__ __volatile__("xchgl %0,%2" : "=r" (p) :
-                                    "0" (p), "m" (*list) : "memory");
+               p = xchg_ptr(list,&tq_last);
                if(p == &tq_last)
                        break;
 
index f780f09b9c1e7f97057af950e50b2b310f89a324..d0dc03c117d1b9f390a8837f3e18bc08dae3fdba 100644 (file)
@@ -28,7 +28,7 @@ typedef unsigned short nlink_t;
 typedef int daddr_t;
 typedef long off_t;
 
-#ifndef __STRICT_ANSI__
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 #define _LOFF_T
 typedef long long loff_t;
 #endif
index 7b0c9830ed23b2795610179108de3d8940517e77..e571dd3f8b8f96993b1546bcfd2cda4db6494290 100644 (file)
 #include <linux/utsname.h>
 #include <linux/ioport.h>
 
+#include <asm/bugs.h>
+
 extern unsigned long * prof_buffer;
 extern unsigned long prof_len;
 extern char etext, end;
 extern char *linux_banner;
-asmlinkage void lcall7(void);
-struct desc_struct default_ldt;
 
 /*
  * we need this inline - forking from kernel space will result
@@ -159,8 +159,6 @@ unsigned char aux_device_present;
 int ramdisk_size;
 int root_mountflags = 0;
 
-static char fpu_error = 0;
-
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
 char *get_options(char *str, int *ints)
@@ -183,6 +181,10 @@ struct {
 } bootsetups[] = {
        { "reserve=", reserve_setup },
        { "ramdisk=", ramdisk_setup },
+#ifdef CONFIG_BUGi386
+       { "no-hlt", no_halt },
+       { "no387", no_387 },
+#endif
 #ifdef CONFIG_INET
        { "ether=", eth_setup },
 #endif
@@ -352,17 +354,6 @@ static void parse_options(char *line)
                        console_loglevel = 10;
                        continue;
                }
-               if (!strcmp(line,"no-hlt")) {
-                       hlt_works_ok = 0;
-                       continue;
-               }
-               if (!strcmp(line,"no387")) {
-                       hard_math = 0;
-                       __asm__("movl %%cr0,%%eax\n\t"
-                               "orl $0xE,%%eax\n\t"
-                               "movl %%eax,%%cr0\n\t" : : : "ax");
-                       continue;
-               }
                if (checksetup(line))
                        continue;
                /*
@@ -409,91 +400,7 @@ static void copy_options(char * to, char * from)
        *to = '\0';
 }
 
-static void copro_timeout(void)
-{
-       fpu_error = 1;
-       timer_table[COPRO_TIMER].expires = jiffies+100;
-       timer_active |= 1<<COPRO_TIMER;
-       printk("387 failed: trying to reset\n");
-       send_sig(SIGFPE, last_task_used_math, 1);
-       outb_p(0,0xf1);
-       outb_p(0,0xf0);
-}
-
-static void check_fpu(void)
-{
-       static double x = 4195835.0;
-       static double y = 3145727.0;
-       unsigned short control_word;
-
-       if (!hard_math) {
-#ifndef CONFIG_MATH_EMULATION
-               printk("No coprocessor found and no math emulation present.\n");
-               printk("Giving up.\n");
-               for (;;) ;
-#endif
-               return;
-       }
-       /*
-        * check if exception 16 works correctly.. This is truly evil
-        * code: it disables the high 8 interrupts to make sure that
-        * the irq13 doesn't happen. But as this will lead to a lockup
-        * if no exception16 arrives, it depends on the fact that the
-        * high 8 interrupts will be re-enabled by the next timer tick.
-        * So the irq13 will happen eventually, but the exception 16
-        * should get there first..
-        */
-       printk("Checking 386/387 coupling... ");
-       timer_table[COPRO_TIMER].expires = jiffies+50;
-       timer_table[COPRO_TIMER].fn = copro_timeout;
-       timer_active |= 1<<COPRO_TIMER;
-       __asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
-       control_word &= 0xffc0;
-       __asm__("fldcw %0 ; fwait": :"m" (*&control_word));
-       outb_p(inb_p(0x21) | (1 << 2), 0x21);
-       __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
-       timer_active &= ~(1<<COPRO_TIMER);
-       if (fpu_error)
-               return;
-       if (!ignore_irq13) {
-               printk("Ok, fpu using old IRQ13 error reporting\n");
-               return;
-       }
-       __asm__("fninit\n\t"
-               "fldl %1\n\t"
-               "fdivl %2\n\t"
-               "fmull %2\n\t"
-               "fldl %1\n\t"
-               "fsubp %%st,%%st(1)\n\t"
-               "fistpl %0\n\t"
-               "fwait\n\t"
-               "fninit"
-               : "=m" (*&fdiv_bug)
-               : "m" (*&x), "m" (*&y));
-       if (!fdiv_bug) {
-               printk("Ok, fpu using exception 16 error reporting.\n");
-               return;
-
-       }
-       printk("Ok, FDIV bug i%c86 system\n", '0'+x86);
-}
-
-static void check_hlt(void)
-{
-       printk("Checking 'hlt' instruction... ");
-       if (!hlt_works_ok) {
-               printk("disabled\n");
-               return;
-       }
-       __asm__ __volatile__("hlt ; hlt ; hlt ; hlt");
-       printk("Ok.\n");
-}
-
-static void check_bugs(void)
-{
-       check_fpu();
-       check_hlt();
-}
+extern void check_bugs(void);
 
 asmlinkage void start_kernel(void)
 {
@@ -501,7 +408,6 @@ asmlinkage void start_kernel(void)
  * Interrupts are still disabled. Do necessary setups, then
  * enable them
  */
-       set_call_gate(&default_ldt,lcall7);
        ROOT_DEV = ORIG_ROOT_DEV;
        drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
@@ -567,7 +473,6 @@ asmlinkage void start_kernel(void)
        sti();
        check_bugs();
 
-       system_utsname.machine[1] = '0' + x86;
        printk(linux_banner);
 
        move_to_user_mode();
index 9cc2b4609051e75c6ca4b5614c40a1319e6fdabc..2625dbce850a1109eb490f509ca4739874123997 100644 (file)
@@ -240,7 +240,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
                if (p->ldt != NULL)
                        memcpy(p->ldt, current->ldt, LDT_ENTRIES*LDT_ENTRY_SIZE);
        }
-       p->tss.bitmap = offsetof(struct tss_struct,io_bitmap);
+       p->tss.bitmap = offsetof(struct thread_struct,io_bitmap);
        for (i = 0; i < IO_BITMAP_SIZE+1 ; i++) /* IO bitmap is actually SIZE+1 */
                p->tss.io_bitmap[i] = ~0;
        if (last_task_used_math == current)
index c499cd229d5bf54e7e524d05cc6ac17490224fda..9e222d77404b7597e5016c7fca5084817d2dfa47 100644 (file)
@@ -144,6 +144,7 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
        X(block_fsync),
        X(wait_for_request),
        X(blksize_size),
+       X(hardsect_size),
        X(blk_size),
        X(blk_dev),
        X(is_read_only),
index 1f3c0f7b010a7b2a0f5891e512c4b99ec30385d2..c9285844f0c484b062c6870961daf74c4a5e56ac 100644 (file)
@@ -95,9 +95,9 @@ unsigned long prof_len = 0;
 extern void mem_use(void);
 
 extern int timer_interrupt(void);
-asmlinkage int system_call(void);
-
 static unsigned long init_kernel_stack[1024] = { STACK_MAGIC, };
+unsigned long init_user_stack[1024] = { STACK_MAGIC, };
 static struct vm_area_struct init_mmap = INIT_MMAP;
 struct task_struct init_task = INIT_TASK;
 
@@ -108,55 +108,8 @@ struct task_struct *last_task_used_math = NULL;
 
 struct task_struct * task[NR_TASKS] = {&init_task, };
 
-long user_stack [ PAGE_SIZE>>2 ] = { STACK_MAGIC, };
-
-struct {
-       long * a;
-       short b;
-       } stack_start = { & user_stack [PAGE_SIZE>>2] , KERNEL_DS };
-
 struct kernel_stat kstat = { 0 };
 
-/*
- *  'math_state_restore()' saves the current math information in the
- * old math state array, and gets the new ones from the current task
- *
- * Careful.. There are problems with IBM-designed IRQ13 behaviour.
- * Don't touch unless you *really* know how it works.
- */
-asmlinkage void math_state_restore(void)
-{
-       __asm__ __volatile__("clts");
-       if (last_task_used_math == current)
-               return;
-       timer_table[COPRO_TIMER].expires = jiffies+50;
-       timer_active |= 1<<COPRO_TIMER; 
-       if (last_task_used_math)
-               __asm__("fnsave %0":"=m" (last_task_used_math->tss.i387));
-       else
-               __asm__("fnclex");
-       last_task_used_math = current;
-       if (current->used_math) {
-               __asm__("frstor %0": :"m" (current->tss.i387));
-       } else {
-               __asm__("fninit");
-               current->used_math=1;
-       }
-       timer_active &= ~(1<<COPRO_TIMER);
-}
-
-#ifndef CONFIG_MATH_EMULATION
-
-asmlinkage void math_emulate(long arg)
-{
-  printk("math-emulation not enabled and no coprocessor found.\n");
-  printk("killing %s.\n",current->comm);
-  send_sig(SIGFPE,current,1);
-  schedule();
-}
-
-#endif /* CONFIG_MATH_EMULATION */
-
 unsigned long itimer_ticks = 0;
 unsigned long itimer_next = ~0;
 
@@ -252,14 +205,6 @@ confuse_gcc2:
                return;
        kstat.context_swtch++;
        switch_to(next);
-       /* Now maybe reload the debug registers */
-       if(current->debugreg[7]){
-               loaddebug(0);
-               loaddebug(1);
-               loaddebug(2);
-               loaddebug(3);
-               loaddebug(6);
-       };
 }
 
 asmlinkage int sys_pause(void)
@@ -801,10 +746,12 @@ static void show_task(int nr,struct task_struct * p)
                printk(stat_nam[p->state]);
        else
                printk(" ");
+#ifdef __i386__
        if (p == current)
                printk(" current  ");
        else
                printk(" %08lX ", ((unsigned long *)p->tss.esp)[3]);
+#endif
        for (free = 1; free < 1024 ; free++) {
                if (((unsigned long *)p->kernel_stack_page)[free])
                        break;
@@ -837,29 +784,11 @@ void show_state(void)
 
 void sched_init(void)
 {
-       int i;
-       struct desc_struct * p;
-
        bh_base[TIMER_BH].routine = timer_bh;
        bh_base[TQUEUE_BH].routine = tqueue_bh;
        bh_base[IMMEDIATE_BH].routine = immediate_bh;
        if (sizeof(struct sigaction) != 16)
                panic("Struct sigaction MUST be 16 bytes");
-       set_tss_desc(gdt+FIRST_TSS_ENTRY,&init_task.tss);
-       set_ldt_desc(gdt+FIRST_LDT_ENTRY,&default_ldt,1);
-       set_system_gate(0x80,&system_call);
-       p = gdt+2+FIRST_TSS_ENTRY;
-       for(i=1 ; i<NR_TASKS ; i++) {
-               task[i] = NULL;
-               p->a=p->b=0;
-               p++;
-               p->a=p->b=0;
-               p++;
-       }
-/* Clear NT, so that we won't have troubles with that later on */
-       __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
-       load_TR(0);
-       load_ldt(0);
        outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
        outb_p(LATCH & 0xff , 0x40);    /* LSB */
        outb(LATCH >> 8 , 0x40);        /* MSB */
index 150b702b3214ca24f337b366d2ccc10a26da9008..c19fa33fcba6a3e1834ae8343295824f70f16ea0 100644 (file)
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
+#include <linux/config.h>
+#include <linux/timer.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/io.h>
 
+asmlinkage int system_call(void);
+asmlinkage void lcall7(void);
+struct desc_struct default_ldt;
+
 static inline void console_verbose(void)
 {
        extern int console_loglevel;
@@ -218,10 +224,52 @@ asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
        math_error();
 }
 
+/*
+ *  'math_state_restore()' saves the current math information in the
+ * old math state array, and gets the new ones from the current task
+ *
+ * Careful.. There are problems with IBM-designed IRQ13 behaviour.
+ * Don't touch unless you *really* know how it works.
+ */
+asmlinkage void math_state_restore(void)
+{
+       __asm__ __volatile__("clts");
+       if (last_task_used_math == current)
+               return;
+       timer_table[COPRO_TIMER].expires = jiffies+50;
+       timer_active |= 1<<COPRO_TIMER; 
+       if (last_task_used_math)
+               __asm__("fnsave %0":"=m" (last_task_used_math->tss.i387));
+       else
+               __asm__("fnclex");
+       last_task_used_math = current;
+       if (current->used_math) {
+               __asm__("frstor %0": :"m" (current->tss.i387));
+       } else {
+               __asm__("fninit");
+               current->used_math=1;
+       }
+       timer_active &= ~(1<<COPRO_TIMER);
+}
+
+#ifndef CONFIG_MATH_EMULATION
+
+asmlinkage void math_emulate(long arg)
+{
+  printk("math-emulation not enabled and no coprocessor found.\n");
+  printk("killing %s.\n",current->comm);
+  send_sig(SIGFPE,current,1);
+  schedule();
+}
+
+#endif /* CONFIG_MATH_EMULATION */
+
 void trap_init(void)
 {
        int i;
+       struct desc_struct * p;
 
+       set_call_gate(&default_ldt,lcall7);
        set_trap_gate(0,&divide_error);
        set_trap_gate(1,&debug);
        set_trap_gate(2,&nmi);
@@ -242,4 +290,21 @@ void trap_init(void)
        set_trap_gate(17,&alignment_check);
        for (i=18;i<48;i++)
                set_trap_gate(i,&reserved);
+       set_system_gate(0x80,&system_call);
+/* set up GDT task & ldt entries */
+       p = gdt+FIRST_TSS_ENTRY;
+       set_tss_desc(p, &init_task.tss);
+       p++;
+       set_ldt_desc(p, &default_ldt, 1);
+       p++;
+       for(i=1 ; i<NR_TASKS ; i++) {
+               p->a=p->b=0;
+               p++;
+               p->a=p->b=0;
+               p++;
+       }
+/* Clear NT, so that we won't have troubles with that later on */
+       __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
+       load_TR(0);
+       load_ldt(0);
 }
index 144d93a024c700f68ed03f606520d550981a487e..f1c78ecf7614765dc194be1d93530ff82251b80d 100644 (file)
@@ -39,8 +39,8 @@
 /*
  * virtual flags (16 and 32-bit versions)
  */
-#define VFLAGS (*(unsigned short *)&(current->v86flags))
-#define VEFLAGS        (current->v86flags)
+#define VFLAGS (*(unsigned short *)&(current->tss.v86flags))
+#define VEFLAGS        (current->tss.v86flags)
 
 #define set_flags(X,new,mask) \
 ((X) = ((X) & ~(mask)) | ((new) & (mask)))
@@ -52,13 +52,13 @@ asmlinkage struct pt_regs * save_v86_state(struct vm86_regs * regs)
 {
        unsigned long tmp;
 
-       if (!current->vm86_info) {
+       if (!current->tss.vm86_info) {
                printk("no vm86_info: BAD\n");
                do_exit(SIGSEGV);
        }
-       set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->v86mask);
-       memcpy_tofs(&current->vm86_info->regs,regs,sizeof(*regs));
-       put_fs_long(current->screen_bitmap,&current->vm86_info->screen_bitmap);
+       set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->tss.v86mask);
+       memcpy_tofs(&current->tss.vm86_info->regs,regs,sizeof(*regs));
+       put_fs_long(current->tss.screen_bitmap,&current->tss.vm86_info->screen_bitmap);
        tmp = current->tss.esp0;
        current->tss.esp0 = current->saved_kernel_stack;
        current->saved_kernel_stack = 0;
@@ -117,16 +117,16 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
 
        switch (info.cpu_type) {
                case CPU_286:
-                       current->v86mask = 0;
+                       current->tss.v86mask = 0;
                        break;
                case CPU_386:
-                       current->v86mask = NT_MASK | IOPL_MASK;
+                       current->tss.v86mask = NT_MASK | IOPL_MASK;
                        break;
                case CPU_486:
-                       current->v86mask = AC_MASK | NT_MASK | IOPL_MASK;
+                       current->tss.v86mask = AC_MASK | NT_MASK | IOPL_MASK;
                        break;
                default:
-                       current->v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
+                       current->tss.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
                        break;
        }
 
@@ -136,9 +136,9 @@ asmlinkage int sys_vm86(struct vm86_struct * v86)
        pt_regs->eax = 0;
        current->saved_kernel_stack = current->tss.esp0;
        current->tss.esp0 = (unsigned long) pt_regs;
-       current->vm86_info = v86;
+       current->tss.vm86_info = v86;
 
-       current->screen_bitmap = info.screen_bitmap;
+       current->tss.screen_bitmap = info.screen_bitmap;
        if (info.flags & VM86_SCREEN_BITMAP)
                mark_screen_rdonly(current);
        __asm__ __volatile__("movl %0,%%esp\n\t"
@@ -178,7 +178,7 @@ static inline void clear_TF(struct vm86_regs * regs)
 
 static inline void set_vflags_long(unsigned long eflags, struct vm86_regs * regs)
 {
-       set_flags(VEFLAGS, eflags, current->v86mask);
+       set_flags(VEFLAGS, eflags, current->tss.v86mask);
        set_flags(regs->eflags, eflags, SAFE_MASK);
        if (eflags & IF_MASK)
                set_IF(regs);
@@ -186,7 +186,7 @@ static inline void set_vflags_long(unsigned long eflags, struct vm86_regs * regs
 
 static inline void set_vflags_short(unsigned short flags, struct vm86_regs * regs)
 {
-       set_flags(VFLAGS, flags, current->v86mask);
+       set_flags(VFLAGS, flags, current->tss.v86mask);
        set_flags(regs->eflags, flags, SAFE_MASK);
        if (flags & IF_MASK)
                set_IF(regs);
@@ -198,7 +198,7 @@ static inline unsigned long get_vflags(struct vm86_regs * regs)
 
        if (VEFLAGS & VIF_MASK)
                flags |= IF_MASK;
-       return flags | (VEFLAGS & current->v86mask);
+       return flags | (VEFLAGS & current->tss.v86mask);
 }
 
 static inline int is_revectored(int nr, struct revectored_struct * bitmap)
@@ -287,9 +287,9 @@ static void do_int(struct vm86_regs *regs, int i, unsigned char * ssp, unsigned
        unsigned short seg = get_fs_word((void *) ((i<<2)+2));
 
        if (seg == BIOSSEG || regs->cs == BIOSSEG ||
-           is_revectored(i, &current->vm86_info->int_revectored))
+           is_revectored(i, &current->tss.vm86_info->int_revectored))
                return_to_32bit(regs, VM86_INTx + (i << 8));
-       if (i==0x21 && is_revectored(AH(regs),&current->vm86_info->int21_revectored))
+       if (i==0x21 && is_revectored(AH(regs),&current->tss.vm86_info->int21_revectored))
                return_to_32bit(regs, VM86_INTx + (i << 8));
        pushw(ssp, sp, get_vflags(regs));
        pushw(ssp, sp, regs->cs);
index 8c69ff0c39f5106875c1024d788de83e30e47249..700330269dab643cf8f6002fcfa065411331af9b 100644 (file)
@@ -4,8 +4,196 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/string.h>
-
-/* all the actual functions should be inline anyway, so.. */
+/*
+ * stupid library routines.. The optimized versions should generally be found
+ * as inline code in <asm-xx/string.h>
+ *
+ * These are buggy as well..
+ */
+#include <linux/types.h>
 
 char * ___strtok = NULL;
+
+char * strcpy(char * dest,const char *src)
+{
+       char *tmp = dest;
+
+       while ((*dest++ = *src++) != '\0')
+               /* nothing */;
+       return tmp;
+}
+
+char * strncpy(char * dest,const char *src,size_t count)
+{
+       char *tmp = dest;
+
+       while ((*dest++ = *src++) != '\0' && --count)
+               /* nothing */;
+
+       return tmp;
+}
+
+char * strcat(char * dest, const char * src)
+{
+       char *tmp = dest;
+
+       while (*dest)
+               dest++;
+       while ((*dest++ = *src++) != '\0')
+               ;
+
+       return tmp;
+}
+
+char * strncat(char *dest, const char *src, size_t count)
+{
+       char *tmp = dest;
+
+       if (count) {
+               while (*dest)
+                       dest++;
+               while ((*dest++ = *src++)) {
+                       if (--count == 0)
+                               break;
+               }
+       }
+
+       return tmp;
+}
+
+int strcmp(const char * cs,const char * ct)
+{
+       register char __res;
+
+       while (1) {
+               if ((__res = *cs - *ct++) != 0 && *cs++)
+                       break;
+       }
+
+       return __res;
+}
+
+int strncmp(const char * cs,const char * ct,size_t count)
+{
+       register char __res = 0;
+
+       while (count) {
+               if ((__res = *cs - *ct++) != 0 || !*cs++)
+                       break;
+               count--;
+       }
+
+       return __res;
+}
+
+char * strchr(const char * s,char c)
+{
+       const char ch = c;
+
+       for(; *s != ch; ++s)
+               if (*s == '\0')
+                       return NULL;
+       return (char *) s;
+}
+
+size_t strlen(const char * s)
+{
+       const char *sc;
+
+       for (sc = s; *sc != '\0'; ++sc)
+               /* nothing */;
+       return sc - s;
+}
+
+size_t strspn(const char *s, const char *accept)
+{
+       const char *p;
+       const char *a;
+       size_t count = 0;
+
+       for (p = s; *p != '\0'; ++p) {
+               for (a = accept; *a != '\0'; ++a) {
+                       if (*p == *a)
+                               break;
+               }
+               if (*a == '\0')
+                       return count;
+               ++count;
+       }
+
+       return count;
+}
+
+char * strpbrk(const char * cs,const char * ct)
+{
+       const char *sc1,*sc2;
+
+       for( sc1 = cs; *sc1 != '\0'; ++sc1) {
+               for( sc2 = ct; *sc2 != '\0'; ++sc2) {
+                       if (*sc1 == *sc2)
+                               return (char *) sc1;
+               }
+       }
+       return NULL;
+}
+
+char * strtok(char * s,const char * ct)
+{
+       char *sbegin, *send;
+
+       sbegin  = s ? s : ___strtok;
+       if (!sbegin) {
+               return NULL;
+       }
+       sbegin += strspn(sbegin,ct);
+       if (*sbegin == '\0') {
+               ___strtok = NULL;
+               return( NULL );
+       }
+       send = strpbrk( sbegin, ct);
+       if (send && *send != '\0')
+               *send++ = '\0';
+       ___strtok = send;
+       return (sbegin);
+}
+
+void * memset(void * s,char c,size_t count)
+{
+       char *xs = (char *) s;
+
+       while (count--)
+               *xs++ = c;
+
+       return s;
+}
+
+void * memcpy(void * dest,const void *src,size_t count)
+{
+       char *tmp = (char *) dest, *s = (char *) src;
+
+       while (count--)
+               *tmp++ = *s++;
+
+       return dest;
+}
+
+void * memmove(void * dest,const void *src,size_t count)
+{
+       char *tmp = (char *) dest, *s = (char *) src;
+
+       while (count--)
+               *tmp++ = *s++;
+
+       return dest;
+}
+
+int memcmp(const void * cs,const void * ct,size_t count)
+{
+       const unsigned char *su1, *su2;
+
+       for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+               if (*su1 != *su2)
+                       return((*su1 < *su2) ? -1 : +1);
+       return(0);
+}
index b85d81ea057d18b4df207ae9720138ca1979efc4..8d435a2327892b3c29109ccd5a95385ee9887e5f 100644 (file)
@@ -1001,7 +1001,7 @@ good_area:
        if (regs->eflags & VM_MASK) {
                unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
                if (bit < 32)
-                       current->screen_bitmap |= 1 << bit;
+                       current->tss.screen_bitmap |= 1 << bit;
        }
        if (!(vma->vm_page_prot & PAGE_USER))
                goto bad_area;
index 8ca59b4ff6c11b76bb98a5ffeedbb99ab02b5def..6c76eb9dbf8a7c1e844ef2376413279ad57b9bd7 100644 (file)
@@ -2118,6 +2118,16 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
                        return 0;
                }
 #endif
+               case IP_MULTICAST_LOOP: 
+               {
+                       unsigned char ucval;
+
+                       ucval=get_fs_byte((unsigned char *)optval);
+                       if(ucval!=0 && ucval!=1)
+                                return -EINVAL;
+                       sk->ip_mc_loop=(int)ucval;
+                       return 0;
+               }
                case IP_MULTICAST_IF: 
                {
                        /* Not fully tested */
@@ -2357,6 +2367,9 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
                case IP_MULTICAST_TTL:
                        val=sk->ip_mc_ttl;
                        break;
+               case IP_MULTICAST_LOOP:
+                       val=sk->ip_mc_loop;
+                       break;
                case IP_MULTICAST_IF:
                        err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
                        if(err)
index c143924bd04beb19721f4170767284df0004ee48..78173fce7633f09b68fd50f3b257ecf3cdc01dbb 100644 (file)
@@ -90,12 +90,13 @@ get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t of
                        timer_active = del_timer(&sp->timer);
                        if (!timer_active)
                                sp->timer.expires = 0;
-                       len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d\n",
+                       len+=sprintf(buffer+len, "%2d: %08lX:%04X %08lX:%04X %02X %08lX:%08lX %02X:%08lX %08X %d %d\n",
                                i, src, srcp, dest, destp, sp->state, 
                                format==0?sp->write_seq-sp->rcv_ack_seq:sp->rmem_alloc, 
                                format==0?sp->acked_seq-sp->copied_seq:sp->wmem_alloc,
                                timer_active, sp->timer.expires, (unsigned) sp->retransmits,
-                               sp->socket?SOCK_INODE(sp->socket)->i_uid:0);
+                               sp->socket?SOCK_INODE(sp->socket)->i_uid:0,
+                               timer_active?sp->timeout:0);
                        if (timer_active)
                                add_timer(&sp->timer);
                        /*
index cb8aef93857b0f9067c8153b3295d48a680c8fae..20dbdcf4b96440e90ee9621dbfca416e7a8ce36f 100644 (file)
@@ -241,7 +241,7 @@ static __inline__ void tcp_set_state(struct sock *sk, int state)
        if(sk->debug)
                printk("TCP sk=%p, State %s -> %s\n",sk, statename[sk->state],statename[state]);
 #endif 
-       /* This is a hack but it doesnt occur often and its going to
+       /* This is a hack but it doesn't occur often and its going to
           be a real        to fix nicely */
           
        if(state==TCP_ESTABLISHED && sk->state==TCP_SYN_RECV)
@@ -602,7 +602,7 @@ static int tcp_readable(struct sock *sk)
                return(0);
        }
   
-       counted = sk->copied_seq+1;     /* Where we are at the moment */
+       counted = sk->copied_seq;       /* Where we are at the moment */
        amount = 0;
   
        /* Do until a push or until we are out of data. */
@@ -655,43 +655,29 @@ static int tcp_readable(struct sock *sk)
  *     listening socket has a receive queue of sockets to accept.
  */
 
-static int tcp_select(struct sock *sk, int sel_type, select_table *wait)
+static int do_tcp_select(struct sock *sk, int sel_type, select_table *wait)
 {
-       sk->inuse = 1;
-
        switch(sel_type) 
        {
                case SEL_IN:
-                       select_wait(sk->sleep, wait);
-                       if(sk->state==TCP_LISTEN)
+                       if (sk->err)
+                               return 1;
+                       if (sk->state == TCP_LISTEN) {
                                select_wait(&master_select_wakeup,wait);
-                       if (skb_peek(&sk->receive_queue) != NULL) 
-                       {
-                               if ((sk->state == TCP_LISTEN && tcp_find_established(sk)) || tcp_readable(sk)) 
-                               {
-                                       release_sock(sk);
-                                       return(1);
-                               }
+                               return (tcp_find_established(sk) != NULL);
                        }
-                       if (sk->err != 0)       /* Receiver error */
-                       {
-                               release_sock(sk);
-                               return(1);
-                       }
-                       if (sk->shutdown & RCV_SHUTDOWN) 
-                       {
-                               release_sock(sk);
-                               return(1);
-                       } 
-                       release_sock(sk);
-                       return(0);
+                       if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)
+                               return 0;
+                       if (sk->acked_seq != sk->copied_seq)
+                               return 1;
+                       if (sk->shutdown & RCV_SHUTDOWN)
+                               return 1;
+                       return 0;
+
                case SEL_OUT:
-                       select_wait(sk->sleep, wait);
-                       if (sk->shutdown & SEND_SHUTDOWN) 
-                       {
+                       if (sk->shutdown & SEND_SHUTDOWN) {
                                /* FIXME: should this return an error? */
-                               release_sock(sk);
-                               return(0);
+                               return 0;
                        }
 
                        /*
@@ -701,29 +687,31 @@ static int tcp_select(struct sock *sk, int sel_type, select_table *wait)
                        
                        if (sk->prot->wspace(sk) >= sk->mtu+128+sk->prot->max_header) 
                        {
-                               release_sock(sk);
                                /* This should cause connect to work ok. */
                                if (sk->state == TCP_SYN_RECV ||
-                                   sk->state == TCP_SYN_SENT) return(0);
-                               return(1);
+                                   sk->state == TCP_SYN_SENT) return 0;
+                               return 1;
                        }
-                       release_sock(sk);
-                       return(0);
+                       return 0;
+
                case SEL_EX:
-                       select_wait(sk->sleep,wait);
-                       if (sk->err || sk->urg_data) 
-                       {
-                               release_sock(sk);
-                               return(1);
-                       }
-                       release_sock(sk);
-                       return(0);
+                       if (sk->err || sk->urg_data)
+                               return 1;
+                       return 0;
        }
-
-       release_sock(sk);
-       return(0);
+       return 0;
 }
 
+static int tcp_select(struct sock *sk, int sel_type, select_table *wait)
+{
+       int retval;
+
+       sk->inuse = 1;
+       select_wait(sk->sleep, wait);
+       retval = do_tcp_select(sk, sel_type, wait);
+       release_sock(sk);
+       return retval;
+}
 
 int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
@@ -753,7 +741,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
                }
                case SIOCATMARK:
                {
-                       int answ = sk->urg_data && sk->urg_seq == sk->copied_seq+1;
+                       int answ = sk->urg_data && sk->urg_seq == sk->copied_seq;
 
                        err = verify_area(VERIFY_WRITE,(void *) arg,
                                                  sizeof(unsigned long));
@@ -1702,7 +1690,7 @@ static int tcp_read(struct sock *sk, unsigned char *to,
                /*
                 * are we at urgent data? Stop if we have read anything.
                 */
-               if (copied && sk->urg_data && sk->urg_seq == 1+*seq)
+               if (copied && sk->urg_data && sk->urg_seq == *seq)
                        break;
 
                current->state = TASK_INTERRUPTIBLE;
@@ -1712,13 +1700,15 @@ static int tcp_read(struct sock *sk, unsigned char *to,
                {
                        if (!skb)
                                break;
-                       if (before(1+*seq, skb->h.th->seq))
+                       if (before(*seq, skb->h.th->seq))
                                break;
-                       offset = 1 + *seq - skb->h.th->seq;
+                       offset = *seq - skb->h.th->seq;
                        if (skb->h.th->syn)
                                offset--;
                        if (offset < skb->len)
                                goto found_ok_skb;
+                       if (skb->h.th->fin)
+                               goto found_fin_ok;
                        if (!(flags & MSG_PEEK))
                                skb->used = 1;
                        skb = skb->next;
@@ -1778,7 +1768,7 @@ static int tcp_read(struct sock *sk, unsigned char *to,
                /* do we have urgent data here? */
                if (sk->urg_data) 
                {
-                       unsigned long urg_offset = sk->urg_seq - (1 + *seq);
+                       unsigned long urg_offset = sk->urg_seq - *seq;
                        if (urg_offset < used) 
                        {
                                if (!urg_offset) 
@@ -1801,10 +1791,25 @@ static int tcp_read(struct sock *sk, unsigned char *to,
                len -= used;
                to += used;
                *seq += used;
-               if (after(sk->copied_seq+1,sk->urg_seq))
+               if (after(sk->copied_seq,sk->urg_seq))
                        sk->urg_data = 0;
-               if (!(flags & MSG_PEEK) && (used + offset >= skb->len))
-                       skb->used = 1;
+               if (used + offset < skb->len)
+                       continue;
+               if (skb->h.th->fin)
+                       goto found_fin_ok;
+               if (flags & MSG_PEEK)
+                       continue;
+               skb->used = 1;
+               continue;
+
+       found_fin_ok:
+               ++*seq;
+               if (flags & MSG_PEEK)
+                       break;
+               skb->used = 1;
+               sk->shutdown |= RCV_SHUTDOWN;
+               break;
+
        }
        remove_wait_queue(sk->sleep, &wait);
        current->state = TASK_RUNNING;
@@ -2256,8 +2261,8 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
        newsk->shutdown = 0;
        newsk->ack_backlog = 0;
        newsk->acked_seq = skb->h.th->seq+1;
+       newsk->copied_seq = skb->h.th->seq+1;
        newsk->fin_seq = skb->h.th->seq;
-       newsk->copied_seq = skb->h.th->seq;
        newsk->state = TCP_SYN_RECV;
        newsk->timeout = 0;
        newsk->write_seq = seq; 
@@ -2291,7 +2296,7 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
        newsk->dummy_th.urg = 0;
        newsk->dummy_th.res2 = 0;
        newsk->acked_seq = skb->h.th->seq + 1;
-       newsk->copied_seq = skb->h.th->seq;
+       newsk->copied_seq = skb->h.th->seq + 1;
        newsk->socket = NULL;
 
        /*
@@ -2780,7 +2785,7 @@ extern __inline__ int tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long
                sk->send_tail = NULL;
        
                /*
-                *      This is an artefact of a flawed concept. We want one
+                *      This is an artifact of a flawed concept. We want one
                 *      queue and a smarter send routine when we send all.
                 */
        
@@ -3175,7 +3180,7 @@ extern __inline__ int tcp_ack(struct sock *sk, struct tcphdr *th, unsigned long
                tcp_set_state(sk, TCP_ESTABLISHED);
                tcp_options(sk,th);
                sk->dummy_th.dest=th->source;
-               sk->copied_seq=sk->acked_seq-1;
+               sk->copied_seq = sk->acked_seq;
                if(!sk->dead)
                        sk->state_change(sk);
                if(sk->max_window==0)
@@ -3373,7 +3378,7 @@ extern __inline__ int tcp_data(struct sk_buff *skb, struct sock *sk,
        {
                /*
                 *      FIXME: BSD has some magic to avoid sending resets to
-                *      broken 4.2 BSD keepalives. Much to my suprise a few none
+                *      broken 4.2 BSD keepalives. Much to my surprise a few non
                 *      BSD stacks still have broken keepalives so we want to
                 *      cope with it.
                 */
@@ -3529,15 +3534,12 @@ extern __inline__ int tcp_data(struct sk_buff *skb, struct sock *sk,
                        skb->acked = 1;
 
                        /*
-                        *      When we ack the fin, we turn on the RCV_SHUTDOWN flag. Also do the FIN 
+                        *      When we ack the fin, we do the FIN 
                         *      processing.
                         */
 
                        if (skb->h.th->fin) 
                        {
-                               if (!sk->dead) 
-                                       sk->state_change(sk);
-                               sk->shutdown |= RCV_SHUTDOWN;
                                tcp_fin(skb,sk,skb->h.th);
                        }
          
@@ -3558,14 +3560,11 @@ extern __inline__ int tcp_data(struct sk_buff *skb, struct sock *sk,
                                        }
                                        skb2->acked = 1;
                                        /*
-                                        *      When we ack the fin, we turn on
-                                        *      the RCV_SHUTDOWN flag.
+                                        *      When we ack the fin, we do
+                                        *      the fin handling.
                                         */
                                        if (skb2->h.th->fin) 
                                        {
-                                               sk->shutdown |= RCV_SHUTDOWN;
-                                               if (!sk->dead)
-                                                       sk->state_change(sk);
                                                tcp_fin(skb,sk,skb->h.th);
                                        }
 
@@ -3676,7 +3675,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
        ptr += th->seq;
 
        /* ignore urgent data that we've already seen and read */
-       if (after(sk->copied_seq+1, ptr))
+       if (after(sk->copied_seq, ptr))
                return;
 
        /* do we already have a newer (or duplicate) urgent pointer? */
@@ -4174,7 +4173,7 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
        /*
         *      This basically follows the flow suggested by RFC793, with the corrections in RFC1122. We
         *      don't implement precedence and we process URG incorrectly (deliberately so) for BSD bug
-        *      compatibility. We also set up variables more throughroughly [Karn notes in the
+        *      compatibility. We also set up variables more thoroughly [Karn notes in the
         *      KA9Q code the RFC793 incoming segment rules don't initialise the variables for all paths].
         */
 
@@ -4223,12 +4222,20 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                        return 0;
                }
        
+               /* retransmitted SYN? */
+               if (sk->state == TCP_SYN_RECV && th->syn && th->seq+1 == sk->acked_seq)
+               {
+                       kfree_skb(skb, FREE_READ);
+                       release_sock(sk);
+                       return 0;
+               }
+               
                /*
                 *      SYN sent means we have to look for a suitable ack and either reset
                 *      for bad matches or go to connected 
                 */
           
-               else if(sk->state==TCP_SYN_SENT)
+               if(sk->state==TCP_SYN_SENT)
                {
                        /* Crossed SYN or previous junk segment */
                        if(th->ack)
@@ -4266,7 +4273,7 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                                tcp_set_state(sk, TCP_ESTABLISHED);
                                tcp_options(sk,th);
                                sk->dummy_th.dest=th->source;
-                               sk->copied_seq=sk->acked_seq-1;
+                               sk->copied_seq = sk->acked_seq;
                                if(!sk->dead)
                                        sk->state_change(sk);
                                if(sk->max_window==0)
@@ -4306,51 +4313,50 @@ int tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
                         */
                        goto rfc_step6;
                }
-               
-       }
-               
-       /* BSD has a funny hack with TIME_WAIT and fast reuse of a port. We
-          don't use it, we don't need it and its not in the spec. There is
+
+       /* BSD has a funny hack with TIME_WAIT and fast reuse of a port. There is
           a more complex suggestion for fixing these reuse issues in RFC1644
           but not yet ready for general use. Also see RFC1379.*/
        
-       /* We are now in normal data flow (see the step list in the RFC) */
-       /* Note most of these are inline now. I'll inline the lot when
-          I have time to test it hard and look at what gcc outputs */
-
 #define BSD_TIME_WAIT
 #ifdef BSD_TIME_WAIT
-       if (sk->state == TCP_TIME_WAIT && th->syn && sk->dead && 
-               after(th->seq, sk->acked_seq) && !th->rst)
-       {
-               long seq=sk->write_seq;
-               if(sk->debug)
-                       printk("Doing a BSD time wait\n");
-               tcp_statistics.TcpEstabResets++;           
-               sk->rmem_alloc -= skb->mem_len;
-               skb->sk = NULL;
-               sk->err=ECONNRESET;
-               tcp_set_state(sk, TCP_CLOSE);
-               sk->shutdown = SHUTDOWN_MASK;
-               release_sock(sk);
-               sk=get_sock(&tcp_prot, th->dest, saddr, th->source, daddr);
-               if(sk && sk->state==TCP_LISTEN)
+               if (sk->state == TCP_TIME_WAIT && th->syn && sk->dead && 
+                       after(th->seq, sk->acked_seq) && !th->rst)
                {
-                       sk->inuse=1;
-                       skb->sk = sk;
-                       sk->rmem_alloc += skb->mem_len;
-                       tcp_conn_request(sk, skb, daddr, saddr,opt, dev,seq+128000);
+                       long seq=sk->write_seq;
+                       if(sk->debug)
+                               printk("Doing a BSD time wait\n");
+                       tcp_statistics.TcpEstabResets++;           
+                       sk->rmem_alloc -= skb->mem_len;
+                       skb->sk = NULL;
+                       sk->err=ECONNRESET;
+                       tcp_set_state(sk, TCP_CLOSE);
+                       sk->shutdown = SHUTDOWN_MASK;
                        release_sock(sk);
+                       sk=get_sock(&tcp_prot, th->dest, saddr, th->source, daddr);
+                       if (sk && sk->state==TCP_LISTEN)
+                       {
+                               sk->inuse=1;
+                               skb->sk = sk;
+                               sk->rmem_alloc += skb->mem_len;
+                               tcp_conn_request(sk, skb, daddr, saddr,opt, dev,seq+128000);
+                               release_sock(sk);
+                               return 0;
+                       }
+                       kfree_skb(skb, FREE_READ);
                        return 0;
                }
-               kfree_skb(skb, FREE_READ);
-               return 0;
-       }
 #endif 
+       }
+
+       /* We are now in normal data flow (see the step list in the RFC) */
+       /* Note most of these are inline now. I'll inline the lot when
+          I have time to test it hard and look at what gcc outputs */
        
-       if(/*sk->state!=TCP_SYN_RECV &&*/ !tcp_sequence(sk,th,len,opt,saddr,dev))
+       if(!tcp_sequence(sk,th,len,opt,saddr,dev))
        {
                kfree_skb(skb, FREE_READ);
+               release_sock(sk);
                return 0;
        }
 
@@ -4501,7 +4507,7 @@ static void tcp_write_wakeup(struct sock *sk)
 }
 
 /*
- *     A window probe timeout has occured.
+ *     A window probe timeout has occurred.
  */
 
 void tcp_send_probe0(struct sock *sk)