diff options
author | Linus Torvalds <torvalds@klaava.Helsinki.FI> | 1993-01-22 12:52:47 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:12 -0400 |
commit | b75fb8468bb5353db99f69805408db991ac0ed39 (patch) | |
tree | 69196f6614fcca6352ab66b02c1d70caf1b89f36 | |
parent | 184df1a3d0f315a5cf4836d1098d6d9531268e02 (diff) | |
download | archive-b75fb8468bb5353db99f69805408db991ac0ed39.tar.gz |
Re: Freeze up on Xv0.99-pl4
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
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | boot/head.S | 6 | ||||
-rw-r--r-- | boot/setup.S | 43 | ||||
-rw-r--r-- | fs/locks.c | 10 | ||||
-rw-r--r-- | fs/minix/bitmap.c | 14 | ||||
-rw-r--r-- | fs/pipe.c | 6 | ||||
-rw-r--r-- | fs/proc/array.c | 11 | ||||
-rw-r--r-- | fs/proc/root.c | 5 | ||||
-rw-r--r-- | fs/super.c | 34 | ||||
-rw-r--r-- | include/asm/bitops.h | 28 | ||||
-rw-r--r-- | include/asm/irq.h | 30 | ||||
-rw-r--r-- | include/linux/fcntl.h | 4 | ||||
-rw-r--r-- | include/linux/fs.h | 16 | ||||
-rw-r--r-- | include/linux/sched.h | 5 | ||||
-rw-r--r-- | include/linux/tasks.h | 9 | ||||
-rw-r--r-- | kernel/blk_drv/scsi/scsi.c | 9 | ||||
-rw-r--r-- | kernel/blk_drv/scsi/seagate.c | 51 | ||||
-rw-r--r-- | kernel/chr_drv/sound/sound_stub.c | 4 | ||||
-rw-r--r-- | kernel/chr_drv/tty_io.c | 2 | ||||
-rw-r--r-- | kernel/ptrace.c | 4 | ||||
-rw-r--r-- | mm/memory.c | 3 | ||||
-rw-r--r-- | net/tcp/dev.c | 28 | ||||
-rw-r--r-- | net/tcp/tcp.c | 4 |
23 files changed, 232 insertions, 107 deletions
@@ -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 diff --git a/boot/head.S b/boot/head.S index 7497241..8cf5c4a 100644 --- a/boot/head.S +++ b/boot/head.S @@ -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 */ diff --git a/boot/setup.S b/boot/setup.S index 0fa8efc..1bebecd 100644 --- a/boot/setup.S +++ b/boot/setup.S @@ -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 @@ -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; } diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 154b7e2..93466b2 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -12,24 +12,14 @@ #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" \ @@ -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) diff --git a/fs/proc/array.c b/fs/proc/array.c index e622571..c552584 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -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; diff --git a/fs/proc/root.c b/fs/proc/root.c index a52204e..3dbec2d 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -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; @@ -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); diff --git a/include/asm/bitops.h b/include/asm/bitops.h index 7140009..b7a8833 100644 --- a/include/asm/bitops.h +++ b/include/asm/bitops.h @@ -11,21 +11,30 @@ * * 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; } diff --git a/include/asm/irq.h b/include/asm/irq.h index 3d16fbb..ea8685c 100644 --- a/include/asm/irq.h +++ b/include/asm/irq.h @@ -59,8 +59,16 @@ "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" \ @@ -69,7 +77,10 @@ "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" \ @@ -81,12 +92,18 @@ "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 diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h index 8b0721a..cea4f5f 100644 --- a/include/linux/fcntl.h +++ b/include/linux/fcntl.h @@ -34,6 +34,10 @@ #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; diff --git a/include/linux/fs.h b/include/linux/fs.h index c7b5744..2c4536e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -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) diff --git a/include/linux/sched.h b/include/linux/sched.h index e6fdbfb..dcdb86f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -12,10 +12,7 @@ #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 index 0000000..0607d87 --- /dev/null +++ b/include/linux/tasks.h @@ -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 diff --git a/kernel/blk_drv/scsi/scsi.c b/kernel/blk_drv/scsi/scsi.c index a00c284..3ef91be 100644 --- a/kernel/blk_drv/scsi/scsi.c +++ b/kernel/blk_drv/scsi/scsi.c @@ -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; }; diff --git a/kernel/blk_drv/scsi/seagate.c b/kernel/blk_drv/scsi/seagate.c index 5f52c78..a09d4a0 100644 --- a/kernel/blk_drv/scsi/seagate.c +++ b/kernel/blk_drv/scsi/seagate.c @@ -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) { diff --git a/kernel/chr_drv/sound/sound_stub.c b/kernel/chr_drv/sound/sound_stub.c index a64e035..e7f6255 100644 --- a/kernel/chr_drv/sound/sound_stub.c +++ b/kernel/chr_drv/sound/sound_stub.c @@ -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 diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c index 64dfaeb..455c2bb 100644 --- a/kernel/chr_drv/tty_io.c +++ b/kernel/chr_drv/tty_io.c @@ -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); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 5b08cff..eca31b8 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -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; diff --git a/mm/memory.c b/mm/memory.c index e74712e..19a961e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -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) { diff --git a/net/tcp/dev.c b/net/tcp/dev.c index 85e615c..ee3388f 100644 --- a/net/tcp/dev.c +++ b/net/tcp/dev.c @@ -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; diff --git a/net/tcp/tcp.c b/net/tcp/tcp.c index 23f62f4..eb9c797 100644 --- a/net/tcp/tcp.c +++ b/net/tcp/tcp.c @@ -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); |