Commit c9e69190 authored by Linus Torvalds's avatar Linus Torvalds

[PATCH] Linux-0.99.4 (January 20, 1993)

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
parent b0755ed8
all: Version Image
# #
# Make "config" the default target if there is no configuration file or # Make "config" the default target if there is no configuration file or
# "depend" the target if there is no top-level dependency information. # "depend" the target if there is no top-level dependency information.
...@@ -123,10 +126,8 @@ KERNELHDRS =/usr/src/linux/include ...@@ -123,10 +126,8 @@ KERNELHDRS =/usr/src/linux/include
.c.o: .c.o:
$(CC) $(CFLAGS) -c -o $*.o $< $(CC) $(CFLAGS) -c -o $*.o $<
all: Version Image
Version: dummy Version: dummy
rm tools/version.h rm -f tools/version.h
lilo: $(CONFIGURE) Image lilo: $(CONFIGURE) Image
if [ -f /vmlinux ]; then mv /vmlinux /vmlinux.old; fi if [ -f /vmlinux ]; then mv /vmlinux /vmlinux.old; fi
...@@ -140,9 +141,11 @@ config: ...@@ -140,9 +141,11 @@ config:
linuxsubdirs: dummy linuxsubdirs: dummy
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done @for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
tools/./version.h: tools/version.h
tools/version.h: $(CONFIGURE) Makefile tools/version.h: $(CONFIGURE) Makefile
@./makever.sh @./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 UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
...@@ -164,7 +167,7 @@ tools/build: $(CONFIGURE) tools/build.c ...@@ -164,7 +167,7 @@ tools/build: $(CONFIGURE) tools/build.c
boot/head.o: $(CONFIGURE) boot/head.s 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 $(CPP) -traditional boot/head.S -o boot/head.s
tools/version.o: tools/version.c tools/version.h tools/version.o: tools/version.c tools/version.h
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
.globl _empty_bad_page_table .globl _empty_bad_page_table
.globl _tmp_floppy_area,_floppy_track_buffer .globl _tmp_floppy_area,_floppy_track_buffer
#include <linux/tasks.h>
/* /*
* swapper_pg_dir is the main page directory, address 0x00001000 * swapper_pg_dir is the main page directory, address 0x00001000
*/ */
...@@ -266,7 +268,7 @@ _idt: ...@@ -266,7 +268,7 @@ _idt:
.align 4 .align 4
.word 0 .word 0
gdt_descr: gdt_descr:
.word 256*8-1 .word (4+2*NR_TASKS)*8-1
.long 0xc0000000+_gdt .long 0xc0000000+_gdt
/* /*
...@@ -279,4 +281,4 @@ _gdt: ...@@ -279,4 +281,4 @@ _gdt:
.quad 0xc0c39a000000ffff /* 1GB at 0xC0000000 */ .quad 0xc0c39a000000ffff /* 1GB at 0xC0000000 */
.quad 0xc0c392000000ffff /* 1GB */ .quad 0xc0c392000000ffff /* 1GB */
.quad 0x0000000000000000 /* TEMPORARY - don't use */ .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 */
...@@ -227,9 +227,14 @@ end_move: ...@@ -227,9 +227,14 @@ end_move:
! things as simple as possible, we do no register set-up or anything, ! 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 ! we let the gnu-compiled 32-bit programs do that. We just jump to
! absolute address 0x00000, in 32-bit protected mode. ! 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 mov ax,#0x0001 ! protected mode (PE) bit
lmsw ax ! This is it! lmsw ax ! This is it!
jmp flush_instr
flush_instr:
jmpi 0,8 ! jmp offset 0 of segment 8 (cs) jmpi 0,8 ! jmp offset 0 of segment 8 (cs)
! This routine checks that the keyboard command queue is empty ! This routine checks that the keyboard command queue is empty
...@@ -258,8 +263,7 @@ getkey: ...@@ -258,8 +263,7 @@ getkey:
! !
! Flush the keyboard buffer ! Flush the keyboard buffer
! !
flush: in al,#0x60 flush: call getkey
.word 0x00eb,0x00eb
cmp al,#0x82 cmp al,#0x82
jae flush jae flush
ret ret
...@@ -321,8 +325,7 @@ svga: cld ...@@ -321,8 +325,7 @@ svga: cld
jne nf1280 jne nf1280
lea si,dscf1280 lea si,dscf1280
lea di,mof1280 lea di,mof1280
lea cx,selmod br selmod
jmp cx
nf1280: cld nf1280: cld
lea si,idati ! Check ATI 'clues' lea si,idati ! Check ATI 'clues'
mov di,#0x31 mov di,#0x31
...@@ -332,8 +335,7 @@ nf1280: cld ...@@ -332,8 +335,7 @@ nf1280: cld
jne noati jne noati
lea si,dscati lea si,dscati
lea di,moati lea di,moati
lea cx,selmod br selmod
jmp cx
noati: mov ax,#0x200f ! Check Ahead 'clues' noati: mov ax,#0x200f ! Check Ahead 'clues'
mov dx,#0x3ce mov dx,#0x3ce
out dx,ax out dx,ax
...@@ -345,8 +347,7 @@ noati: mov ax,#0x200f ! Check Ahead 'clues' ...@@ -345,8 +347,7 @@ noati: mov ax,#0x200f ! Check Ahead 'clues'
jne noahed jne noahed
isahed: lea si,dscahead isahed: lea si,dscahead
lea di,moahead lea di,moahead
lea cx,selmod br selmod
jmp cx
noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues' noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
in al,dx in al,dx
or al,#0x10 or al,#0x10
...@@ -362,8 +363,7 @@ noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues' ...@@ -362,8 +363,7 @@ noahed: mov dx,#0x3c3 ! Check Chips & Tech. 'clues'
jne nocant jne nocant
lea si,dsccandt lea si,dsccandt
lea di,mocandt lea di,mocandt
lea cx,selmod br selmod
jmp cx
nocant: mov dx,#0x3d4 ! Check Cirrus 'clues' nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
mov al,#0x0c mov al,#0x0c
out dx,al out dx,al
...@@ -401,8 +401,7 @@ nocant: mov dx,#0x3d4 ! Check Cirrus 'clues' ...@@ -401,8 +401,7 @@ nocant: mov dx,#0x3d4 ! Check Cirrus 'clues'
call rst3d4 call rst3d4
lea si,dsccirrus lea si,dsccirrus
lea di,mocirrus lea di,mocirrus
lea cx,selmod br selmod
jmp cx
rst3d4: mov dx,#0x3d4 rst3d4: mov dx,#0x3d4
mov al,bl mov al,bl
xor ah,ah xor ah,ah
...@@ -423,8 +422,7 @@ nocirr: call rst3d4 ! Check Everex 'clues' ...@@ -423,8 +422,7 @@ nocirr: call rst3d4 ! Check Everex 'clues'
je istrid je istrid
lea si,dsceverex lea si,dsceverex
lea di,moeverex lea di,moeverex
lea cx,selmod br selmod
jmp cx
istrid: lea cx,ev2tri istrid: lea cx,ev2tri
jmp cx jmp cx
noevrx: lea si,idgenoa ! Check Genoa 'clues' noevrx: lea si,idgenoa ! Check Genoa 'clues'
...@@ -446,8 +444,7 @@ l1: inc si ...@@ -446,8 +444,7 @@ l1: inc si
jne nogen jne nogen
lea si,dscgenoa lea si,dscgenoa
lea di,mogenoa lea di,mogenoa
lea cx,selmod br selmod
jmp cx
nogen: cld nogen: cld
lea si,idoakvga lea si,idoakvga
mov di,#0x08 mov di,#0x08
...@@ -457,8 +454,7 @@ nogen: cld ...@@ -457,8 +454,7 @@ nogen: cld
jne nooak jne nooak
lea si,dscoakvga lea si,dscoakvga
lea di,mooakvga lea di,mooakvga
lea cx,selmod br selmod
jmp cx
nooak: cld nooak: cld
lea si,idparadise ! Check Paradise 'clues' lea si,idparadise ! Check Paradise 'clues'
mov di,#0x7d mov di,#0x7d
...@@ -468,8 +464,7 @@ nooak: cld ...@@ -468,8 +464,7 @@ nooak: cld
jne nopara jne nopara
lea si,dscparadise lea si,dscparadise
lea di,moparadise lea di,moparadise
lea cx,selmod br selmod
jmp cx
nopara: mov dx,#0x3c4 ! Check Trident 'clues' nopara: mov dx,#0x3c4 ! Check Trident 'clues'
mov al,#0x0e mov al,#0x0e
out dx,al out dx,al
...@@ -492,8 +487,7 @@ clrb2: out dx,al ...@@ -492,8 +487,7 @@ clrb2: out dx,al
jne notrid jne notrid
ev2tri: lea si,dsctrident ev2tri: lea si,dsctrident
lea di,motrident lea di,motrident
lea cx,selmod jmp selmod
jmp cx
notrid: mov dx,#0x3cd ! Check Tseng 'clues' notrid: mov dx,#0x3cd ! Check Tseng 'clues'
in al,dx ! Could things be this simple ! :-) in al,dx ! Could things be this simple ! :-)
mov bl,al mov bl,al
...@@ -507,8 +501,7 @@ notrid: mov dx,#0x3cd ! Check Tseng 'clues' ...@@ -507,8 +501,7 @@ notrid: mov dx,#0x3cd ! Check Tseng 'clues'
jne notsen jne notsen
lea si,dsctseng lea si,dsctseng
lea di,motseng lea di,motseng
lea cx,selmod jmp selmod
jmp cx
notsen: mov dx,#0x3cc ! Check Video7 'clues' notsen: mov dx,#0x3cc ! Check Video7 'clues'
in al,dx in al,dx
mov dx,#0x3b4 mov dx,#0x3b4
......
...@@ -110,6 +110,16 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l) ...@@ -110,6 +110,16 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
if (!(filp->f_mode & 2)) if (!(filp->f_mode & 2))
return -EBADF; return -EBADF;
break; 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 : case F_UNLCK :
break; break;
} }
......
...@@ -12,24 +12,14 @@ ...@@ -12,24 +12,14 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <asm/bitops.h>
#define clear_block(addr) \ #define clear_block(addr) \
__asm__("cld\n\t" \ __asm__("cld\n\t" \
"rep\n\t" \ "rep\n\t" \
"stosl" \ "stosl" \
::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di") ::"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) ({ \ #define find_first_zero(addr) ({ \
int __res; \ int __res; \
__asm__("cld\n" \ __asm__("cld\n" \
......
...@@ -40,7 +40,11 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c ...@@ -40,7 +40,11 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
buf += chars; buf += chars;
} }
wake_up(& PIPE_WRITE_WAIT(*inode)); 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) static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
......
...@@ -59,6 +59,14 @@ static int get_meminfo(char * buffer) ...@@ -59,6 +59,14 @@ static int get_meminfo(char * buffer)
i.totalswap, i.totalswap-i.freeswap, i.freeswap); 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) static struct task_struct ** get_task(pid_t pid)
{ {
struct task_struct ** p; struct task_struct ** p;
...@@ -296,6 +304,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c ...@@ -296,6 +304,9 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
case 4: case 4:
length = get_meminfo(page); length = get_meminfo(page);
break; break;
case 6:
length = get_version(page);
break;
case 9: case 9:
length = get_env(pid, page); length = get_env(pid, page);
break; break;
......
...@@ -56,7 +56,8 @@ static struct proc_dir_entry root_dir[] = { ...@@ -56,7 +56,8 @@ static struct proc_dir_entry root_dir[] = {
{ 3,6,"uptime" }, { 3,6,"uptime" },
{ 4,7,"meminfo" }, { 4,7,"meminfo" },
{ 5,4,"kmsg" }, { 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]))) #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, ...@@ -83,7 +84,7 @@ static int proc_lookuproot(struct inode * dir,const char * name, int len,
*result = dir; *result = dir;
return 0; return 0;
} }
if (ino == 6) /* self modifying inode ... */ if (ino == 7) /* self modifying inode ... */
ino = (current->pid << 16) + 2; ino = (current->pid << 16) + 2;
} else { } else {
pid = 0; pid = 0;
......
...@@ -310,6 +310,32 @@ static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * ...@@ -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 */ 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 * 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). * 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, ...@@ -337,6 +363,10 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
if (!suser()) if (!suser())
return -EPERM; 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) { if (type) {
for (i = 0 ; i < 100 ; i++) for (i = 0 ; i < 100 ; i++)
if (!(tmp[i] = get_fs_byte(type++))) if (!(tmp[i] = get_fs_byte(type++)))
...@@ -378,8 +408,8 @@ int sys_mount(char * dev_name, char * dir_name, char * type, ...@@ -378,8 +408,8 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
return retval; return retval;
} }
} }
if ((new_flags & 0xffff0000) == 0xC0ED0000) { if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
flags = new_flags & 0xffff; flags = new_flags & ~MS_MGC_MSK;
if (data) { if (data) {
if ((unsigned long) data >= TASK_SIZE) { if ((unsigned long) data >= TASK_SIZE) {
iput(inode); iput(inode);
......
...@@ -11,21 +11,30 @@ ...@@ -11,21 +11,30 @@
* *
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). * 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; char ok;
__asm__ __volatile__("btsl %1,%2\n\tsetb %0": __asm__ __volatile__("btsl %2,%1\n\tsetb %0"
"=q" (ok):"r" (nr),"m" (*(addr))); :"=q" (ok),"=m" (ADDR)
:"r" (nr));
return ok; return ok;
} }
extern inline int clear_bit(int nr, int * addr) extern inline int clear_bit(int nr, void * addr)
{ {
char ok; char ok;
__asm__ __volatile__("btrl %1,%2\n\tsetnb %0": __asm__ __volatile__("btrl %2,%1\n\tsetnb %0"
"=q" (ok):"r" (nr),"m" (*(addr))); :"=q" (ok),"=m" (ADDR)
:"r" (nr));
return ok; return ok;
} }
...@@ -33,12 +42,13 @@ extern inline int clear_bit(int nr, int * addr) ...@@ -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 routine doesn't need to be atomic, but it's faster to code it
* this way. * this way.
*/ */
extern inline int test_bit(int nr, int * addr) extern inline int test_bit(int nr, void * addr)
{ {
char ok; char ok;
__asm__ __volatile__("btl %1,%2\n\tsetb %0": __asm__ __volatile__("btl %2,%1\n\tsetb %0"
"=q" (ok):"r" (nr),"m" (*(addr))); :"=q" (ok)
:"m" (ADDR),"r" (nr));
return ok; return ok;
} }
......
...@@ -59,8 +59,16 @@ ...@@ -59,8 +59,16 @@
"pop %es\n\t" \ "pop %es\n\t" \
"iret" "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) \ #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" \ "movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t" \ "outb %al,$0x21\n\t" \
"jmp 1f\n" \ "jmp 1f\n" \
...@@ -69,7 +77,10 @@ ...@@ -69,7 +77,10 @@
"outb %al,$0x20\n\t" "outb %al,$0x20\n\t"
#define ACK_SECOND(mask) \ #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" \ "movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t" \ "outb %al,$0xA1\n\t" \
"jmp 1f\n" \ "jmp 1f\n" \
...@@ -81,12 +92,18 @@ ...@@ -81,12 +92,18 @@
"1:\toutb %al,$0x20\n\t" "1:\toutb %al,$0x20\n\t"
#define UNBLK_FIRST(mask) \ #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" \ "movb _cache_21,%al\n\t" \
"outb %al,$0x21\n\t" "outb %al,$0x21\n\t"
#define UNBLK_SECOND(mask) \ #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" \ "movb _cache_A1,%al\n\t" \
"outb %al,$0xA1\n\t" "outb %al,$0xA1\n\t"
...@@ -159,9 +176,8 @@ __asm__( \ ...@@ -159,9 +176,8 @@ __asm__( \
RESTORE_MOST \ RESTORE_MOST \
"\n\n.align 4\n" \ "\n\n.align 4\n" \
"_bad_IRQ" #nr "_interrupt:\n\t" \ "_bad_IRQ" #nr "_interrupt:\n\t" \
"pushl %eax\n\t" \ SAVE_MOST \
ACK_##chip(mask) \ ACK_##chip(mask) \
"popl %eax\n\t" \ RESTORE_MOST);
"iret");
#endif #endif
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
#define F_WRLCK 1 #define F_WRLCK 1
#define F_UNLCK 2 #define F_UNLCK 2
/* For bsd flock () */
#define F_EXLCK 4 /* or 3 */
#define F_SHLCK 8 /* or 4 */
/* Once again - not implemented, but ... */ /* Once again - not implemented, but ... */
struct flock { struct flock {
short l_type; short l_type;
......
...@@ -88,14 +88,28 @@ extern unsigned long inode_init(unsigned long start, unsigned long end); ...@@ -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_NODEV 4 /* disallow access to device special files */
#define MS_NOEXEC 8 /* disallow program execution */ #define MS_NOEXEC 8 /* disallow program execution */
#define MS_SYNC 16 /* writes are synced at once */ #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 * 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 * 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 * possible to overrride it sevelctively if you really wanted to with some
* ioctl() that is not currently implemented. * 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_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
......
...@@ -12,10 +12,7 @@ ...@@ -12,10 +12,7 @@
#define HZ 100 #define HZ 100
/* #include <linux/tasks.h>
* This is the maximum nr of tasks - change it if you need to
*/
#define NR_TASKS 64
/* /*
* User space process size: 3GB. This is hardcoded into a few places, * User space process size: 3GB. This is hardcoded into a few places,
......
#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
...@@ -113,11 +113,16 @@ static struct blist blacklist[] = ...@@ -113,11 +113,16 @@ static struct blist blacklist[] =
static int blacklisted(char * response_data){ static int blacklisted(char * response_data){
int i = 0; int i = 0;
char * pnt;
for(i=0; 1; i++){ for(i=0; 1; i++){
if(blacklist[i].vendor == NULL) return 0; 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; 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; strlen(blacklist[i].model))) continue;
return 1; return 1;
}; };
......
...@@ -101,9 +101,11 @@ static const Signature signatures[] = { ...@@ -101,9 +101,11 @@ static const Signature signatures[] = {
I believe it. 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 V6.0105/31/90",5, 47, FD},
{"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, 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 #endif
} }
; ;
...@@ -251,6 +253,7 @@ static int should_reconnect = 0; ...@@ -251,6 +253,7 @@ static int should_reconnect = 0;
static void seagate_reconnect_intr (int unused) static void seagate_reconnect_intr (int unused)
{ {
int temp; int temp;
Scsi_Cmnd * SCtmp;
/* enable all other interrupts. */ /* enable all other interrupts. */
sti(); sti();
...@@ -283,9 +286,10 @@ static void seagate_reconnect_intr (int unused) ...@@ -283,9 +286,10 @@ static void seagate_reconnect_intr (int unused)
hostno, temp); hostno, temp);
#endif #endif
if(!SCint) panic("SCint == NULL in seagate"); if(!SCint) panic("SCint == NULL in seagate");
SCint->result = temp; SCtmp = SCint;
done_fn (SCint);
SCint = NULL; SCint = NULL;
SCtmp->result = temp;
done_fn (SCtmp);
} }
else else
printk("done_fn() not defined.\n"); printk("done_fn() not defined.\n");
...@@ -297,12 +301,19 @@ static void seagate_reconnect_intr (int unused) ...@@ -297,12 +301,19 @@ static void seagate_reconnect_intr (int unused)
* The seagate_st0x_queue_command() function provides a queued interface * The seagate_st0x_queue_command() function provides a queued interface
* to the seagate SCSI driver. Basically, it just passes control onto the * to the seagate SCSI driver. Basically, it just passes control onto the
* seagate_command() function, after fixing it so that the done_fn() * 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 seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{ {
int result; int result;
Scsi_Cmnd * SCtmp;
done_fn = done; done_fn = done;
current_target = SCpnt->target; current_target = SCpnt->target;
...@@ -311,20 +322,24 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -311,20 +322,24 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
current_data = SCpnt->request_buffer; current_data = SCpnt->request_buffer;
current_bufflen = SCpnt->request_bufflen; current_bufflen = SCpnt->request_bufflen;
SCint = SCpnt; SCint = SCpnt;
if(recursion_depth) {
result = internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer, return 0;
SCpnt->request_bufflen, };
CAN_RECONNECT); recursion_depth++;
if (msg_byte(result) == DISCONNECT) do{
return 0;
else result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
{ SCint->request_bufflen,
SCpnt->result = result; CAN_RECONNECT);
done_fn (SCpnt); if (msg_byte(result) == DISCONNECT) break;
SCint = NULL; SCtmp = SCint;
return 1; SCint = NULL;
} SCtmp->result = result;
} done_fn (SCtmp);
} while(SCint);
recursion_depth--;
return 0;
}
int seagate_st0x_command (Scsi_Cmnd * SCpnt) int seagate_st0x_command (Scsi_Cmnd * SCpnt)
{ {
......
...@@ -14,6 +14,10 @@ long soundcard_init(long mem_start) ...@@ -14,6 +14,10 @@ long soundcard_init(long mem_start)
return mem_start; return mem_start;
} }
void sound_mem_init(void)
{
}
#ifdef CONFIG_SOUND #ifdef CONFIG_SOUND
#error The Sound Driver not installed. #error The Sound Driver not installed.
#endif #endif
...@@ -965,6 +965,8 @@ static void release_dev(int dev, struct file * filp) ...@@ -965,6 +965,8 @@ static void release_dev(int dev, struct file * filp)
tty_termios[dev] = NULL; tty_termios[dev] = NULL;
kfree_s(tp, sizeof(struct termios)); kfree_s(tp, sizeof(struct termios));
} }
if (tty == redirect || o_tty == redirect)
redirect = NULL;
free_page((unsigned long) tty); free_page((unsigned long) tty);
if (o_tty) if (o_tty)
free_page((unsigned long) o_tty); free_page((unsigned long) o_tty);
......
...@@ -258,7 +258,9 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -258,7 +258,9 @@ int sys_ptrace(long request, long pid, long addr, long data)
child->signal = 0; child->signal = 0;
return 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; return -ESRCH;
if (child->p_pptr != current) if (child->p_pptr != current)
return -ESRCH; return -ESRCH;
......
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
unsigned long high_memory = 0; unsigned long high_memory = 0;
extern void sound_mem_init(void);
int nr_free_pages = 0; int nr_free_pages = 0;
unsigned long free_page_list = 0; unsigned long free_page_list = 0;
/* /*
...@@ -931,6 +933,7 @@ void mem_init(unsigned long start_low_mem, ...@@ -931,6 +933,7 @@ void mem_init(unsigned long start_low_mem,
mem_map[MAP_NR(start_mem)] = 0; mem_map[MAP_NR(start_mem)] = 0;
start_mem += 4096; start_mem += 4096;
} }
sound_mem_init();
free_page_list = 0; free_page_list = 0;
nr_free_pages = 0; nr_free_pages = 0;
for (tmp = 0 ; tmp < end_mem ; tmp += 4096) { for (tmp = 0 ; tmp < end_mem ; tmp += 4096) {
......
...@@ -221,13 +221,13 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri) ...@@ -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 int
dev_rint(unsigned char *buff, long len, int flags, dev_rint(unsigned char *buff, long len, int flags,
struct device * dev) struct device * dev)
{ {
struct sk_buff *skb=NULL; volatile struct sk_buff *skb=NULL;
unsigned char *to; unsigned char *to;
int amount; int amount;
...@@ -247,7 +247,7 @@ dev_rint(unsigned char *buff, long len, int flags, ...@@ -247,7 +247,7 @@ dev_rint(unsigned char *buff, long len, int flags,
} }
skb->lock = 0; skb->lock = 0;
skb->mem_len = sizeof (*skb) + len; 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. */ /* first we copy the packet into a buffer, and save it for later. */
to = (unsigned char *)(skb+1); to = (unsigned char *)(skb+1);
...@@ -272,16 +272,16 @@ dev_rint(unsigned char *buff, long len, int flags, ...@@ -272,16 +272,16 @@ dev_rint(unsigned char *buff, long len, int flags,
cli(); cli();
if (backlog == NULL) if (backlog == NULL)
{ {
skb->prev = skb; skb->prev = (struct sk_buff *)skb;
skb->next = skb; skb->next = (struct sk_buff *)skb;
backlog = skb; backlog = skb;
} }
else else
{ {
skb ->prev = backlog->prev; skb->prev = backlog->prev;
skb->next = backlog; skb->next = (struct sk_buff *)backlog;
skb->next->prev = skb; skb->next->prev = (struct sk_buff *)skb;
skb->prev->next = skb; skb->prev->next = (struct sk_buff *)skb;
} }
sti(); sti();
...@@ -294,11 +294,11 @@ dev_rint(unsigned char *buff, long len, int flags, ...@@ -294,11 +294,11 @@ dev_rint(unsigned char *buff, long len, int flags,
void void
inet_bh(void *tmp) inet_bh(void *tmp)
{ {
struct sk_buff *skb; volatile struct sk_buff *skb;
struct packet_type *ptype; struct packet_type *ptype;
unsigned short type; unsigned short type;
unsigned char flag =0; unsigned char flag =0;
static int in_bh=0; static volatile int in_bh=0;
cli(); cli();
if (in_bh != 0) if (in_bh != 0)
...@@ -331,7 +331,7 @@ inet_bh(void *tmp) ...@@ -331,7 +331,7 @@ inet_bh(void *tmp)
skb->len -= skb->dev->hard_header_len; skb->len -= skb->dev->hard_header_len;
/* convert the type to an ethernet type. */ /* 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 /* 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. */ a bunch of linked lists like we do for ip protocols. */
...@@ -355,7 +355,7 @@ inet_bh(void *tmp) ...@@ -355,7 +355,7 @@ inet_bh(void *tmp)
} }
else else
{ {
skb2 = skb; skb2 = (struct sk_buff *)skb;
flag = 1; flag = 1;
} }
...@@ -366,7 +366,7 @@ inet_bh(void *tmp) ...@@ -366,7 +366,7 @@ inet_bh(void *tmp)
if (!flag) if (!flag)
{ {
PRINTK (("discarding packet type = %X\n", type)); PRINTK (("discarding packet type = %X\n", type));
kfree_skb (skb, FREE_READ); kfree_skb ((struct sk_buff *)skb, FREE_READ);
} }
} }
in_bh = 0; in_bh = 0;
......
...@@ -2951,7 +2951,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -2951,7 +2951,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
{ {
sk->err = ECONNRESET; sk->err = ECONNRESET;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
sk->state = SHUTDOWN_MASK; sk->shutdown = SHUTDOWN_MASK;
tcp_reset (daddr, saddr, th, sk->prot, opt,dev); tcp_reset (daddr, saddr, th, sk->prot, opt,dev);
if (!sk->dead) if (!sk->dead)
{ {
...@@ -3070,7 +3070,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, ...@@ -3070,7 +3070,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
{ {
sk->err = ECONNREFUSED ; sk->err = ECONNREFUSED ;
sk->state = TCP_CLOSE; sk->state = TCP_CLOSE;
sk->state = SHUTDOWN_MASK; sk->shutdown = SHUTDOWN_MASK;
if (!sk->dead) if (!sk->dead)
{ {
wake_up (sk->sleep); wake_up (sk->sleep);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment