]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Linux-0.99.2 (January 1, 1993) 0.99.2
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)
Bottom half race condition fix.

Return ENODEV for nonexistent special devices.

Fix Unix domain sockets to properly check for target equality.

Add 'wchan' to /proc/stat

[Original announcement below]

Yes, as you've probably noticed, it's now 1993 and I still haven't
released 1.0.  Sorry about that, and I have only another patchlevel to
offer.  The new kernel should mainly fix some of the keyboard problems
people have experienced, but does contain some other minor fixes.

Linux 0.99.2 is available now at nic.funet.fi: pub/OS/Linux/PEOPLE/Linus
as both sources and diffs against 0.99.1 the diffs are essentially the
same as the second alpha-diffs I released for limited testing, with only
minor fixes to fs/exec.c and fs/open.c.

Please try out 0.99.2: the more feedback (hopefully positive) I get on
it, the faster 1.0 will be out.

Changes from pl1 are mainly:
 - pretty much rewritten low-level keyboard handling IO - this time
   actually trying to do it by the book.  It now handles resend requests
   from the keyboard etc.
 - you can run executables from filesystems without bmap support.  This
   mainly means NFS and msdos.  Note that while it's possible, it's
   slower and less memory-efficient than using a "normal" linux
   filesystem, and should generally be avoided.
 - /proc filesystem changes: /proc/kmsg can be used to log the kernel
   messages under X11 (instead of using the older system call to do the
   same), and there are changes to the statistics routines (WCHAN).

+ various minor fixes (non-existent devices are handled better, some
changes to socket bind behaviour etc).

                Linus

57 files changed:
Makefile
boot/head.S
boot/setup.S
config.in
fs/exec.c
fs/ext/blkdev.c
fs/ext/chrdev.c
fs/ext/file.c
fs/ext/namei.c
fs/isofs/blkdev.c
fs/isofs/chrdev.c
fs/minix/blkdev.c
fs/minix/chrdev.c
fs/minix/file.c
fs/minix/namei.c
fs/msdos/inode.c
fs/msdos/namei.c
fs/nfs/blkdev.c
fs/nfs/chrdev.c
fs/open.c
fs/proc/Makefile
fs/proc/array.c
fs/proc/inode.c
fs/proc/kmsg.c [new file with mode: 0644]
fs/proc/root.c
fs/select.c
include/asm/irq.h
include/asm/system.h
include/linux/autoconf.h [deleted file]
include/linux/config.h
include/linux/config_rel.h [deleted file]
include/linux/config_ver.h [deleted file]
include/linux/interrupt.h
include/linux/lp.h
include/linux/minix_fs.h
include/linux/proc_fs.h
include/linux/sched.h
include/linux/types.h
init/main.c
kernel/FPU-emu/get_address.c
kernel/blk_drv/scsi/scsi.c
kernel/blk_drv/scsi/sd.c
kernel/blk_drv/scsi/seagate.c
kernel/blk_drv/scsi/seagate.h
kernel/blk_drv/scsi/sr.c
kernel/blk_drv/scsi/st.c
kernel/blk_drv/scsi/wd7000.c
kernel/chr_drv/keyboard.c
kernel/chr_drv/sound/sound_stub.c
kernel/chr_drv/tty_io.c
kernel/chr_drv/tty_ioctl.c
kernel/irq.c
kernel/sched.c
kernel/sys_call.S
net/tcp/dev.c
net/unix.c
tools/build.c

index d740d50ef0686dff916ecd67b9a384336163ee9d..4fe289401e39cf07d12dc16759cb151ff57e7846 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -66,7 +66,7 @@ SVGA_MODE=    -DSVGA_MODE=1
 # You should use one of the values 4096 (SB), 16384 (SB Pro), 32768 (PAS+) 
 # or 65536 (PAS16). The SBC_IRQ defines the IRQ line used by SoundBlaster and
 # the PAS_IRQ is the IRQ number for ProAudioSpectrum.
-# NOTE! The ProAudioSpectrum support is not available yet.
+#
 
 SOUND_SUPPORT = -DKERNEL_SOUNDCARD -DDSP_BUFFSIZE=16384 -DSBC_IRQ=7 -DPAS_IRQ=5
 
@@ -97,6 +97,7 @@ CC    =gcc -DKERNEL
 MAKE   =make
 CPP    =$(CC) -E
 AR     =ar
+STRIP  =strip
 
 ARCHIVES       =kernel/kernel.o mm/mm.o fs/fs.o net/net.o
 FILESYSTEMS    =fs/filesystems.a
@@ -141,7 +142,7 @@ linuxsubdirs: dummy
 
 Version: dummy
        @./makever.sh
-       @echo \#define UTS_RELEASE \"0.99.pl1-`cat .version`\" > tools/version.h
+       @echo \#define UTS_RELEASE \"0.99.pl2-`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
@@ -149,7 +150,7 @@ Version: dummy
 
 Image: $(CONFIGURATION) boot/bootsect boot/setup tools/system tools/build
        cp tools/system system.tmp
-       strip system.tmp
+       $(STRIP) system.tmp
        tools/build boot/bootsect boot/setup system.tmp $(ROOT_DEV) > Image
        rm system.tmp
        sync
index 63812b234c1a60a74a68ba170a88bb742fa379b0..7497241ae12eb59642648ae3fb97a6c23feedd1f 100644 (file)
@@ -35,7 +35,19 @@ startup_32:
        movl %eax,0x000000      # loop forever if it isn't
        cmpl %eax,0x100000
        je 1b
+/*
+ * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
+ * confuse the debugger if this code is traced.
+ * XXX - best to initialize before switching to protected mode.
+ */
+       pushl $0
+       popfl
 /* check if it is 486 or 386. */
+/*
+ * XXX - this does a lot of unnecessary setup.  Alignment checks don't
+ * apply at our cpl of 0 and the stack ought to be aligned already, and
+ * we don't need to preserve eflags.
+ */
        movl %esp,%edi          # save stack pointer
        andl $0xfffffffc,%esp   # align stack to avoid AC fault
        pushfl                  # push EFLAGS
@@ -46,8 +58,9 @@ startup_32:
        popfl                   # set EFLAGS
        pushfl                  # get new EFLAGS
        popl %eax               # put it in eax
-       xorl %ecx,%eax          # check if AC bit is changed. zero is 486.
-       jz 1f                   # 486
+       xorl %ecx,%eax          # change in flags
+       andl $0x40000,%eax      # check if AC bit changed
+       jnz 1f                  # 486
        pushl %ecx              # restore original EFLAGS
        popfl
        movl %edi,%esp          # restore esp
@@ -60,13 +73,15 @@ startup_32:
  * mode. Then it would be unnecessary with the "verify_area()"-calls.
  * 486 users probably want to set the NE (#5) bit also, so as to use
  * int 16 for math errors.
+ * XXX - the above is out of date.  We set all the bits, but don't take
+ * advantage of WP (26 Dec 92).
  */
 1:     pushl %ecx              # restore original EFLAGS
        popfl
        movl %edi,%esp          # restore esp
        movl %cr0,%eax          # 486
        andl $0x80000011,%eax   # Save PG,PE,ET
-       orl $0x10022,%eax       # set NE and MP
+       orl $0x50022,%eax       # set AM, WP, NE and MP
 2:     movl %eax,%cr0
        call check_x87
        call setup_paging
index 194ca1b7e90038ec2391f01e0d09fb8b09e638ab..0fa8efcdf46d9361d40ac474ac90b2c55d068196 100644 (file)
@@ -253,17 +253,15 @@ no_output:
 getkey:
        in      al,#0x60                ! Quick and dirty...
        .word   0x00eb,0x00eb           ! jmp $+2, jmp $+2
-       mov     bl,al
-       in      al,#0x61
-       .word   0x00eb,0x00eb
-       mov     ah,al
-       or      al,#0x80
-       out     #0x61,al
-       .word   0x00eb,0x00eb
-       mov     al,ah
-       out     #0x61,al
+       ret
+
+!
+! Flush the keyboard buffer
+!
+flush: in      al,#0x60
        .word   0x00eb,0x00eb
-       mov     al,bl
+       cmp     al,#0x82
+       jae     flush
        ret
 
 ! Routine trying to recognize type of SVGA-board present (if any)
@@ -287,11 +285,8 @@ chsvga:    cld
        jne     svga
        lea     si,msg1
        call    prtstr
-flush: in      al,#0x60                ! Flush the keyboard buffer
-       cmp     al,#0x82
-       jb      nokey
-       jmp     flush
-nokey: call getkey
+       call    flush
+nokey: call    getkey
        cmp     al,#0x9c                ! enter ?
        je      svga                    ! yes - svga selection
        cmp     al,#0xb9                ! space ?
@@ -317,7 +312,18 @@ extvga:
        mov     ax,#0x5032      ! return 80x50
        ret
 /* svga modes */
-svga:  cld
+svga:  cld     
+       lea     si,idf1280      ! Check for Orchid F1280 (dingbat@diku.dk)
+       mov     di,#0x10a       ! id string is at c000:010a
+       mov     cx,#0x21        ! length
+       repe
+       cmpsb
+       jne     nf1280  
+       lea     si,dscf1280
+       lea     di,mof1280
+       lea     cx,selmod
+       jmp     cx
+nf1280:        cld
        lea     si,idati                ! Check ATI 'clues'
        mov     di,#0x31
        mov     cx,#0x09
@@ -701,6 +707,7 @@ idcandt:    .byte   0xa5
 idgenoa:       .byte   0x77, 0x00, 0x66, 0x99
 idparadise:    .ascii  "VGA="
 idoakvga:      .ascii  "OAK VGA "
+idf1280:       .ascii  "Orchid Technology Fahrenheit 1280"
 
 ! Manufacturer:          Numofmodes:   Mode:
 
@@ -715,6 +722,7 @@ motrident:  .byte   0x07,   0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
 motseng:       .byte   0x05,   0x26, 0x2a, 0x23, 0x24, 0x22
 movideo7:      .byte   0x06,   0x40, 0x43, 0x44, 0x41, 0x42, 0x45
 mooakvga:      .byte   0x05,   0x00, 0x07, 0x4f, 0x50, 0x51
+mof1280:       .byte   0x02,   0x54, 0x55
 
 !                      msb = Cols lsb = Rows:
 
@@ -729,6 +737,7 @@ dsctrident: .word   0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
 dsctseng:      .word   0x503c, 0x6428, 0x8419, 0x841c, 0x842c
 dscvideo7:     .word   0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
 dscoakvga:     .word   0x2819, 0x5019, 0x843c, 0x8419, 0x842C
+dscf1280:      .word   0x842b, 0x8419
 modesave:      .word   SVGA_MODE
        
 .text
index 051413969d8fd8ff2738e529a0d20406049682ae..12c8abc7cc0bd86cf6748f7b4f8fb27096a832dc 100644 (file)
--- a/config.in
+++ b/config.in
@@ -33,8 +33,6 @@ Adaptec AHA1542 support
 CONFIG_SCSI_AHA1542 y/n y
 Adaptec AHA1740 support
 CONFIG_SCSI_AHA1740 y/n y
-Always IN support
-CONFIG_SCSI_ALWAYS y/n y
 Future Domain SCSI support
 CONFIG_SCSI_FUTURE_DOMAIN y/n y
 Seagate ST-02 SCSI support
@@ -62,7 +60,7 @@ CONFIG_ISO9660_FS y/n n
 Various character device drivers..
 .
 Autoconfigure serial IRQ lines at bootup
-CONFIG_AUTOIRQ y/n n
+CONFIG_AUTO_IRQ y/n n
 AST Fourport serial driver support
 CONFIG_AST_FOURPORT y/n n
 Accent Async 4 serial support
index 2942228d2ecb690e247688a0ae6b73e60a2e0a1f..135014271c72a14e8e12ed32d20d1fe1d767d54d 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -194,6 +194,10 @@ int sys_uselib(const char * library)
                iput(inode);
                return -EACCES;
        }
+       if (!inode->i_op || !inode->i_op->bmap) {
+               iput(inode);
+               return -ENOEXEC;
+       }
        if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
                iput(inode);
                return -EACCES;
@@ -365,35 +369,42 @@ static unsigned long change_ldt(unsigned long text_size,unsigned long * page)
        return data_limit;
 }
 
-static void read_omagic(struct inode *inode, int bytes)
+/*
+ * Read in the complete executable. This is used for "-N" files
+ * that aren't on a block boundary, and for files on filesystems
+ * without bmap support.
+ */
+static int read_exec(struct inode *inode, unsigned long offset,
+       char * addr, unsigned long count)
 {
-       struct buffer_head *bh;
-       int n, blkno, blk = 0;
-       char *dest = (char *) 0;
-       unsigned int block_size;
+       struct file file;
+       int result = -ENOEXEC;
 
-       block_size = 1024;
-       if (inode->i_sb)
-               block_size = inode->i_sb->s_blocksize;
-       while (bytes > 0) {
-               n = (blk ? block_size : block_size - sizeof(struct exec));
-               if (bytes < n)
-                       n = bytes;
-               blkno = bmap(inode, blk);
-               if (blkno) {
-                       bh = bread(inode->i_dev, blkno, block_size);
-                       if (!bh)
-                               sys_exit(-1);
-                       memcpy_tofs(dest, (blk ? bh->b_data :
-                               bh->b_data + sizeof(struct exec)), n);
-                       brelse(bh);
-               }
-               ++blk;
-               dest += n;
-               bytes -= n;
-       }
-       iput(inode);
-       current->executable = NULL;
+       if (!inode->i_op || !inode->i_op->default_file_ops)
+               goto end_readexec;
+       file.f_mode = 1;
+       file.f_flags = 0;
+       file.f_count = 1;
+       file.f_inode = inode;
+       file.f_pos = 0;
+       file.f_reada = 0;
+       file.f_op = inode->i_op->default_file_ops;
+       if (file.f_op->open)
+               if (file.f_op->open(inode,&file))
+                       goto end_readexec;
+       if (!file.f_op || !file.f_op->read)
+               goto close_readexec;
+       if (file.f_op->lseek) {
+               if (file.f_op->lseek(inode,&file,offset,0) != offset)
+                       goto close_readexec;
+       } else
+               file.f_pos = offset;
+       result = file.f_op->read(inode, &file, addr, count);
+close_readexec:
+       if (file.f_op->release)
+               file.f_op->release(inode,&file);
+end_readexec:
+       return result;
 }
 
 /*
@@ -406,7 +417,8 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
        char ** argv, char ** envp)
 {
        struct inode * inode;
-       struct buffer_head * bh;
+       char buf[128];
+       unsigned long old_fs;
        struct exec ex;
        unsigned long page[MAX_ARG_PAGES];
        int i,argc,envc;
@@ -463,32 +475,35 @@ restart_interp:
                retval = -EACCES;
                goto exec_error2;
        }
-       if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
-               retval = -EACCES;
+       memset(buf,0,sizeof(buf));
+       old_fs = get_fs();
+       set_fs(get_ds());
+       retval = read_exec(inode,0,buf,128);
+       set_fs(old_fs);
+       if (retval < 0)
                goto exec_error2;
-       }
-       if (!IS_RDONLY(inode)) {
-               inode->i_atime = CURRENT_TIME;
-               inode->i_dirt = 1;
-       }
-       ex = *((struct exec *) bh->b_data);     /* read exec-header */
-       if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
+       ex = *((struct exec *) buf);            /* exec-header */
+       if ((buf[0] == '#') && (buf[1] == '!') && (!sh_bang)) {
                /*
                 * This section does the #! interpretation.
                 * Sorta complicated, but hopefully it will work.  -TYT
                 */
 
-               char buf[128], *cp, *interp, *i_name, *i_arg;
-               unsigned long old_fs;
+               char *cp, *interp, *i_name, *i_arg;
 
-               strncpy(buf, bh->b_data+2, 127);
-               brelse(bh);
                iput(inode);
                buf[127] = '\0';
-               if ((cp = strchr(buf, '\n')) != NULL) {
-                       *cp = '\0';
-                       for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);
+               if ((cp = strchr(buf, '\n')) == NULL)
+                       cp = buf+127;
+               *cp = '\0';
+               while (cp > buf) {
+                       cp--;
+                       if ((*cp == ' ') || (*cp == '\t'))
+                               *cp = '\0';
+                       else
+                               break;
                }
+               for (cp = buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
                if (!cp || *cp == '\0') {
                        retval = -ENOEXEC; /* No interpreter name found */
                        goto exec_error1;
@@ -499,10 +514,10 @@ restart_interp:
                        if (*cp == '/')
                                i_name = cp+1;
                }
-               if (*cp) {
+               while ((*cp == ' ') || (*cp == '\t'))
                        *cp++ = '\0';
+               if (*cp)
                        i_arg = cp;
-               }
                /*
                 * OK, we've parsed out the interpreter name and
                 * (optional) argument.
@@ -542,7 +557,6 @@ restart_interp:
                        goto exec_error1;
                goto restart_interp;
        }
-       brelse(bh);
        if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
                ex.a_trsize || ex.a_drsize ||
                ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
@@ -569,12 +583,13 @@ restart_interp:
                if (ch == '/')
                        i = 0;
                else
-                       if (i < 8)
+                       if (i < 15)
                                current->comm[i++] = ch;
-       if (i < 8)
-               current->comm[i] = '\0';
-       if (current->executable)
+       current->comm[i] = '\0';
+       if (current->executable) {
                iput(current->executable);
+               current->executable = NULL;
+       }
        i = current->numlibraries;
        while (i-- > 0) {
                iput(current->libraries[i].library);
@@ -584,7 +599,6 @@ restart_interp:
            !permission(inode,MAY_READ))
                current->dumpable = 0;
        current->numlibraries = 0;
-       current->executable = inode;
        current->signal = 0;
        for (i=0 ; i<32 ; i++) {
                current->sigaction[i].sa_mask = 0;
@@ -610,8 +624,14 @@ restart_interp:
        current->rss = (TASK_SIZE - p + PAGE_SIZE-1) / PAGE_SIZE;
        current->suid = current->euid = e_uid;
        current->sgid = current->egid = e_gid;
-       if (N_MAGIC(ex) == OMAGIC)
-               read_omagic(inode, ex.a_text+ex.a_data);
+       if (N_MAGIC(ex) == OMAGIC) {
+               read_exec(inode, 32, (char *) 0, ex.a_text+ex.a_data);
+               iput(inode);
+       } else if (!inode->i_op || !inode->i_op->bmap) {
+               read_exec(inode, 1024, (char *) 0, ex.a_text+ex.a_data);
+               iput(inode);
+       } else
+               current->executable = inode;
        eip[0] = ex.a_entry;            /* eip, magic happens :-) */
        eip[3] = p;                     /* stack pointer */
        if (current->flags & PF_PTRACED)
index 031678ac6429d1c38b7e821ced243f423d3d2905..381e44d757b617841b754d3b74a16a86e28e074c 100644 (file)
@@ -25,11 +25,11 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_BLKDEV) {
-               filp->f_op = blkdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_BLKDEV || !blkdev_fops[i])
+               return -ENODEV;
+       filp->f_op = blkdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }      
 
index 5d31e39cba4e5f52bac41ce802fabdead1d1ad8e..44976a0b98ad469d09850e5ad3f5bf145a0b3a00 100644 (file)
@@ -25,11 +25,11 @@ static int chrdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_CHRDEV) {
-               filp->f_op = chrdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_CHRDEV || !chrdev_fops[i])
+               return -ENODEV;
+       filp->f_op = chrdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }
 
index bb70d5050a0b851acb472504d3e8eb2b12f835e9..b86ce20d76707dbafd118ca54c99f74ec70cba8f 100644 (file)
@@ -118,14 +118,14 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
           buffers and caches. */
 
        do {
-               bhrequest = 0;
-               uptodate = 1;
+               bhrequest = 0;
+               uptodate = 1;
                while (blocks) {
                        --blocks;
                        *bhb = ext_getblk(inode, block++, 0);
                        if (*bhb && !(*bhb)->b_uptodate) {
-                               uptodate = 0;
-                               bhreq[bhrequest++] = *bhb;
+                               uptodate = 0;
+                               bhreq[bhrequest++] = *bhb;
                        }
 
                        if (++bhb == &buflist[NBUF])
index b094fbe10b42a226608c5eed6465b28693bf8946..bfb0171919f2e8325e13d8f778a332c7aaa6f7a6 100644 (file)
@@ -808,6 +808,11 @@ start_up:
                retval = -EEXIST;
                goto end_rename;
        }
+       retval = -EPERM;
+       if (new_inode && (new_dir->i_mode & S_ISVTX) && 
+           current->euid != new_inode->i_uid &&
+           current->euid != new_dir->i_uid && !suser())
+               goto end_rename;
        if (S_ISDIR(old_inode->i_mode)) {
                retval = -EEXIST;
                if (new_bh)
index 7b93d74cc351886ddb6c2282b8fce7380dff35bf..04934c7f09b164b4c19e5679b62b04860ee7ac86 100644 (file)
@@ -24,11 +24,11 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_BLKDEV) {
-               filp->f_op = blkdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_BLKDEV || !blkdev_fops[i])
+               return -ENODEV;
+       filp->f_op = blkdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }      
 
index fc69b12670c8c18b5a96955b9f9eba37b0704463..868690d9104684caaba7669ae0e8be3437eff0b8 100644 (file)
@@ -24,11 +24,11 @@ static int chrdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_CHRDEV) {
-               filp->f_op = chrdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_CHRDEV || !chrdev_fops[i])
+               return -ENODEV;
+       filp->f_op = chrdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }
 
index 061fc5c6a06d8776a217cf08e2a0790b207cd0b4..73fa71af85fa006e082e4d96900cee69494a05f6 100644 (file)
@@ -19,11 +19,11 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_BLKDEV) {
-               filp->f_op = blkdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_BLKDEV || !blkdev_fops[i])
+               return -ENODEV;
+       filp->f_op = blkdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }      
 
index 6f5e9d64a3449473fb0044f7bcd60e23dbd2169b..1e791e6cc018eba5ee8cf2494c1565d4505b32f6 100644 (file)
@@ -19,11 +19,11 @@ static int chrdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_CHRDEV) {
-               filp->f_op = chrdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_CHRDEV || !chrdev_fops[i])
+               return -ENODEV;
+       filp->f_op = chrdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }
 
index 9643009da1d30108a3cf80f94201d0189dae089d..82739313ef86a4e50d69414aca1ecac7f8a18181 100644 (file)
@@ -113,13 +113,13 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
 
        do {
                bhrequest = 0;
-               uptodate = 1;
+               uptodate = 1;
                while (blocks) {
                        --blocks;
                        *bhb = minix_getblk(inode, block++, 0);
                        if (*bhb && !(*bhb)->b_uptodate) {
-                               uptodate = 0;
-                               bhreq[bhrequest++] = *bhb;
+                               uptodate = 0;
+                               bhreq[bhrequest++] = *bhb;
                        }
 
                        if (++bhb == &buflist[NBUF])
index ec6cb63eff7c142a717d8dc5e73537eb685dd046..c2ba87f1e7a789647fe7df49cd5f0472e7cad1b2 100644 (file)
@@ -683,6 +683,11 @@ start_up:
                retval = -EEXIST;
                goto end_rename;
        }
+       retval = -EPERM;
+       if (new_inode && (new_dir->i_mode & S_ISVTX) && 
+           current->euid != new_inode->i_uid &&
+           current->euid != new_dir->i_uid && !suser())
+               goto end_rename;
        if (S_ISDIR(old_inode->i_mode)) {
                retval = -EEXIST;
                if (new_bh)
index 346c1f2d2e16f9440d14b59662c223c69ee6437c..bd5b7d88b0098ee9d9728255a655227bf13e3257 100644 (file)
@@ -169,7 +169,6 @@ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\n",
                printk("Unsupported FS parameters\n");
                return NULL;
        }
-       if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\n");
        s->s_magic = MSDOS_SUPER_MAGIC;
        MSDOS_SB(s)->name_check = check;
        MSDOS_SB(s)->conversion = conversion;
@@ -266,7 +265,7 @@ void msdos_read_inode(struct inode *inode)
        raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
            [inode->i_ino & (MSDOS_DPB-1)];
        if ((raw_entry->attr & ATTR_DIR) && *raw_entry->name && *(unsigned char *)
-            raw_entry->name != DELETED_FLAG) {
+           raw_entry->name != DELETED_FLAG) {
                inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0777 &
                    ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR;
                inode->i_op = &msdos_dir_inode_operations;
index 6fda997cbc9f68c38297418ba72e31a02c549fae..e38a92cecde4a11aebd701d250cb9abe03349331 100644 (file)
@@ -226,7 +226,7 @@ static void dump_fat(struct super_block *sb,int start)
        printk("[");
        while (start) {
                printk("%d ",start);
-               start = fat_access(sb,start,-1);
+               start = fat_access(sb,start,-1);
                if (!start) {
                        printk("ERROR");
                        break;
index 7df82f6ec008031c76d788fffd8ddc0d8d348096..6b4e0b45df8b67e7d299ac4d19a0062774fe1803 100644 (file)
@@ -19,11 +19,11 @@ static int blkdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_BLKDEV) {
-               filp->f_op = blkdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_BLKDEV || !blkdev_fops[i])
+               return -ENODEV;
+       filp->f_op = blkdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }      
 
index 458b4c703717ac83ceb3ea43ff72437af51d6851..f568bd119cf7da47d9754c65969cbfb165640a4a 100644 (file)
@@ -19,11 +19,11 @@ static int chrdev_open(struct inode * inode, struct file * filp)
        int i;
 
        i = MAJOR(inode->i_rdev);
-       if (i < MAX_CHRDEV) {
-               filp->f_op = chrdev_fops[i];
-               if (filp->f_op && filp->f_op->open)
-                       return filp->f_op->open(inode,filp);
-       }
+       if (i >= MAX_CHRDEV || !chrdev_fops[i])
+               return -ENODEV;
+       filp->f_op = chrdev_fops[i];
+       if (filp->f_op->open)
+               return filp->f_op->open(inode,filp);
        return 0;
 }
 
index 27a49814b942e0c5aed84db6df6584dbae5f2483..174af7f50fd25399d490ceed2c44ddb4f7ef65be 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -243,6 +243,8 @@ int sys_fchmod(unsigned int fd, mode_t mode)
        if (IS_RDONLY(inode))
                return -EROFS;
        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
+       if (!suser() && !in_group_p(inode->i_gid))
+               inode->i_mode &= ~S_ISGID;
        inode->i_dirt = 1;
        return notify_change(inode);
 }
@@ -264,6 +266,8 @@ int sys_chmod(const char * filename, mode_t mode)
                return -EROFS;
        }
        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
+       if (!suser() && !in_group_p(inode->i_gid))
+               inode->i_mode &= ~S_ISGID;
        inode->i_dirt = 1;
        error = notify_change(inode);
        iput(inode);
index 9af56d33105df0c1fa692fa493a073fb035724dd..cc1667621c72a173bb261b7b33a84b03b519e38b 100644 (file)
@@ -14,7 +14,7 @@
 .s.o:
        $(AS) -o $*.o $<
 
-OBJS=  inode.o root.o base.o mem.o link.o fd.o array.o
+OBJS=  inode.o root.o base.o mem.o link.o fd.o array.o kmsg.o
 
 proc.o: $(OBJS)
        $(LD) -r -o proc.o $(OBJS)
index f9e4b0ea0cdf74bb082e2ed2a790bf9d0bc4d7a1..5cd30ad1819a30c5fc2c88cf7caf6d10a3ee56d0 100644 (file)
@@ -26,8 +26,6 @@
 #define        SSIZE(stack)    (KSTK_ESP(stack) ? _SSIZE(stack) : 0)
 
 #define        VSIZE(task,stack) ((task)->brk + 1023 + SSIZE(stack))
-#define        SIZE(task,stack)  (((task)->brk - (task)->end_code + 1023 + \
-                         SSIZE(stack)) / 1024)
 
 
 static int get_loadavg(char * buffer)
@@ -140,19 +138,42 @@ static int get_arg(int pid, char * buffer)
        return get_array(p, (*p)->arg_start, (*p)->arg_end, buffer);
 }
 
+static unsigned long get_wchan(struct task_struct *p)
+{
+       unsigned long ebp, eip;
+       unsigned long stack_page;
+       int count = 0;
+
+       if (!p || p == current)
+               return 0;
+       ebp = p->tss.ebp;
+       stack_page = p->kernel_stack_page;
+       do {
+               if (ebp < stack_page || ebp >= 4092+stack_page)
+                       return 0;
+               eip = *(unsigned long *) (ebp+4);
+               if ((void *)eip != sleep_on &&
+                   (void *)eip != interruptible_sleep_on)
+                       return eip;
+               ebp = *(unsigned long *) ebp;
+       } while (count++ < 16);
+       return 0;
+}
+
 static int get_stat(int pid, char * buffer)
 {
        struct task_struct ** p = get_task(pid);
-       unsigned long sigignore=0, sigcatch=0, bit=1;
+       unsigned long sigignore=0, sigcatch=0, bit=1, wchan;
        int i;
        char state;
 
        if (!p || !*p)
                return 0;
-       if ((*p)->state < 0)
+       if ((*p)->state < 0 || (*p)->state > 5)
                state = '.';
        else
                state = "RSDZTD"[(*p)->state];
+       wchan = get_wchan(*p);
        for(i=0; i<32; ++i) {
                switch((int) (*p)->sigaction[i].sa_handler) {
                case 1: sigignore |= bit; break;
@@ -200,7 +221,7 @@ static int get_stat(int pid, char * buffer)
                (*p)->blocked,
                sigignore,
                sigcatch,
-               (*p)->tss.eip);
+               wchan);
 }
 
 static int get_statm(int pid, char * buffer)
index 07ceb81e85e8f5af1df5674eeea8a18609961b70..81492a80c5405afada956fbd1aaf2df33cb1dbaa 100644 (file)
@@ -67,16 +67,6 @@ void proc_statfs(struct super_block *sb, struct statfs *buf)
        /* Don't know what value to put in buf->f_fsid */
 }
 
-int proc_bmap(struct inode * inode,int block)
-{
-       return 0;
-}
-
-int proc_create_block(struct inode * inode, int block)
-{
-       return 0;
-}
-
 void proc_read_inode(struct inode * inode)
 {
        unsigned long ino, pid;
@@ -111,6 +101,8 @@ void proc_read_inode(struct inode * inode)
        if (!pid) {
                inode->i_mode = S_IFREG | 0444;
                inode->i_op = &proc_array_inode_operations;
+               if (ino == 5)
+                       inode->i_op = &proc_kmsg_inode_operations;
                return;
        }
        ino &= 0x0000ffff;
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
new file mode 100644 (file)
index 0000000..2cc2605
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  linux/fs/proc/kmsg.c
+ *
+ *  Copyright (C) 1992  by Linus Torvalds
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+
+extern int sys_syslog(int type, char * bug, int count);
+
+static int kmsg_open(struct inode * inode, struct file * file)
+{
+       return sys_syslog(1,NULL,0);
+}
+
+static void kmsg_release(struct inode * inode, struct file * file)
+{
+       (void) sys_syslog(0,NULL,0);
+}
+
+static int kmsg_read(struct inode * inode, struct file * file,char * buf, int count)
+{
+       return sys_syslog(2,buf,count);
+}
+
+static struct file_operations proc_kmsg_operations = {
+       NULL,           /* kmsg_lseek */
+       kmsg_read,
+       NULL,           /* kmsg_write */
+       NULL,           /* kmsg_readdir */
+       NULL,           /* kmsg_select */
+       NULL,           /* kmsg_ioctl */
+       NULL,           /* mmap */
+       kmsg_open,
+       kmsg_release
+};
+
+struct inode_operations proc_kmsg_inode_operations = {
+       &proc_kmsg_operations,  /* default base directory file-ops */
+       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 */
+       NULL                    /* truncate */
+};
index 2aa78a60aaffee057b5b7f2f4becc509f2c4d215..700f6b04bc05749c94eefd11a34f55fc17ce2efd 100644 (file)
@@ -54,7 +54,8 @@ static struct proc_dir_entry root_dir[] = {
        { 2,7,"loadavg" },
        { 3,6,"uptime" },
        { 4,7,"meminfo" },
-       { 5,4,"self" }  /* will change inode # */
+       { 5,4,"kmsg" },
+       { 6,4,"self" }  /* will change inode # */
 };
 
 #define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
@@ -81,7 +82,7 @@ static int proc_lookuproot(struct inode * dir,const char * name, int len,
                        *result = dir;
                        return 0;
                }
-               if (ino == 5) /* self modifying inode ... */
+               if (ino == 6) /* self modifying inode ... */
                        ino = (current->pid << 16) + 2;
        } else {
                pid = 0;
index ea97e58fe4dd4233317929435f85aae310c30a6e..1bf7f153033924f8efb6c02eb2a8377bff3afa24 100644 (file)
@@ -18,6 +18,8 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 
+#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
+
 /*
  * Ok, Peter made a complicated, but straightforward multiple_wait() function.
  * I have rewritten this, taking some shortcuts: This code may not be easy to
@@ -198,7 +200,7 @@ int sys_select( unsigned long *buffer )
        timeout = 0xffffffff;
        if (tvp) {
                timeout = jiffies;
-               timeout += get_fs_long((unsigned long *)&tvp->tv_usec)/(1000000/HZ);
+               timeout += ROUND_UP(get_fs_long((unsigned long *)&tvp->tv_usec),(1000000/HZ));
                timeout += get_fs_long((unsigned long *)&tvp->tv_sec) * HZ;
                if (timeout <= jiffies)
                        timeout = 0;
index a492dc88e08983b0329e2b679181275e22463259..da69d1f790feed2157f3bca86502b1b97539e331 100644 (file)
@@ -122,7 +122,15 @@ __asm__( \
        "addl $8,%esp\n\t" \
        "cli\n\t" \
        UNBLK_##chip(mask) \
-       "call _do_bottom_half\n\t"\
+       "decl _intr_count\n\t" \
+       "jne ret_from_sys_call\n\t" \
+       "cmpl $0,_bh_active\n\t" \
+       "je ret_from_sys_call\n\t" \
+       "incl _intr_count\n\t" \
+       "sti\n\t" \
+       "call _do_bottom_half\n\t" \
+       "cli\n\t" \
+       "decl _intr_count\n\t" \
        "jmp ret_from_sys_call\n" \
 "\n.align 2\n" \
 "_fast_IRQ" #nr "_interrupt:\n\t" \
index 45cb87de3ed98e3f16b71e5f073d8ebd449d4ca8..4aee818a3b985f172d810c36e680cb27f9377e2d 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef __ASM_SYSTEM_H
+#define __ASM_SYSTEM_H
+
 #define move_to_user_mode() \
 __asm__ __volatile__ ("movl %%esp,%%eax\n\t" \
        "pushl $0x17\n\t" \
@@ -17,6 +20,14 @@ __asm__ __volatile__ ("movl %%esp,%%eax\n\t" \
 #define cli() __asm__ __volatile__ ("cli"::)
 #define nop() __asm__ __volatile__ ("nop"::)
 
+extern inline int tas(char * m)
+{
+       char res;
+
+       __asm__("xchg %0,%1":"=q" (res),"=m" (*m):"0" (0x1));
+       return res;
+}
+
 #define save_flags(x) \
 __asm__ __volatile__("pushfl ; popl %0":"=r" (x))
 
@@ -70,3 +81,5 @@ __asm__ __volatile__ ("movw $" #limit ",%1\n\t" \
 
 #define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),231,"0x89")
 #define set_ldt_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),23,"0x82")
+
+#endif
diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h
deleted file mode 100644 (file)
index e6db1e5..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Automatically generated C config: don't edit
- */
-
-/*
- * General setup
- */
-#define CONFIG_BLK_DEV_HD 1
-#define CONFIG_TCPIP 1
-#define CONFIG_MAX_16M 1
-#define CONFIG_M486 1
-
-/*
- * SCSI support
- */
-
-/*
- * SCSI support type (disk, tape, CDrom)
- */
-
-/*
- * SCSI low-level drivers
- */
-
-/*
- * Filesystems
- */
-#define CONFIG_MINIX_FS 1
-#define CONFIG_PROC_FS 1
-
-/*
- * Various character device drivers..
- */
index 59d2c69002748a82e6383e2a3dc1c40478cc5a03..c47233508844391dc672b24aa4f73c4e3ae8c36c 100644 (file)
@@ -22,7 +22,7 @@
 #define DEF_INITSEG    0x9000
 #define DEF_SYSSEG     0x1000
 #define DEF_SETUPSEG   0x9020
-#define DEF_SYSSIZE    0x7000
+#define DEF_SYSSIZE    0x8000
 
 /* internal svga startup constants */
 #define NORMAL_VGA     0xffff          /* 80x25 mode */
diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h
deleted file mode 100644 (file)
index f875936..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#define UTS_RELEASE "0.97.pl2-44"
diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h
deleted file mode 100644 (file)
index 18a6d6e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#define UTS_VERSION "08/23/92"
index f997e3cde71179eb690252f2505a2a52ae95d4d6..812faf408c7c5edc962425ac18c599ab58ab4e7e 100644 (file)
@@ -16,9 +16,15 @@ enum {
        TIMER_BH = 0,
        CONSOLE_BH,
        SERIAL_BH,
-       INET_BH
+       INET_BH,
+       KEYBOARD_BH
 };
 
 void do_bottom_half();
 
+extern inline void mark_bh(int nr)
+{
+       __asm__ __volatile__("btsl %1,%0":"=m" (bh_active):"ir" (nr));
+}
+
 #endif
index b73709c35762d5b2cf0a9c23f3f01950c4c2762d..c885ae27c0e078fc2ad2bd45aa98f92cc2bb3f6a 100644 (file)
  * have extremely slow printing, or if the machine seems to slow down
  * a lot when you print.  If you have slow printing, increase this
  * number and recompile, and if your system gets bogged down, decrease
- * this number.  This can be changed with the tunelp(8) command.
+ * this number.  This can be changed with the tunelp(8) command as well.
  */
 
-#define LP_INIT_CHAR 250
+#define LP_INIT_CHAR 1000
 
 /* The parallel port specs apparently say that there needs to be
  * a .5usec wait before and after the strobe.  Since there are wildly
  * different computers running linux, I can't come up with a perfect
  * value, but since it worked well on most printers before without,
- * and I have seen some improvement on my computer by making it a
- * small number, I'll initialize it to 2.
+ * I'll initialize it to 0.
  */
 
-#define LP_INIT_WAIT 2
+#define LP_INIT_WAIT 0
 
 /* This is the amount of time that the driver waits for the printer to
  * catch up when the printer's buffer appears to be filled.  If you
  * want to tune this and have a fast printer (i.e. HPIIIP), decrease
  * this number, and if you have a slow printer, increase this number.
- * This is in hundredths of a second, the default 10 being .1 second.
+ * This is in hundredths of a second, the default 2 being .05 second.
  * Or use the tunelp(8) command, which is especially nice if you want
  * change back and forth between character and graphics printing, which
  * are wildly different...
  */
 
-#define LP_INIT_TIME 10
+#define LP_INIT_TIME 2
 
 /* IOCTL numbers */
 #define LPCHAR   0x0001  /* corresponds to LP_INIT_CHAR */
index f97fbcd09d6a5e49aa501a594613febb83265d51..a8f321159419f1db33d2cecc3beba1406611dd43 100644 (file)
@@ -5,12 +5,20 @@
  * The minix filesystem constants/structures
  */
 
+/*
+ * Thanks to Kees J Bot for sending me the definitions of the new
+ * minix filesystem (aka V2) with bigger inodes and 32-bit block
+ * pointers. It's not actually implemented yet, but I'll look into
+ * it.
+ */
+
 #define MINIX_NAME_LEN 14
 #define MINIX_ROOT_INO 1
 
-#define MINIX_I_MAP_SLOTS 8
-#define MINIX_Z_MAP_SLOTS 8
-#define MINIX_SUPER_MAGIC 0x137F
+#define MINIX_I_MAP_SLOTS      8
+#define MINIX_Z_MAP_SLOTS      8
+#define MINIX_SUPER_MAGIC      0x137F
+#define NEW_MINIX_SUPER_MAGIC  0x2468
 
 #define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
 #define MINIX_DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_dir_entry)))
@@ -25,6 +33,24 @@ struct minix_inode {
        unsigned short i_zone[9];
 };
 
+/*
+ * The new minix inode has all the time entries, as well as
+ * long block numbers and a third indirect block (7+1+1+1
+ * instead of 7+1+1). Also, some previously 8-bit values are
+ * now 16-bit. The inode is now 64 bytes instead of 32.
+ */
+struct new_minix_inode {
+       unsigned short i_mode;
+       unsigned short i_nlinks;
+       unsigned short i_uid;
+       unsigned short i_gid;
+       unsigned long i_size;
+       unsigned long i_atime;
+       unsigned long i_mtime;
+       unsigned long i_ctime;
+       unsigned long i_zone[10];
+};
+
 /*
  * minix super-block data on disk
  */
index b8bc123a3c7bb639922645f381204c36a42fa593..8ff2ebaaf17fabb7cfbb958232d81640cdd9ff5f 100644 (file)
@@ -27,6 +27,7 @@ extern struct inode_operations proc_root_inode_operations;
 extern struct inode_operations proc_base_inode_operations;
 extern struct inode_operations proc_mem_inode_operations;
 extern struct inode_operations proc_array_inode_operations;
+extern struct inode_operations proc_kmsg_inode_operations;
 extern struct inode_operations proc_link_inode_operations;
 extern struct inode_operations proc_fd_inode_operations;
 
index d52d65c7a8da07da0db65d042124b026e18da80c..e6fdbfbed9de915235cde312db975506c3c0da7d 100644 (file)
@@ -184,7 +184,7 @@ struct task_struct {
        struct rlimit rlim[RLIM_NLIMITS]; 
        unsigned short used_math;
        unsigned short rss;     /* number of resident pages */
-       char comm[8];
+       char comm[16];
        struct vm86_struct * vm86_info;
        unsigned long screen_bitmap;
 /* file system info */
index ff3db4bb941376959f6db4f1456e132e1d5b7356..968a49e1670b17beb795f47aa306bbbafe5e5861 100644 (file)
@@ -82,7 +82,7 @@ typedef unsigned long tcflag_t;
 #define __FDSET_LONGS 8
 
 typedef struct fd_set {
-       unsigned long __bits [__FDSET_LONGS];
+       unsigned long fds_bits [__FDSET_LONGS];
 } fd_set;
 
 #undef __NFDBITS
index cb47e84cb74fd83d038f3db07de6074c45fcdfb4..9f8b16f0eef44f2d863cb1e3aa10a701834ec562 100644 (file)
@@ -100,7 +100,7 @@ extern unsigned long scsi_dev_init(unsigned long, unsigned long);
  */
 
 #define CMOS_READ(addr) ({ \
-outb_p(0x80|addr,0x70); \
+outb_p(addr,0x70); \
 inb_p(0x71); \
 })
 
@@ -109,7 +109,11 @@ inb_p(0x71); \
 static void time_init(void)
 {
        struct mktime time;
+       int i;
 
+       for (i = 0 ; i < 1000000 ; i++)
+               if (!(CMOS_READ(10) & 0x80))
+                       break;
        do {
                time.sec = CMOS_READ(0);
                time.min = CMOS_READ(2);
index 75b149e0c45a61c72152aa634456ca235c958cd2..3d5e97fd538ccea3a649f48691c8ee975d9807b7 100644 (file)
@@ -115,7 +115,7 @@ void get_address(unsigned char FPU_modrm)
 {
   unsigned char mod;
   long *cpu_reg_ptr;
-  int offset;
+  int offset = 0;
   
   mod = (FPU_modrm >> 6) & 3;
 
index 369d4748f90373283e3f80857dedb4cdc8f08760..40093a018c6c16653650cc75bb1c781b74f58d77 100644 (file)
@@ -104,11 +104,9 @@ extern int last_reset[];
        char * revision; /* Latest revision known to be bad.  Not used yet */
      };
 
-#if 0
 static struct blist blacklist[] = 
 {{"TANDBERG","TDC 3600","U07"},  /* Locks up if polled for lun != 0 */
    {"SEAGATE","ST296","921"},   /* Responds to all lun */
-   {"NEWBURY","NDR3380S","2.10"},   /* Responds to all lun */
    {NULL, NULL, NULL}};        
 
 static int blacklisted(char * response_data){
@@ -122,7 +120,6 @@ static int blacklisted(char * response_data){
     return 1;
   };   
 };
-#endif
 
 /*
  *     As the actual SCSI command runs in the background, we must set up a 
@@ -324,11 +321,9 @@ static void scan_scsis (void)
                        };
 
                        ++NR_SCSI_DEVICES;
-#if 0
                        /* Some scsi devices cannot be polled for lun != 0
                           due to firmware bugs */
                        if(blacklisted(scsi_result)) break;
-#endif
                        /* Some scsi-1 peripherals do not handle lun != 0.
                           I am assuming that scsi-2 peripherals do better */
                        if((scsi_result[2] & 0x07) == 1 && 
index 9f1e83b7493a82f48e7b3ffbcb577a61d2c519c5..ca3c935a3092583a217fe40c747b13dbc23e49dd 100644 (file)
@@ -62,7 +62,7 @@ static int sd_open(struct inode * inode, struct file * filp)
        target =  DEVICE_NR(MINOR(inode->i_rdev));
 
        if(target >= NR_SD || !rscsi_disks[target].device)
-         return -EACCES;   /* No such device */
+         return -ENODEV;   /* No such device */
        
 /* Make sure that only one process can do a check_change_disk at one time.
  This is also used to lock out further access when the partition table is being re-read. */
@@ -761,6 +761,7 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
 {
        int i;
 
+       blkdev_fops[MAJOR_NR] = &sd_fops; /* to get sd_open in table */
        if (MAX_SD == 0) return memory_start;
 
        sd_sizes = (int *) memory_start;
@@ -779,7 +780,6 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
          i = sd_init_onedisk(i);
 
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
-       blkdev_fops[MAJOR_NR] = &sd_fops;
 
        /* If our host adapter is capable of scatter-gather, then we increase
           the read-ahead to 8 blocks (16 sectors).  If not, we use
index 7b11506957a8e14ba75a4b5647885c568d837dae..5214b227cf3083d2307a91294583e447e6fc7493 100644 (file)
@@ -61,7 +61,7 @@ static volatile int st0x_aborted=0;   /*
                                                detect routine - but this 
                                                overides it. 
                                        */
-
+static unsigned char controller_type;  /* set to SEAGATE for ST0x boards or FD for TMC-88x boards */
                        
 #define retcode(result) (((result) << 16) | (message << 8) | status)                   
 #define STATUS (*(unsigned char *) st0x_cr_sr)
@@ -76,11 +76,12 @@ typedef struct
        char *signature ;
        unsigned offset;
        unsigned length;
+       unsigned char type;
        } Signature;
        
 static const Signature signatures[] = {
 #ifdef CONFIG_SCSI_SEAGATE
-{"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40},
+{"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 
 /*
        The following two lines are NOT mistakes.  One detects 
@@ -90,9 +91,8 @@ static const Signature signatures[] = {
        are probably "good enough"
 */
 
-{"SEAGATE SCSI BIOS ",16, 17},
-{"SEAGATE SCSI BIOS ",17, 17},
-#endif
+{"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
+{"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
 
 /*
        This is for the Future Domain 88x series.  I've been told that
@@ -101,8 +101,9 @@ static const Signature signatures[] = {
        I believe it.
 */
 
-#ifdef CONFIG_SCSI_FD_88x
-{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 5, 46},
+{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 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},
 #endif
 }
 ;
@@ -168,14 +169,16 @@ static struct sigaction seagate_sigaction = {
                for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
                if (!memcmp ((void *) (seagate_bases[i] +
                    signatures[j].offset), (void *) signatures[j].signature,
-                   signatures[j].length))
+                   signatures[j].length)) {
                        base_address = (void *) seagate_bases[i];
+                       controller_type = signatures[j].type;
+               }
  #endif
  
        if (base_address)
                {
-               st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00); 
-               st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
+               st0x_cr_sr =(void *) (((unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00)); 
+               st0x_dr = (void *) (((unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
 #ifdef DEBUG
                printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
 #endif
@@ -369,7 +372,7 @@ static int internal_command(unsigned char target, unsigned char lun, const void
 #endif
        
 
-       if (target > 6)
+       if (target == (controller_type == SEAGATE ? 7 : 6))
                return DID_BAD_TARGET;
 
 /*
@@ -410,7 +413,7 @@ static int internal_command(unsigned char target, unsigned char lun, const void
  *     ID off of the BUS.
  */
  
-               if (!((temp = DATA) & 0x80))
+               if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
                        {
 #if (DEBUG & PHASE_RESELECT)
                        printk("scsi%d : detected reconnect request to different target.\n" 
@@ -518,7 +521,7 @@ static int internal_command(unsigned char target, unsigned char lun, const void
 /*
  *     We must assert both our ID and our target's ID on the bus.
  */
-               DATA = (unsigned char) ((1 << target) | 0x80);
+               DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
 
 /*
  *     If we are allowing ourselves to reconnect, then I will keep 
index b40b7068e45ce0c1e47456787813fb99a3850773..efbbe05703eab15af1abf266e8242b66a30d2411 100644 (file)
@@ -125,6 +125,9 @@ extern volatile int seagate_st0x_timeout;
 
 #define eoi() __asm__("push %%eax\nmovb $0x20, %%al\noutb %%al, $0x20\npop %%eax"::)
        
+#define SEAGATE 1      /* these determine the type of the controller */
+#define FD     2
+
 
 #endif
 
index 9f9fb338ec78c10f420d932fa592d67541465a8b..63a750901c66f73d67e7da49bd3eefff1583a1c2 100644 (file)
@@ -257,7 +257,7 @@ static void rw_intr (Scsi_Cmnd * SCpnt)
 static int sr_open(struct inode * inode, struct file * filp)
 {
        if(MINOR(inode->i_rdev) >= NR_SR || 
-          !scsi_CDs[MINOR(inode->i_rdev)].device) return -EACCES;   /* No such device */
+          !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENODEV;   /* No such device */
 
         check_disk_change(inode->i_rdev);
 
@@ -601,6 +601,7 @@ unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
 {
        int i;
 
+       blkdev_fops[MAJOR_NR] = &sr_fops; 
        if(MAX_SR == 0) return memory_start;
 
        sr_sizes = (int *) memory_start;
@@ -628,6 +629,5 @@ unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
        else
          read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
 
-       blkdev_fops[MAJOR_NR] = &sr_fops; 
        return memory_start;
 }      
index 9ede064b64f28af6c686e233dab0796fe0053cd2..c648768756f80630ef746bd03f3530b79324d382 100644 (file)
@@ -292,7 +292,7 @@ static int scsi_tape_open(struct inode * inode, struct file * filp)
 
     dev = inode->i_rdev & 127;
     if (dev >= NR_ST)
-      return (-ENXIO);
+      return (-ENODEV);
     if (scsi_tapes[dev].in_use) {
       printk("st%d: Device already in use.\n", dev);
       return (-EBUSY);
@@ -1227,12 +1227,12 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
 {
   int i;
 
+  chrdev_fops[MAJOR_NR] = &st_fops;
   if (NR_ST == 0) return mem_start;
 
 #ifdef DEBUG
   printk("st: Init tape.\n");
 #endif
-  chrdev_fops[MAJOR_NR] = &st_fops;
 
   for (i=0; i < NR_ST; ++i) {
     scsi_tapes[i].capacity = 0xfffff;
index 61b5437cd362166e324b51f96f76bc677d6729f7..cbd55b42145e96d29753ea4889b4ef3660a34d21 100644 (file)
@@ -61,8 +61,6 @@
   indices need not be involved.
 */
 
-static void wd7000_set_sync(int id);
-
 static struct {
        struct wd_mailbox ogmb[OGMB_CNT]; 
        struct wd_mailbox icmb[ICMB_CNT];
@@ -576,21 +574,6 @@ const char *wd7000_info(void)
     return info;
 }
 
-
-void wd7000_set_sync(int id)
-{
-    volatile unchar icb[ICB_LEN] = {0x8a};
-    unchar speedval = 0x2c;    /* Sets 4MHz for SBIC Revision A */
-    any2scsi(icb+2,1);         /* Transfer 1 byte */
-    any2scsi(icb+5,&speedval); /* The speed buffer address */
-    icb[8]=0; icb[9]=2*id;      /* The index into the table */
-
-    icb[ICB_PHASE] = 1;
-    mail_out( (struct scb *) icb );
-    while (icb[ICB_PHASE]) /* wait for completion */;
-}
-
-
 int wd7000_abort(Scsi_Cmnd * SCpnt, int i)
 {
 #ifdef DEBUG
index 5f43db0f3034622426f17b19b44ef83ba9e94d6e..2ca72d336963857305864bac0a98cb3d253dde9c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/ptrace.h>
 #include <linux/keyboard.h>
+#include <linux/interrupt.h>
 
 /*
  * The default IO slowdown is doing 'inb()'s from 0x61, which should be
@@ -39,6 +40,9 @@ struct kbd_struct kbd_table[NR_CONSOLES];
 static struct kbd_struct * kbd = kbd_table;
 static struct tty_struct * tty = NULL;
 
+static volatile unsigned char acknowledge = 0;
+static volatile unsigned char resend = 0;
+
 typedef void (*fptr)(int);
 
 static int diacr = -1;
@@ -53,57 +57,87 @@ static unsigned int handle_diacr(unsigned int);
 
 static struct pt_regs * pt_regs;
 
+static inline void kb_wait(void)
+{
+       int i;
+
+       for (i=0; i<0x10000; i++)
+               if ((inb_p(0x64) & 0x02) == 0)
+                       break;
+}
+
+/*
+ * send_cmd() sends a command byte to the keyboard.
+ */
+static inline void send_cmd(unsigned char c)
+{
+       kb_wait();
+       outb(c,0x64);
+}
+
+static inline unsigned char get_scancode(void)
+{
+       kb_wait();
+       if (inb_p(0x64) & 0x01)
+               return inb(0x60);
+       return 0;
+}
+
 static void keyboard_interrupt(int int_pt_regs)
 {
        static unsigned char rep = 0xff;
        unsigned char scancode;
 
        pt_regs = (struct pt_regs *) int_pt_regs;
-       while (inb_p(0x64) & 1) {
-               kbd_prev_dead_keys |= kbd_dead_keys;
-               if (!kbd_dead_keys)
-                       kbd_prev_dead_keys = 0;
-               kbd_dead_keys = 0;
-               scancode = inb_p(0x60);
-               tty = TTY_TABLE(0);
-               kbd = kbd_table + fg_console;
-               if (vc_kbd_flag(kbd,VC_RAW)) {
-                       kbd_flags = 0;
-                       put_queue(scancode);
-                       continue;
-               }
-               if (scancode == 0xe0) {
-                       set_kbd_dead(KGD_E0);
-                       continue;
-               } else if (scancode == 0xe1) {
-                       set_kbd_dead(KGD_E1);
-                       continue;
-               }
-               /*
-                *  The keyboard maintains its own internal caps lock and num lock
-                *  statuses. In caps lock mode E0 AA precedes make code and E0 2A
-                *  follows break code. In num lock mode, E0 2A precedes make
-                *  code and E0 AA follows break code. We do our own book-keeping,
-                *  so we will just ignore these.
-                */
-               if (kbd_dead(KGD_E0) && (scancode == 0x2a || scancode == 0xaa))
-                       continue;
-               /*
-                *  Repeat a key only if the input buffers are empty or the
-                *  characters get echoed locally. This makes key repeat usable
-                *  with slow applications and unders heavy loads.
-                */
-               if (scancode == rep) {
-                       if (!(vc_kbd_flag(kbd,VC_REPEAT) && tty &&
-                                  (L_ECHO(tty) ||
-                                   (EMPTY(&tty->secondary) &&
-                                    EMPTY(&tty->read_q)))))
-                               continue;
-               }
-               rep = scancode;
-               key_table[scancode](scancode);
+       kbd_prev_dead_keys |= kbd_dead_keys;
+       if (!kbd_dead_keys)
+               kbd_prev_dead_keys = 0;
+       kbd_dead_keys = 0;
+       send_cmd(0xAD);
+       scancode = get_scancode();
+       if (scancode == 0xfa) {
+               acknowledge = 1;
+               goto end_kbd_intr;
+       } else if (scancode == 0xfe) {
+               resend = 1;
+               goto end_kbd_intr;
+       }
+       tty = TTY_TABLE(0);
+       kbd = kbd_table + fg_console;
+       if (vc_kbd_flag(kbd,VC_RAW)) {
+               kbd_flags = 0;
+               put_queue(scancode);
+               goto end_kbd_intr;
        }
+       if (scancode == 0xe0) {
+               set_kbd_dead(KGD_E0);
+               goto end_kbd_intr;
+       } else if (scancode == 0xe1) {
+               set_kbd_dead(KGD_E1);
+               goto end_kbd_intr;
+       }
+       /*
+        *  The keyboard maintains its own internal caps lock and num lock
+        *  statuses. In caps lock mode E0 AA precedes make code and E0 2A
+        *  follows break code. In num lock mode, E0 2A precedes make
+        *  code and E0 AA follows break code. We do our own book-keeping,
+        *  so we will just ignore these.
+        */
+       if (kbd_dead(KGD_E0) && (scancode == 0x2a || scancode == 0xaa))
+               goto end_kbd_intr;
+       /*
+        *  Repeat a key only if the input buffers are empty or the
+        *  characters get echoed locally. This makes key repeat usable
+        *  with slow applications and unders heavy loads.
+        */
+       if ((scancode != rep) || 
+           (vc_kbd_flag(kbd,VC_REPEAT) && tty &&
+            (L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
+               key_table[scancode](scancode);
+       rep = scancode;
+end_kbd_intr:
        do_keyboard_interrupt();
+       send_cmd(0xAE);
 }
 
 static void put_queue(int ch)
@@ -1273,51 +1307,48 @@ static void none(int sc)
 }
 
 /*
- * kb_wait waits for the keyboard controller buffer to empty.
+ * send_data sends a character to the keyboard and waits
+ * for a acknowledge, possibly retrying if asked to. Returns
+ * the success status.
  */
-static void kb_wait(void)
+static int send_data(unsigned char data)
 {
+       int retries = 3;
        int i;
 
-       for (i=0; i<0x10000; i++)
-               if ((inb(0x64)&0x02) == 0)
-                       break;
+       do {
+               kb_wait();
+               acknowledge = 0;
+               resend = 0;
+               outb_p(data, 0x60);
+               for(i=0; i<0x20000; i++) {
+                       inb_p(0x64);            /* just as a delay */
+                       if (acknowledge)
+                               return 1;
+                       if (resend)
+                               goto repeat;
+               }
+               return 0;
+repeat:
+       } while (retries-- > 0);
+       return 0;
 }
 
-/*
- * kb_ack waits for 0xfa to appear in port 0x60
- *
- * Suggested by Bruce Evans
- * Added by Niels Skou Olsen [NSO]
- * April 21, 1992
- *
- * Heavily inspired by kb_wait :-)
- * I don't know how much waiting actually is required,
- * but this seems to work
- */
-static void kb_ack(void)
+static void kbd_bh(void * unused)
 {
-       int i;
+       static unsigned char old_leds = -1;
+       unsigned char leds = kbd_table[fg_console].flags & LED_MASK;
 
-       for(i=0; i<0x10000; i++)
-               if (inb(0x60) == 0xfa)
-                       break;
+       if (leds == old_leds)
+               return;
+       old_leds = leds;
+       if (!send_data(0xed) || !send_data(leds))
+               send_data(0xf4);        /* re-enable kbd if any errors */
 }
 
 void set_leds(void)
 {
-       static unsigned char old_leds = -1;
-       unsigned char leds = kbd_table[fg_console].flags & LED_MASK;
-
-       if (leds != old_leds) {
-               old_leds = leds;
-               kb_wait();
-               outb(0xed, 0x60);       /* set leds command */
-               kb_ack();
-               kb_wait();
-               outb(leds, 0x60);
-               kb_ack();
-       }
+       mark_bh(KEYBOARD_BH);
 }
 
 long no_idt[2] = {0, 0};
@@ -1332,7 +1363,7 @@ void hard_reset_now(void)
        int i, j;
        extern unsigned long pg0[1024];
 
-       sti();
+       cli();
 /* rebooting needs to touch the page at absolute addr 0 */
        pg0[0] = 7;
        *((unsigned short *)0x472) = 0x1234;
@@ -1425,6 +1456,7 @@ unsigned long kbd_init(unsigned long kmem_start)
                kbd->default_flags = KBD_DEFFLAGS;
                kbd->kbd_flags = KBDFLAGS;
        }
+       bh_base[KEYBOARD_BH].routine = kbd_bh;
        request_irq(KEYBOARD_IRQ,keyboard_interrupt);
        keyboard_interrupt(0);
        return kmem_start;
index 33cc58d86b083c7a141364139333819c1a2e3ec3..a64e035d95d4134cbb7872e0d2a65dc677f493bd 100644 (file)
@@ -13,3 +13,7 @@ long soundcard_init(long mem_start)
 {
        return mem_start;
 }
+
+#ifdef CONFIG_SOUND
+#error The Sound Driver not installed.
+#endif
index 00e4952246e3b34548935a30efcf9ff19989d552..4d3f5a9e885e76b0a8d53218823ddd16cf87314e 100644 (file)
@@ -1130,9 +1130,9 @@ long tty_init(long kmem_start)
                tty_table[i] =  0;
                tty_termios[i] = 0;
        }
+       kmem_start = kbd_init(kmem_start);
        kmem_start = con_init(kmem_start);
        kmem_start = rs_init(kmem_start);
-       kmem_start = kbd_init(kmem_start);
        printk("%d virtual consoles\n\r",NR_CONSOLES);
        return kmem_start;
 }
index 7021f2eade10654e4db559002b3cb671b02cf6e0..7eb6e4e5f5ee4ccac5f2e266c4b7a3df1aef9d50 100644 (file)
@@ -61,18 +61,24 @@ void flush_output(struct tty_struct * tty)
 
 void wait_until_sent(struct tty_struct * tty)
 {
-       while (!(current->signal & ~current->blocked) &&
-              !EMPTY(&tty->write_q)) {
+       struct wait_queue wait = { current, NULL };
+
+       TTY_WRITE_FLUSH(tty);
+       if (EMPTY(&tty->write_q))
+               return;
+       add_wait_queue(&tty->write_q.proc_list, &wait);
+       current->counter = 0;   /* make us low-priority */
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               if (current->signal & ~current->blocked)
+                       break;
                TTY_WRITE_FLUSH(tty);
-               current->counter = 0;
-               cli();
                if (EMPTY(&tty->write_q))
                        break;
-               else
-                       interruptible_sleep_on(&tty->write_q.proc_list);
-               sti();
+               schedule();
        }
-       sti();
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&tty->write_q.proc_list, &wait);
 }
 
 static int do_get_ps_info(int arg)
@@ -333,7 +339,14 @@ int tty_ioctl(struct inode * inode, struct file * file,
                case TIOCNXCL:
                        return -EINVAL; /* not implemented */
                case TIOCSCTTY:
-                       return -EINVAL; /* set controlling term NI */
+                       if (current->leader && current->tty < 0
+                           && tty->session == 0) {
+                               current->tty = dev;
+                               tty->session = current->session;
+                               tty->pgrp = current->pgrp;
+                               return 0;
+                       }
+                       return -EPERM;
                case TIOCGPGRP:
                        verify_area((void *) arg,4);
                        put_fs_long(termios_tty->pgrp,(unsigned long *) arg);
index 55ec8c71333d18d80aef0641a0678d9d4aca6b18..c3fe5141dd9ef08bec41561a5bd3a339cd98d816 100644 (file)
@@ -32,8 +32,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-
-void irq13(void);
+#define CR0_NE 32
 
 static unsigned long intr_count=0;
 
@@ -41,55 +40,25 @@ static unsigned long intr_count=0;
 int bh_active=0;
 struct bh_struct bh_base[32]; 
 
-/* interrupts should be on at the interrupt priority controller level. */
-/* returns with interrupts off at the processor level. */
-
+/*
+ * do_bottom_half() runs at normal kernel priority: all interrupts
+ * enabled.  do_bottom_half() is atomic with respect to itself: a
+ * bottom_half handler need not be re-entrant.  This function is
+ * called only when bh_active is non-zero and when there aren't any
+ * nested irq's active.
+ */
 void do_bottom_half(void)
 {
        struct bh_struct *bh;
-       int mask;
-       int count;
-       static int in_bh = 0;
-
-       cli();
-       if (intr_count > 1) {
-               intr_count--;
-               return;
-       }
-  /* don't just decrement it in case it is already 0 */
-
-       intr_count = 0;
-
-  /* any sort of real time test should go here. */
-       if (in_bh != 0) {
-               return;
-       }
-
-       in_bh = 1;
-       do {
-               count = 0;
-               for (mask = 1, bh = bh_base; mask ; bh++, mask = mask << 1) {
-                       if (mask > bh_active)
-                               break;
-                       if (!(mask & bh_active))
-                               continue;
+       int nr;
 
-                       count++;
-                       bh_active &= ~mask;
-
-                       /* turn the interrupts back on. */
-                       sti();
-
-                       if (bh->routine != NULL)
-                               bh->routine(bh->data);
-                       else
-                               printk ("irq.c:bad bottom half entry.\n");
-
-               /* and back off. */
-                       cli();
-               }
-       } while (count > 0);
-       in_bh = 0;
+       __asm__ __volatile__("bsfl %1,%0":"=r" (nr):"m" (bh_active));
+       __asm__ __volatile__("btcl %1,%0":"=m" (bh_active):"r" (nr));
+       bh = bh_base+nr;
+       if (bh->routine != NULL)
+               bh->routine(bh->data);
+       else
+               printk ("irq.c:bad bottom half entry.\n");
 }
 
 /*
@@ -267,12 +236,24 @@ void free_irq(unsigned int irq)
 
 extern void do_coprocessor_error(long,long);
 
+/*
+ * Note that on a 486, we don't want to do a SIGFPE on a irq13
+ * as the irq is unreliable, and exception 16 works correctly
+ * (ie as explained in the intel litterature). On a 386, you
+ * can't use exception 16 due to bad IBM design, so we have to
+ * rely on the less exact irq13.
+ */
 static void math_error_irq(int cpl)
 {
        outb(0,0xF0);
        do_coprocessor_error(0,0);
 }
 
+static void math_error_irq_486(int cpl)
+{
+       outb(0,0xF0);   /* even this is probably not needed.. */
+}
+
 static void no_action(int cpl) { }
 
 static struct sigaction ignore_IRQ = {
@@ -285,20 +266,25 @@ static struct sigaction ignore_IRQ = {
 void init_IRQ(void)
 {
        int i;
+       unsigned long cr0;
 
        for (i = 0; i < 16 ; i++)
                set_intr_gate(0x20+i,bad_interrupt[i]);
        if (irqaction(2,&ignore_IRQ))
                printk("Unable to get IRQ2 for cascade\n");
-       if (request_irq(13,math_error_irq))
+       __asm__("movl %%cr0,%%eax":"=a" (cr0));
+       if (cr0 & CR0_NE)
+               i = request_irq(13,math_error_irq_486);
+       else
+               i = request_irq(13,math_error_irq);
+       if (i)
                printk("Unable to get IRQ13 for math-error handler\n");
 
        /* intialize the bottom half routines. */
-       for (i = 0; i < 32; i++)
-         {
-           bh_base[i].routine = NULL;
-           bh_base[i].data = NULL;
-         }
+       for (i = 0; i < 32; i++) {
+               bh_base[i].routine = NULL;
+               bh_base[i].data = NULL;
+       }
        bh_active = 0;
-
+       intr_count = 0;
 }
index 69e35439ca3db41dee8ba20e24e0790a4dd2b2f3..3276ac26d98c8f10cd1688eba69960d8a8a8e61f 100644 (file)
@@ -74,11 +74,11 @@ void math_state_restore()
 {
        if (last_task_used_math == current)
                return;
-       __asm__("fwait");
        if (last_task_used_math) {
                __asm__("fnsave %0"::"m" (last_task_used_math->tss.i387));
        }
-       last_task_used_math=current;
+       __asm__("fwait");
+       last_task_used_math = current;
        if (current->used_math) {
                __asm__("frstor %0"::"m" (current->tss.i387));
        } else {
index 3507ed3d232cb567948e900d046b84b839db5f79..fa58a9adfb1a39c6d4cd0f6477dddc65fc9abd36 100644 (file)
@@ -149,6 +149,9 @@ _system_call:
        call _schedule
        .align 4,0x90
 ret_from_sys_call:
+/*
+ * XXX - interrupts are masked here about 3 times in 1000.  Fishy.
+ */
        movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
        testl $VM_MASK,%eax             # different then
        jne 4f
@@ -172,11 +175,11 @@ ret_from_sys_call:
        movl blocked(%eax),%ecx
        notl %ecx
        andl %ebx,%ecx
+       je 2f                           # XXX - branch is almost always taken
        bsfl %ecx,%ecx
-       je 2f
-       btrl %ecx,%ebx
+       btrl %ecx,signal(%eax)          # change atomically (%ebx is stale)
+       jnc 2f                          # bit became clear (can't happen?)
        incl %ecx
-       movl %ebx,signal(%eax)
        movl %esp,%ebx
        testl $VM_MASK,EFLAGS(%esp)
        je 3f
index 3a8cb12502b4dcf550e330e63350dd626c8d85f5..00b8eff099101db3b12c81093ef067a85edfecc3 100644 (file)
@@ -286,7 +286,7 @@ dev_rint(unsigned char *buff, long len, int flags,
    sti();
    
    if (backlog != NULL)
-     bh_active |= 1 << INET_BH;
+     mark_bh(INET_BH);
 
   return (0);
 }
index ec2c4d597ca6263e36c4480803797877346bcf8e..c15247fe93392d00cf46ca204c30c20a0bff3bc5 100644 (file)
@@ -184,29 +184,9 @@ unix_proto_recv(struct socket *sock, void *buff, int len, int nonblock,
        return (unix_proto_read (sock, buff, len, nonblock));
 }
 
-/*
- * Since unix domain sockets use filenames to communicate, two sockets are
- * the same if their strings are the same, even if their lengths are different
- * (due to possible null terminations). Verified under SunOS 4.1.2
- */
-static int
-same_path(char *s1, int l1, char *s2, int l2)
-{
-       /*
-        * Skip chars while they're equal
-        */
-       for (; l1 && l2 && *s1 == *s2; ++s1, ++s2, --l1, --l2);
-
-       /*
-        * Both must be exhausted, or one must be null terminated and the
-        * other either exhausted or null terminated, for the paths to be
-        * equivalent
-        */
-       return ((l1 == 0 || *s1 == '\0') && (l2 == 0 || *s2 == '\0'));
-}
-
 static struct unix_proto_data *
-unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
+unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len,
+                struct inode *inode)
 {
        struct unix_proto_data *upd;
 
@@ -214,9 +194,7 @@ unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
                if (upd->refcnt && upd->socket &&
                    upd->socket->state == SS_UNCONNECTED &&
                    upd->sockaddr_un.sun_family == sockun->sun_family &&
-                   same_path(sockun->sun_path, sockaddr_len - UN_PATH_OFFSET,
-                             upd->sockaddr_un.sun_path,
-                             upd->sockaddr_len - UN_PATH_OFFSET))
+                   upd->inode == inode)
                        return upd;
        }
        return NULL;
@@ -386,6 +364,7 @@ unix_proto_bind(struct socket *sock, struct sockaddr *umyaddr,
 #ifdef SOCK_DEBUG
        sockaddr_un_printk(&upd->sockaddr_un, upd->sockaddr_len);
 #endif
+       PRINTK("to inode 0x%x\n", upd->inode);
        return 0;
 }
 
@@ -400,6 +379,9 @@ unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
        int i;
        struct unix_proto_data *serv_upd;
        struct sockaddr_un sockun;
+       char fname[sizeof(((struct sockaddr_un *)0)->sun_path) + 1];
+       unsigned long old_fs;
+       struct inode *inode;
 
        PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
               sockaddr_len);
@@ -423,8 +405,28 @@ unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
                       sockun.sun_family, AF_UNIX);
                return -EINVAL;
        }
-       if (!(serv_upd = unix_data_lookup(&sockun, sockaddr_len))) {
-               PRINTK("unix_proto_connect: can't locate peer\n");
+
+       /*
+        * try to open the name in the filesystem - this is how we
+        * identify ourselves and our server. Note that we don't
+        * hold onto the inode that long, just enough to find our
+        * server. When we're connected, we mooch off the server.
+        */
+       memcpy(fname, sockun.sun_path, sockaddr_len-UN_PATH_OFFSET);
+       fname[sockaddr_len-UN_PATH_OFFSET] = '\0';
+       old_fs = get_fs();
+       set_fs(get_ds());
+       i = open_namei(fname, 0, S_IFSOCK, &inode, NULL);
+       set_fs(old_fs);
+       if (i < 0) {
+               PRINTK("unix_proto_connect: can't open socket %s\n", fname);
+               return i;
+       }
+       serv_upd = unix_data_lookup(&sockun, sockaddr_len, inode);
+       iput(inode);
+       if (!serv_upd) {
+               PRINTK("unix_proto_connect: can't locate peer %s at inode 0x%x\n",
+                       fname, inode);
                return -EINVAL;
        }
        if ((i = sock_awaitconn(sock, serv_upd->socket)) < 0) {
@@ -437,7 +439,7 @@ unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
 }
 
 /*
- * to do a socketpair, we make just connect the two datas, easy! since we
+ * to do a socketpair, we just connect the two datas, easy! since we
  * always wait on the socket inode, they're no contention for a wait area,
  * and deadlock prevention in the case of a process writing to itself is,
  * ignored, in true unix fashion!
index d7005c682fb53c3a16fafafec54056f8be95175a..8dd7ccf1affc1b11d0e5b23be1e6e852533600f0 100644 (file)
 #include <sys/sysmacros.h>
 #include <unistd.h>    /* contains read/write */
 #include <fcntl.h>
+#include <linux/config.h>
 
 #define MINIX_HEADER 32
 #define GCC_HEADER 1024
 
-#define SYS_SIZE 0x7000
+#define SYS_SIZE DEF_SYSSIZE
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
 
 #define STRINGIFY(x) #x
 
+typedef union {
+       long l;
+       short s[2];
+       char b[4];
+} conv;
+
+long intel_long(long l)
+{
+       conv t;
+
+       t.b[0] = l & 0xff; l >>= 8;
+       t.b[1] = l & 0xff; l >>= 8;
+       t.b[2] = l & 0xff; l >>= 8;
+       t.b[3] = l & 0xff; l >>= 8;
+       return t.l;
+}
+
+short intel_short(short l)
+{
+       conv t;
+
+       t.b[0] = l & 0xff; l >>= 8;
+       t.b[1] = l & 0xff; l >>= 8;
+       return t.s[0];
+}
+
 void die(char * str)
 {
        fprintf(stderr,"%s\n",str);
@@ -85,9 +112,9 @@ int main(int argc, char ** argv)
                die("Unable to open 'boot'");
        if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
                die("Unable to read header of 'boot'");
-       if (((long *) buf)[0]!=0x04100301)
+       if (((long *) buf)[0]!=intel_long(0x04100301))
                die("Non-Minix header of 'boot'");
-       if (((long *) buf)[1]!=MINIX_HEADER)
+       if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
                die("Non-Minix header of 'boot'");
        if (((long *) buf)[3]!=0)
                die("Illegal data segment in 'boot'");
@@ -101,7 +128,7 @@ int main(int argc, char ** argv)
        fprintf(stderr,"Boot sector %d bytes.\n",i);
        if (i != 512)
                die("Boot block must be exactly 512 bytes");
-       if ((*(unsigned short *)(buf+510)) != 0xAA55)
+       if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
                die("Boot block hasn't got boot flag (0xAA55)");
        buf[508] = (char) minor_root;
        buf[509] = (char) major_root;   
@@ -114,9 +141,9 @@ int main(int argc, char ** argv)
                die("Unable to open 'setup'");
        if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
                die("Unable to read header of 'setup'");
-       if (((long *) buf)[0]!=0x04100301)
+       if (((long *) buf)[0]!=intel_long(0x04100301))
                die("Non-Minix header of 'setup'");
-       if (((long *) buf)[1]!=MINIX_HEADER)
+       if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
                die("Non-Minix header of 'setup'");
        if (((long *) buf)[3]!=0)
                die("Illegal data segment in 'setup'");