]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Linux-0.99.4 (January 20, 1993) 0.99.4
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:08 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:08 +0000 (15:09 -0500)
net-1: random addition of "volatile" keywords to try to hide race
conditions in the code.

File locking updated with shared and exclusive locks for BSD flock.

Re-mounting of filesystems and new mount system call.

Re: Freeze up on X

In article <1993Jan21.181502.23485@miles.com> dennisf@miles.com (Dennis Flaherty) writes:
>
>Here's another clue.  Try this: when your system freezes, running X, try
>MOVING THE MOUSE.  It's weird!!  But moving the mouse actually makes the
>system run!  Stop moving the mouse, and the system freezes again.  And
>this only happens with 0.99.3, not 0.99.2.

Get pl4, and it should be gone.  There was a bug in the handling of
uninitialized interrupts in pl3, where they could result in either the
wrong interrupt mask being loaded leading to interrupt lock-out or (in
some cases) bit corruption at the user level.  The symptoms are exactly
as you describe: a good interrupt that didn't happen to be locked out
will correct the interrupt mask, and the system goes on (it can be
moving the mouse, but it might also be a keyboard event etc).

            Linus

23 files changed:
Makefile
boot/head.S
boot/setup.S
fs/locks.c
fs/minix/bitmap.c
fs/pipe.c
fs/proc/array.c
fs/proc/root.c
fs/super.c
include/asm/bitops.h
include/asm/irq.h
include/linux/fcntl.h
include/linux/fs.h
include/linux/sched.h
include/linux/tasks.h [new file with mode: 0644]
kernel/blk_drv/scsi/scsi.c
kernel/blk_drv/scsi/seagate.c
kernel/chr_drv/sound/sound_stub.c
kernel/chr_drv/tty_io.c
kernel/ptrace.c
mm/memory.c
net/tcp/dev.c
net/tcp/tcp.c

index 6de4fde122565d76e3d6f451a162b54e38b82b1e..f377e4aa094112a9e8a5bdbac1fd8109a4ef40ef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,6 @@
+
+all:   Version Image
+
 #
 # Make "config" the default target if there is no configuration file or
 # "depend" the target if there is no top-level dependency information.
@@ -123,10 +126,8 @@ KERNELHDRS =/usr/src/linux/include
 .c.o:
        $(CC) $(CFLAGS) -c -o $*.o $<
 
-all:   Version Image
-
 Version: dummy
-       rm tools/version.h
+       rm -f tools/version.h
 
 lilo: $(CONFIGURE) Image
        if [ -f /vmlinux ]; then mv /vmlinux /vmlinux.old; fi
@@ -140,9 +141,11 @@ config:
 linuxsubdirs: dummy
        @for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
 
+tools/./version.h: tools/version.h
+
 tools/version.h: $(CONFIGURE) Makefile
        @./makever.sh
-       @echo \#define UTS_RELEASE \"0.99.pl3-`cat .version`\" > tools/version.h
+       @echo \#define UTS_RELEASE \"0.99.pl4-`cat .version`\" > tools/version.h
        @echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
        @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
        @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
@@ -164,7 +167,7 @@ tools/build: $(CONFIGURE) tools/build.c
 
 boot/head.o: $(CONFIGURE) boot/head.s
 
-boot/head.s: $(CONFIGURE) boot/head.S
+boot/head.s: $(CONFIGURE) boot/head.S include/linux/tasks.h
        $(CPP) -traditional boot/head.S -o boot/head.s
 
 tools/version.o: tools/version.c tools/version.h
index 7497241ae12eb59642648ae3fb97a6c23feedd1f..8cf5c4a22abdc38f87b7025194af0125489065bd 100644 (file)
@@ -18,6 +18,8 @@
 .globl _empty_bad_page_table
 .globl _tmp_floppy_area,_floppy_track_buffer
 
+#include <linux/tasks.h>
+
 /*
  * swapper_pg_dir is the main page directory, address 0x00001000
  */
@@ -266,7 +268,7 @@ _idt:
 .align 4
 .word 0
 gdt_descr:
-       .word 256*8-1
+       .word (4+2*NR_TASKS)*8-1
        .long 0xc0000000+_gdt
 
 /*
@@ -279,4 +281,4 @@ _gdt:
        .quad 0xc0c39a000000ffff        /* 1GB at 0xC0000000 */
        .quad 0xc0c392000000ffff        /* 1GB */
        .quad 0x0000000000000000        /* TEMPORARY - don't use */
-       .fill 252,8,0                   /* space for LDT's and TSS's etc */
+       .fill 2*NR_TASKS,8,0            /* space for LDT's and TSS's etc */
index 0fa8efcdf46d9361d40ac474ac90b2c55d068196..1bebecd059665bcd0fd28a17cc7bb0ac4c8a11ec 100644 (file)
@@ -227,9 +227,14 @@ end_move:
 ! things as simple as possible, we do no register set-up or anything,
 ! we let the gnu-compiled 32-bit programs do that. We just jump to
 ! absolute address 0x00000, in 32-bit protected mode.
-
+!
+! Note that the short jump isn't strictly needed, althought there are
+! reasons why it might be a good idea. It won't hurt in any case.
+!
        mov     ax,#0x0001      ! protected mode (PE) bit
        lmsw    ax              ! This is it!
+       jmp     flush_instr
+flush_instr:
        jmpi    0,8             ! jmp offset 0 of segment 8 (cs)
 
 ! This routine checks that the keyboard command queue is empty
@@ -258,8 +263,7 @@ getkey:
 !
 ! Flush the keyboard buffer
 !
-flush: in      al,#0x60
-       .word   0x00eb,0x00eb
+flush: call getkey
        cmp     al,#0x82
        jae     flush
        ret
@@ -321,8 +325,7 @@ svga:       cld
        jne     nf1280  
        lea     si,dscf1280
        lea     di,mof1280
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 nf1280:        cld
        lea     si,idati                ! Check ATI 'clues'
        mov     di,#0x31
@@ -332,8 +335,7 @@ nf1280:     cld
        jne     noati
        lea     si,dscati
        lea     di,moati
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 noati: mov     ax,#0x200f              ! Check Ahead 'clues'
        mov     dx,#0x3ce
        out     dx,ax
@@ -345,8 +347,7 @@ noati:      mov     ax,#0x200f              ! Check Ahead 'clues'
        jne     noahed
 isahed:        lea     si,dscahead
        lea     di,moahead
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 noahed:        mov     dx,#0x3c3               ! Check Chips & Tech. 'clues'
        in      al,dx
        or      al,#0x10
@@ -362,8 +363,7 @@ noahed:     mov     dx,#0x3c3               ! Check Chips & Tech. 'clues'
        jne     nocant
        lea     si,dsccandt
        lea     di,mocandt
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 nocant:        mov     dx,#0x3d4               ! Check Cirrus 'clues'
        mov     al,#0x0c
        out     dx,al
@@ -401,8 +401,7 @@ nocant:     mov     dx,#0x3d4               ! Check Cirrus 'clues'
        call    rst3d4  
        lea     si,dsccirrus
        lea     di,mocirrus
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 rst3d4:        mov     dx,#0x3d4
        mov     al,bl
        xor     ah,ah
@@ -423,8 +422,7 @@ nocirr:     call    rst3d4                  ! Check Everex 'clues'
        je      istrid
        lea     si,dsceverex
        lea     di,moeverex
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 istrid:        lea     cx,ev2tri
        jmp     cx
 noevrx:        lea     si,idgenoa              ! Check Genoa 'clues'
@@ -446,8 +444,7 @@ l1: inc     si
        jne     nogen
        lea     si,dscgenoa
        lea     di,mogenoa
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 nogen: cld
        lea     si,idoakvga
        mov     di,#0x08
@@ -457,8 +454,7 @@ nogen:      cld
        jne     nooak
        lea     si,dscoakvga
        lea     di,mooakvga
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 nooak: cld
        lea     si,idparadise           ! Check Paradise 'clues'
        mov     di,#0x7d
@@ -468,8 +464,7 @@ nooak:      cld
        jne     nopara
        lea     si,dscparadise
        lea     di,moparadise
-       lea     cx,selmod
-       jmp     cx
+       br      selmod
 nopara:        mov     dx,#0x3c4               ! Check Trident 'clues'
        mov     al,#0x0e
        out     dx,al
@@ -492,8 +487,7 @@ clrb2:      out     dx,al
        jne     notrid
 ev2tri:        lea     si,dsctrident
        lea     di,motrident
-       lea     cx,selmod
-       jmp     cx
+       jmp     selmod
 notrid:        mov     dx,#0x3cd               ! Check Tseng 'clues'
        in      al,dx                   ! Could things be this simple ! :-)
        mov     bl,al
@@ -507,8 +501,7 @@ notrid:     mov     dx,#0x3cd               ! Check Tseng 'clues'
        jne     notsen
        lea     si,dsctseng
        lea     di,motseng
-       lea     cx,selmod
-       jmp     cx
+       jmp     selmod
 notsen:        mov     dx,#0x3cc               ! Check Video7 'clues'
        in      al,dx
        mov     dx,#0x3b4
index d99821b6dddac6d6a53199deaa0d0a6ee683c393..21793183c0112d6ff385e86a30d943bd4e056fa0 100644 (file)
@@ -110,6 +110,16 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
                if (!(filp->f_mode & 2))
                        return -EBADF;
                break;
+       case F_SHLCK :
+               if (!(filp->f_mode & 3))
+                       return -EBADF;
+               file_lock.fl_type = F_RDLCK;
+               break;
+       case F_EXLCK :
+               if (!(filp->f_mode & 3))
+                       return -EBADF;
+               file_lock.fl_type = F_WRLCK;
+               break;
        case F_UNLCK :
                break;
        }
index 154b7e292fcbbe59e83aa678726e607167c7c3b7..93466b22fc5b32cfdfa987d96512bcb1245c526d 100644 (file)
 #include <linux/kernel.h>
 #include <linux/string.h>
 
+#include <asm/bitops.h>
+
 #define clear_block(addr) \
 __asm__("cld\n\t" \
        "rep\n\t" \
        "stosl" \
        ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
 
-#define set_bit(nr,addr) ({\
-char res; \
-__asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
-"=q" (res):"r" (nr),"m" (*(addr))); \
-res;})
-
-#define clear_bit(nr,addr) ({\
-char res; \
-__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
-"=q" (res):"r" (nr),"m" (*(addr))); \
-res;})
-
 #define find_first_zero(addr) ({ \
 int __res; \
 __asm__("cld\n" \
index ca1e7584e42ebdd489e70902234ef78bf01fddd2..6ac34c1c47df19d0b28aa68454f2019459a0b399 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -40,7 +40,11 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
                buf += chars;
        }
        wake_up(& PIPE_WRITE_WAIT(*inode));
-       return read?read:-EAGAIN;
+       if (read)
+               return read;
+       if (PIPE_WRITERS(*inode))
+               return -EAGAIN;
+       return 0;
 }
        
 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
index e622571bded7fd11690737f04a4db3feca72ae84..c5525845178aca909d6a793d84f12a6865d87754 100644 (file)
@@ -59,6 +59,14 @@ static int get_meminfo(char * buffer)
                i.totalswap, i.totalswap-i.freeswap, i.freeswap);
 }
 
+static int get_version(char * buffer)
+{
+       extern char *linux_banner;
+
+       strcpy(buffer, linux_banner);
+       return strlen(buffer);
+}
+
 static struct task_struct ** get_task(pid_t pid)
 {
        struct task_struct ** p;
@@ -296,6 +304,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
                case 4:
                        length = get_meminfo(page);
                        break;
+               case 6:
+                       length = get_version(page);
+                       break;
                case 9:
                        length = get_env(pid, page);
                        break;
index a52204e9758466361248a1b16fd971c7021a6ebe..3dbec2dae91304072be09865cef9f8488eb459ff 100644 (file)
@@ -56,7 +56,8 @@ static struct proc_dir_entry root_dir[] = {
        { 3,6,"uptime" },
        { 4,7,"meminfo" },
        { 5,4,"kmsg" },
-       { 6,4,"self" }  /* will change inode # */
+       { 6,7,"version" },
+       { 7,4,"self" }  /* will change inode # */
 };
 
 #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
@@ -83,7 +84,7 @@ static int proc_lookuproot(struct inode * dir,const char * name, int len,
                        *result = dir;
                        return 0;
                }
-               if (ino == 6) /* self modifying inode ... */
+               if (ino == 7) /* self modifying inode ... */
                        ino = (current->pid << 16) + 2;
        } else {
                pid = 0;
index f18e24dbde68f9ce4a9977b80e04ab9f29e7ccde..a5acab0a1680836f1a8ff1c4410c6414d970b338 100644 (file)
@@ -310,6 +310,32 @@ static int do_mount(dev_t dev, const char * dir, char * type, int flags, void *
        return 0;               /* we don't iput(dir_i) - see umount */
 }
 
+
+/*
+ * Alters the mount flags of a mounted file system. Only the mount point
+ * is used as a reference - file system type and the device are ignored.
+ * FS-specific mount options can't be altered by remounting.
+ */
+
+static int do_remount(const char *dir,int flags)
+{
+       struct inode *dir_i;
+       int retval;
+
+       retval = namei(dir,&dir_i);
+       if (retval)
+               return retval;
+       if (dir_i != dir_i->i_sb->s_mounted) {
+               iput(dir_i);
+               return -EINVAL;
+       }
+       dir_i->i_sb->s_flags = (dir_i->i_sb->s_flags & ~MS_RMT_MASK) |
+               (flags & MS_RMT_MASK);
+       iput(dir_i);
+       return 0;
+}
+
+
 /*
  * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
  * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
@@ -337,6 +363,10 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
 
        if (!suser())
                return -EPERM;
+       if ((new_flags & (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL |
+           MS_REMOUNT))
+               return do_remount(dir_name,new_flags & ~MS_MGC_MSK &
+                   ~MS_REMOUNT);
        if (type) {
                for (i = 0 ; i < 100 ; i++)
                        if (!(tmp[i] = get_fs_byte(type++)))
@@ -378,8 +408,8 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
                        return retval;
                }
        }
-       if ((new_flags & 0xffff0000) == 0xC0ED0000) {
-               flags = new_flags & 0xffff;
+       if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
+               flags = new_flags & ~MS_MGC_MSK;
                if (data) {
                        if ((unsigned long) data >= TASK_SIZE) {
                                iput(inode);
index 7140009ba270cb36d51be53e9917a0d2955a3090..b7a88331ed4105e7a978b40299cb9225354036c6 100644 (file)
  *
  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  */
-extern inline int set_bit(int nr,int * addr)
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy { unsigned long a[100]; };
+#define ADDR (*(struct __dummy *) addr)
+
+extern inline int set_bit(int nr, void * addr)
 {
        char ok;
 
-       __asm__ __volatile__("btsl %1,%2\n\tsetb %0":
-               "=q" (ok):"r" (nr),"m" (*(addr)));
+       __asm__ __volatile__("btsl %2,%1\n\tsetb %0"
+               :"=q" (ok),"=m" (ADDR)
+               :"r" (nr));
        return ok;
 }
 
-extern inline int clear_bit(int nr, int * addr)
+extern inline int clear_bit(int nr, void * addr)
 {
        char ok;
 
-       __asm__ __volatile__("btrl %1,%2\n\tsetnb %0":
-               "=q" (ok):"r" (nr),"m" (*(addr)));
+       __asm__ __volatile__("btrl %2,%1\n\tsetnb %0"
+               :"=q" (ok),"=m" (ADDR)
+               :"r" (nr));
        return ok;
 }
 
@@ -33,12 +42,13 @@ extern inline int clear_bit(int nr, int * addr)
  * This routine doesn't need to be atomic, but it's faster to code it
  * this way.
  */
-extern inline int test_bit(int nr, int * addr)
+extern inline int test_bit(int nr, void * addr)
 {
        char ok;
 
-       __asm__ __volatile__("btl %1,%2\n\tsetb %0":
-               "=q" (ok):"r" (nr),"m" (*(addr)));
+       __asm__ __volatile__("btl %2,%1\n\tsetb %0"
+               :"=q" (ok)
+               :"m" (ADDR),"r" (nr));
        return ok;
 }
 
index 3d16fbbb7b9014328542e8bad9fac42ddbf16978..ea8685c3eb75b80493885a9c3d0bd4c5f68a3749 100644 (file)
        "pop %es\n\t" \
        "iret"
 
+/*
+ * The "inb" instructions are not needed, but seem to change the timings
+ * a bit - without them it seems that the harddisk driver won't work on
+ * all hardware. Arghh.
+ */
 #define ACK_FIRST(mask) \
-       "orb $" #mask ",_cache_21\n\t" \
+       "inb $0x21,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\torb $" #mask ",_cache_21\n\t" \
        "movb _cache_21,%al\n\t" \
        "outb %al,$0x21\n\t" \
        "jmp 1f\n" \
        "outb %al,$0x20\n\t"
 
 #define ACK_SECOND(mask) \
-       "orb $" #mask ",_cache_A1\n\t" \
+       "inb $0xA1,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\torb $" #mask ",_cache_A1\n\t" \
        "movb _cache_A1,%al\n\t" \
        "outb %al,$0xA1\n\t" \
        "jmp 1f\n" \
        "1:\toutb %al,$0x20\n\t"
 
 #define UNBLK_FIRST(mask) \
-       "andb $~(" #mask "),_cache_21\n\t" \
+       "inb $0x21,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tandb $~(" #mask "),_cache_21\n\t" \
        "movb _cache_21,%al\n\t" \
        "outb %al,$0x21\n\t"
 
 #define UNBLK_SECOND(mask) \
-       "andb $~(" #mask "),_cache_A1\n\t" \
+       "inb $0xA1,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tandb $~(" #mask "),_cache_A1\n\t" \
        "movb _cache_A1,%al\n\t" \
        "outb %al,$0xA1\n\t"
 
@@ -159,9 +176,8 @@ __asm__( \
        RESTORE_MOST \
 "\n\n.align 4\n" \
 "_bad_IRQ" #nr "_interrupt:\n\t" \
-       "pushl %eax\n\t" \
+       SAVE_MOST \
        ACK_##chip(mask) \
-       "popl %eax\n\t" \
-       "iret");
+       RESTORE_MOST);
 
 #endif
index 8b0721acc628d3ddee6e79d9fdfe855bd72c78c9..cea4f5f28d5c1718f50b4802f756b8ee52bf8fca 100644 (file)
 #define F_WRLCK                1
 #define F_UNLCK                2
 
+/* For bsd flock () */
+#define F_EXLCK                4       /* or 3 */
+#define F_SHLCK                8       /* or 4 */
+
 /* Once again - not implemented, but ... */
 struct flock {
        short l_type;
index c7b57441f979a244ccabc44cec8bb47220cf4830..2c4536ee2afd43282bb3695a2a82502d5afd6c01 100644 (file)
@@ -88,14 +88,28 @@ extern unsigned long inode_init(unsigned long start, unsigned long end);
 #define MS_NODEV     4 /* disallow access to device special files */
 #define MS_NOEXEC    8 /* disallow program execution */
 #define MS_SYNC     16 /* writes are synced at once */
+#define        MS_REMOUNT  32 /* alter flags of a mounted FS */
+
+/*
+ * Flags that can be altered by MS_REMOUNT
+ */
+#define MS_RMT_MASK (MS_RDONLY)
+
+/*
+ * Magic mount flag number. Has to be or-ed to the flag values.
+ */
+#define MS_MGC_VAL 0xC0ED0000 /* magic flag number to indicate "new" flags */
+#define MS_MGC_MSK 0xffff0000 /* magic flag number mask */
 
 /*
  * Note that read-only etc flags are inode-specific: setting some file-system
  * flags just means all the inodes inherit those flags by default. It might be
  * possible to overrride it sevelctively if you really wanted to with some
  * ioctl() that is not currently implemented.
+ *
+ * Exception: MS_RDONLY is always applied to the entire file system.
  */
-#define IS_RDONLY(inode) ((inode)->i_flags & MS_RDONLY)
+#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
 #define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
 #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
 #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
index e6fdbfbed9de915235cde312db975506c3c0da7d..dcdb86f04e72b654bbfc3185ba966b6f2216571d 100644 (file)
 
 #define HZ 100
 
-/*
- * This is the maximum nr of tasks - change it if you need to
- */
-#define NR_TASKS       64
+#include <linux/tasks.h>
 
 /*
  * User space process size: 3GB. This is hardcoded into a few places,
diff --git a/include/linux/tasks.h b/include/linux/tasks.h
new file mode 100644 (file)
index 0000000..0607d87
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _LINUX_TASKS_H
+#define _LINUX_TASKS_H
+
+/*
+ * This is the maximum nr of tasks - change it if you need to
+ */
+#define NR_TASKS       64
+
+#endif
index a00c28445ec58907e93a8851358638b5941ef8bd..3ef91be8454d2c275fb8ca7805d5e687ecc783a8 100644 (file)
@@ -113,11 +113,16 @@ static struct blist blacklist[] =
 
 static int blacklisted(char * response_data){
   int i = 0;
+  char * pnt;
   for(i=0; 1; i++){
     if(blacklist[i].vendor == NULL) return 0;
-    if(strncmp(blacklist[i].vendor, &response_data[8],
+    pnt = &response_data[8];
+    while(*pnt && *pnt == ' ') pnt++;
+    if(strncmp(blacklist[i].vendor, pnt,
               strlen(blacklist[i].vendor))) continue;
-    if(strncmp(blacklist[i].model, &response_data[16],
+    pnt = &response_data[16];
+    while(*pnt && *pnt == ' ') pnt++;
+    if(strncmp(blacklist[i].model, pnt,
               strlen(blacklist[i].model))) continue;
     return 1;
   };   
index 5f52c7805ac52296b1869746a83420379542628e..a09d4a0056f6ca9030fac36aa08733f46661fc1f 100644 (file)
@@ -101,9 +101,11 @@ static const Signature signatures[] = {
        I believe it.
 */
 
-{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 5, 46, FD},
+{"FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88",5,48, FD},
+{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
+{"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FD},
 #endif
 }
 ;
@@ -251,6 +253,7 @@ static int should_reconnect = 0;
 static void seagate_reconnect_intr (int unused)
        {
        int temp;
+       Scsi_Cmnd * SCtmp;
 
 /* enable all other interrupts. */     
        sti();
@@ -283,9 +286,10 @@ static void seagate_reconnect_intr (int unused)
                                hostno, temp);
 #endif
                                if(!SCint) panic("SCint == NULL in seagate");
-                               SCint->result = temp;
-                               done_fn (SCint);
+                               SCtmp = SCint;
                                SCint = NULL;
+                               SCtmp->result = temp;
+                               done_fn (SCtmp);
                                }
                        else
                                printk("done_fn() not defined.\n");
@@ -297,12 +301,19 @@ static void seagate_reconnect_intr (int unused)
  * The seagate_st0x_queue_command() function provides a queued interface
  * to the seagate SCSI driver.  Basically, it just passes control onto the
  * seagate_command() function, after fixing it so that the done_fn()
- * is set to the one passed to the function.
+ * is set to the one passed to the function.  We have to be very careful,
+ * because there are some commands on some devices that do not disconnect,
+ * and if we simply call the done_fn when the command is done then another
+ * command is started and queue_command is called again...  We end up
+ * overflowing the kernel stack, and this tends not to be such a good idea.
  */
 
+static int recursion_depth = 0;
+
 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
        {
        int result;
+       Scsi_Cmnd * SCtmp;
 
        done_fn = done;
        current_target = SCpnt->target;
@@ -311,20 +322,24 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt,  void (*done)(Scsi_Cmnd *))
        current_data = SCpnt->request_buffer;
        current_bufflen = SCpnt->request_bufflen;
        SCint = SCpnt;
-
-       result = internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
-                                  SCpnt->request_bufflen, 
-                                  CAN_RECONNECT);
-       if (msg_byte(result) == DISCONNECT)
-               return 0;
-       else 
-               {
-                 SCpnt->result = result;
-               done_fn (SCpnt); 
-               SCint = NULL;
-               return 1; 
-               }
-       }
+       if(recursion_depth) {
+         return 0;
+       };
+       recursion_depth++;
+       do{
+         
+         result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
+                                    SCint->request_bufflen, 
+                                    CAN_RECONNECT);
+         if (msg_byte(result) == DISCONNECT)  break;
+         SCtmp = SCint;
+         SCint = NULL;
+         SCtmp->result = result;
+         done_fn (SCtmp);
+       } while(SCint);
+       recursion_depth--;
+       return 0;
+      }
 
 int seagate_st0x_command (Scsi_Cmnd * SCpnt)
        {
index a64e035d95d4134cbb7872e0d2a65dc677f493bd..e7f6255e348e32d6d2e0f5f1d19d62b1d8843294 100644 (file)
@@ -14,6 +14,10 @@ long soundcard_init(long mem_start)
        return mem_start;
 }
 
+void sound_mem_init(void)
+{
+}
+
 #ifdef CONFIG_SOUND
 #error The Sound Driver not installed.
 #endif
index 64dfaebe42c84b276d8750a3ea40e3e62608557e..455c2bbb973a60360ed7f1560e71a0130ad513a5 100644 (file)
@@ -965,6 +965,8 @@ static void release_dev(int dev, struct file * filp)
                tty_termios[dev] = NULL;
                kfree_s(tp, sizeof(struct termios));
        }
+       if (tty == redirect || o_tty == redirect)
+               redirect = NULL;
        free_page((unsigned long) tty);
        if (o_tty)
                free_page((unsigned long) o_tty);
index 5b08cffcf8719bf2c3ceaac43e7631449cb2ed55..eca31b8d2fb82093bd38608e84b180ba33a8bf79 100644 (file)
@@ -258,7 +258,9 @@ int sys_ptrace(long request, long pid, long addr, long data)
                child->signal = 0;
                return 0;
        }
-       if (!(child->flags & PF_PTRACED) || child->state != TASK_STOPPED)
+       if (!(child->flags & PF_PTRACED))
+               return -ESRCH;
+       if (child->state != TASK_STOPPED && request != PTRACE_DETACH)
                return -ESRCH;
        if (child->p_pptr != current)
                return -ESRCH;
index e74712e55e4f48629e6316696852683a059dc5ad..19a961e81ade5d198ff80e900ef715222c430f66 100644 (file)
@@ -40,6 +40,8 @@
 
 unsigned long high_memory = 0;
 
+extern void sound_mem_init(void);
+
 int nr_free_pages = 0;
 unsigned long free_page_list = 0;
 /*
@@ -931,6 +933,7 @@ void mem_init(unsigned long start_low_mem,
                mem_map[MAP_NR(start_mem)] = 0;
                start_mem += 4096;
        }
+       sound_mem_init();
        free_page_list = 0;
        nr_free_pages = 0;
        for (tmp = 0 ; tmp < end_mem ; tmp += 4096) {
index 85e615c0ad45a9cb6edfa04f63a9a26f10c8ba03..ee3388fda7ce7a62b3f5355498469be8cc17b2da 100644 (file)
@@ -221,13 +221,13 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
 
   */
 
-static struct sk_buff *backlog = NULL;
+static volatile struct sk_buff * volatile backlog = NULL;
 
 int
 dev_rint(unsigned char *buff, long len, int flags,
         struct device * dev)
 {
-   struct sk_buff *skb=NULL;
+   volatile struct sk_buff *skb=NULL;
    unsigned char *to;
    int amount;
 
@@ -247,7 +247,7 @@ dev_rint(unsigned char *buff, long len, int flags,
         }
        skb->lock = 0;
        skb->mem_len = sizeof (*skb) + len;
-       skb->mem_addr = skb;
+       skb->mem_addr = (struct sk_buff *)skb;
        /* first we copy the packet into a buffer, and save it for later. */
 
        to = (unsigned char *)(skb+1);
@@ -272,16 +272,16 @@ dev_rint(unsigned char *buff, long len, int flags,
    cli();
    if (backlog == NULL)
      {
-       skb->prev = skb;
-       skb->next = skb;
+       skb->prev = (struct sk_buff *)skb;
+       skb->next = (struct sk_buff *)skb;
        backlog = skb;
      }
    else
      {
-       skb ->prev = backlog->prev;
-       skb->next = backlog;
-       skb->next->prev = skb;
-       skb->prev->next = skb;
+       skb->prev = backlog->prev;
+       skb->next = (struct sk_buff *)backlog;
+       skb->next->prev = (struct sk_buff *)skb;
+       skb->prev->next = (struct sk_buff *)skb;
      }
    sti();
    
@@ -294,11 +294,11 @@ dev_rint(unsigned char *buff, long len, int flags,
 void
 inet_bh(void *tmp)
 {
-  struct sk_buff *skb;
+  volatile struct sk_buff *skb;
   struct packet_type *ptype;
   unsigned short type;
   unsigned char flag =0;
-  static int in_bh=0;
+  static volatile int in_bh=0;
 
   cli();
   if (in_bh != 0)
@@ -331,7 +331,7 @@ inet_bh(void *tmp)
        skb->len -= skb->dev->hard_header_len;
 
        /* convert the type to an ethernet type. */
-       type = skb->dev->type_trans (skb, skb->dev);
+       type = skb->dev->type_trans ((struct sk_buff *)skb, skb->dev);
 
        /* if there get to be a lot of types we should changes this to
          a bunch of linked lists like we do for ip protocols. */
@@ -355,7 +355,7 @@ inet_bh(void *tmp)
                 }
               else
                 {
-                  skb2 = skb;
+                  skb2 = (struct sk_buff *)skb;
                   flag = 1;
                 }
               
@@ -366,7 +366,7 @@ inet_bh(void *tmp)
        if (!flag)
         {
           PRINTK (("discarding packet type = %X\n", type));
-          kfree_skb (skb, FREE_READ);
+          kfree_skb ((struct sk_buff *)skb, FREE_READ);
         }
      }
   in_bh = 0;
index 23f62f46775e5cac39b85cef94ce7d9d9152b877..eb9c7975b0b84922d064ff9e9842f239552d5053 100644 (file)
@@ -2951,7 +2951,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
        {
           sk->err = ECONNRESET;
           sk->state = TCP_CLOSE;
-          sk->state = SHUTDOWN_MASK;
+          sk->shutdown = SHUTDOWN_MASK;
           tcp_reset (daddr, saddr,  th, sk->prot, opt,dev);
           if (!sk->dead)
             {
@@ -3070,7 +3070,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
        {
          sk->err = ECONNREFUSED ;
          sk->state = TCP_CLOSE;
-         sk->state = SHUTDOWN_MASK;
+         sk->shutdown = SHUTDOWN_MASK;
          if (!sk->dead)
            {
              wake_up (sk->sleep);