]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Linux-0.97.5 (September 12, 1992) 0.97.5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:05 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:05 +0000 (15:09 -0500)
SCSI CD-ROM support by David Giller (based on sd.c by Drew)

Microsoft Busmouse support by Teemu Rantanen

Do the same buffer cleanups to extfs that we just did to Minixfs.

Efficient VGA emulation in dosemu wanted to know when we write
to the pseudo-VGA memory area. Add vm86 mode hooks for that.

[Original announcement below]

Patch 5 fixes the extended filesystem problems (thanks to Remy Card), as
well as including many smaller fixes (some more fs cleanups, the CDROM
patches and several other minor changes).  Pl5 finally removes even the
last few header-files that were incompatible with the normal headers, so
the "-nostdinc -I$(KERNELHDRS)" stuff is gone.

Patch 5 should also fix the problems with iopl() that resulted in the
X8514-server having problems with 0.97.pl2 and above.

In case people are wondering, my schedule for 1.0 looks something like
this:

 - 0.98 out in about a week: this is essentially 0.97.5 + the tcp/ip
   directory, as well as any fixes that may come up.  I'll try to get
   the loadable driver interface into it too.

 - 0.99 out after 0.98 has been shaken down: a month or so.

 - 1.0 will be the same as 0.99: the only changes will be eventual
   trivial bug-fixes in case 0.99 has some problems.  This is just to
   try to get over the "X.0" bug syndrome.

There are a few on-going projects: depending on circumstances these will
be implemented sooner or later, so I won't give any promises.  These
include: loadable drivers/fs's (alpha-patches already availabla), full
support for different block-sizes (some work still required), and a
extensive rewrite of the mm routines (I'll want to make a vmm interface
similar to the vfs interface for the filesystem routines).

                Linus

74 files changed:
Makefile
README
boot/setup.S
fs/Makefile
fs/buffer.c
fs/ext/blkdev.c
fs/ext/chrdev.c
fs/ext/dir.c
fs/ext/file.c
fs/ext/freelists.c
fs/ext/inode.c
fs/ext/namei.c
fs/ext/symlink.c
fs/ext/truncate.c
fs/fifo.c
fs/inode.c
fs/ioctl.c
fs/minix/inode.c
fs/minix/namei.c
fs/minix/truncate.c
fs/msdos/fat.c
fs/namei.c
fs/pipe.c
fs/select.c
fs/stat.c
include/asm/io.h
include/linux/busmouse.h
include/linux/cdrom.h [new file with mode: 0644]
include/linux/config.dist.h
include/linux/config.h
include/linux/ext_fs.h
include/linux/ext_fs_i.h
include/linux/fs.h
include/linux/kd.h [new file with mode: 0644]
include/linux/minix_fs_i.h
include/linux/mktime.h [new file with mode: 0644]
include/linux/mman.h [new file with mode: 0644]
include/linux/mouse.h
include/linux/pipe_fs_i.h [new file with mode: 0644]
include/linux/sched.h
include/linux/tty.h
include/linux/vm86.h
include/linux/vt.h [new file with mode: 0644]
init/main.c
kernel/Makefile
kernel/blk_drv/Makefile
kernel/blk_drv/blk.h
kernel/blk_drv/floppy.c
kernel/blk_drv/ll_rw_blk.c
kernel/blk_drv/scsi/Makefile
kernel/blk_drv/scsi/aha1542.c
kernel/blk_drv/scsi/scsi.c
kernel/blk_drv/scsi/scsi.h
kernel/blk_drv/scsi/sd.c
kernel/blk_drv/scsi/sr.c [new file with mode: 0644]
kernel/blk_drv/scsi/sr.h [new file with mode: 0644]
kernel/blk_drv/scsi/sr_ioctl.c [new file with mode: 0644]
kernel/chr_drv/Makefile
kernel/chr_drv/busmouse.c
kernel/chr_drv/console.c
kernel/chr_drv/keyboard.c
kernel/chr_drv/mouse.c
kernel/chr_drv/serial.c
kernel/chr_drv/tty_io.c
kernel/chr_drv/tty_ioctl.c
kernel/chr_drv/vt.c
kernel/mktime.c
kernel/sys.c
kernel/sys_call.S
lib/malloc.c
mm/memory.c
mm/mmap.c
mm/swap.c
net/Makefile

index 26cbba78fc7a5a96c7e81711b283a763dcf8b16b..dc3a34ef37d4978a17045776455adaf6c0f2506b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,12 @@ KEYBOARD = -DKBD_FINNISH -DKBDFLAGS=0
 # KEYBOARD = -DKBD_SG_LATIN1 -DKBDFLAGS=0x9F
 # KEYBOARD = -DKDB_NO
 
+#
+# comment this line to turn off keyboard NUM LOCK
+#
+
+NUM_LOCK = -DKBD_NUMERIC_LOCK
+
 #
 # comment this line if you don't want the emulation-code
 #
@@ -78,7 +84,7 @@ LD86  =ld86 -0
 AS     =as
 LD     =ld
 HOSTCC =gcc -static
-CC     =gcc -nostdinc -I$(KERNELHDRS) $(PROFILING)
+CC     =gcc -DKERNEL
 MAKE   =make
 CPP    =$(CC) -E
 AR     =ar
@@ -112,7 +118,7 @@ linuxsubdirs: dummy
 
 Version:
        @./makever.sh
-       @echo \#define UTS_RELEASE \"0.97.pl4-`cat .version`\" > tools/version.h
+       @echo \#define UTS_RELEASE \"0.97.pl5-`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
diff --git a/README b/README
index 2b090c590b4e461b45279a72cc8d9dff02f756f0..9868ea511abbb20ed8a238965ded6dcff19f1ce7 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,10 @@
 
+ [ NOTE! As of linux-0.97.pl5, the linux kernel include-files have
+   finally been totally integrated with the normal headers.  That means
+   no more "-nostdinc -I$(KERNELHDRS)" in the Makefiles etc, but it
+   also means that you /have/ to have the correct /usr/include/linux
+   and ../asm symlinks. See "Basic configuration 2" ]
+
        VERY QUICK AND DIRTY README
            by Lars Wirzenius
 
@@ -30,22 +36,18 @@ the FPU if it finds one, even with MATH_EMULATION defined.  The kernel
 will be slightly bigger.  It is probably not worth it to recompile the
 kernel just to get rid of the emulation.
 
-[ Linus' note1: if you have a correctly installed gcc-2.2.2d, you can
-  also remove the "-nostdinc -I$(KERNELHDRS)" thing from the main
-  Makefile CC definition. But it doesn't hurt to have it, as long as
-  KERNELHDRS is correctly defined ]
-
-2.  Create a symlink:
+2.  Create the symlinks:
 
-       ln -s /usr/src/linux/include/linux /usr/include/linux 
+       ln -fs /usr/src/linux/include/linux /usr/include/linux 
+       ln -fs /usr/src/linux/include/asm /usr/include/asm
 
-This is required so that tools/build.c will compile and link (it
-requires the standard versions of headers instead of the kernel specific
-headers, as it is a normal application, not kernel code).
+This is required so that the linux sources will correctly find their
+header files - it is also used by the normal user-level header files to
+get some system-specific information.
 
-[ Linus' note2: This is automatically done by the gcc-2.2.2d
+[ Linus' note2: This is automatically done by the gcc-2.2.2d and newer
   installation script, so if you have the new compiler, you should
-  already have this link ]
+  already have these links ]
 
 * Things you may want to get rid of
 
index 5c5266e97d7dd8597523621f650e96195c1d1c4e..179cda8ef52ebd77cb80ea870977a66f617e0b5b 100644 (file)
@@ -280,8 +280,8 @@ chsvga:     cld
        mov     ax,#0xc000
        mov     es,ax
        lea     si,msg1
-       call    prtstr
 #ifndef SVGA_MODE
+       call    prtstr
 flush: in      al,#0x60                ! Flush the keyboard buffer
        cmp     al,#0x82
        jb      nokey
@@ -425,6 +425,17 @@ l1:        inc     si
        lea     cx,selmod
        jmp     cx
 nogen: cld
+       lea     si,idoakvga
+       mov     di,#0x08
+       mov     cx,#0x08
+       repe
+       cmpsb
+       jne     nooak
+       lea     si,dscoakvga
+       lea     di,mooakvga
+       lea     cx,selmod
+       jmp     cx
+nooak: cld
        lea     si,idparadise           ! Check Paradise 'clues'
        mov     di,#0x7d
        mov     cx,#0x04
@@ -688,6 +699,7 @@ idati:              .ascii  "761295520"
 idcandt:       .byte   0xa5
 idgenoa:       .byte   0x77, 0x00, 0x66, 0x99
 idparadise:    .ascii  "VGA="
+idoakvga:      .ascii  "OAK VGA "
 
 ! Manufacturer:          Numofmodes:   Mode:
 
@@ -701,6 +713,7 @@ moparadise: .byte   0x02,   0x55, 0x54
 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
 
 !                      msb = Cols lsb = Rows:
 
@@ -714,6 +727,7 @@ dscparadise:        .word   0x8419, 0x842b
 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
        
 .text
 endtext:
index 0da3da264ff4f0f108e77cc8c795588f6e7a8b87..2491aecd618c6a3bc039cf58a39ada9881184298 100644 (file)
@@ -35,7 +35,7 @@ clean:
 
 depend dep:
        sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-       for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+       $(CPP) -M *.c >> tmp_make
        cp tmp_make Makefile
        for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
 
index 8729986e08aa0105cc33fda924ddc1bdc134407b..62517dab0413fa8c9a17be19ada6f4da9250355b 100644 (file)
 #include <asm/system.h>
 #include <asm/io.h>
 
+#ifdef CONFIG_BLK_DEV_SR
+extern int check_cdrom_media_change(int, int);
+#endif
+
 static struct buffer_head * hash_table[NR_HASH];
 static struct buffer_head * free_list = NULL;
 static struct buffer_head * unused_list = NULL;
@@ -121,14 +125,27 @@ void check_disk_change(int dev)
        int i;
        struct buffer_head * bh;
 
-       if (MAJOR(dev) != 2)
-               return;
-       if (!(bh = getblk(dev,0,1024)))
-               return;
-       i = floppy_change(bh);
-       brelse(bh);
-       if (!i)
+       switch(MAJOR(dev)){
+       case 2: /* floppy disc */
+               if (!(bh = getblk(dev,0,1024)))
+                       return;
+               i = floppy_change(bh);
+               brelse(bh);
+               break;
+
+#ifdef CONFIG_BLK_DEV_SR
+         case 11: /* CDROM */
+               i = check_cdrom_media_change(dev, 0);
+               if (i) printk("Flushing buffers and inodes for CDROM\n");
+               break;
+#endif
+
+         default:
                return;
+       };
+
+       if (!i) return;
+
        for (i=0 ; i<NR_SUPER ; i++)
                if (super_block[i].s_dev == dev)
                        put_super(super_block[i].s_dev);
index 74dd9fe703b46173ba471e4b34ab06c940c9275b..5745c7d8828bb13dcf10650bb4d4336e1f49c215 100644 (file)
@@ -62,6 +62,6 @@ struct inode_operations ext_blkdev_inode_operations = {
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
-       ext_bmap,               /* bmap */
-       ext_truncate            /* truncate */
+       NULL,                   /* bmap */
+       NULL                    /* truncate */
 };
index b1b55ea2d9db359f59508a5b1de7eff2abf15363..18f9fb246912fb39bcca9df2bcef7700a7bb8a34 100644 (file)
@@ -62,7 +62,7 @@ struct inode_operations ext_chrdev_inode_operations = {
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
-       ext_bmap,               /* bmap */
-       ext_truncate            /* truncate */
+       NULL,                   /* bmap */
+       NULL                    /* truncate */
 };
 
index 48cefa2845b47a53c09ddd0349a67f7da04112d8..9de7af7ea67c91f0029f684dcf288a9a78e12b6c 100644 (file)
@@ -48,14 +48,14 @@ struct inode_operations ext_dir_inode_operations = {
        ext_rename,             /* rename */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
-       ext_bmap,               /* bmap */
+       NULL,                   /* bmap */
        ext_truncate            /* truncate */
 };
 
 static int ext_readdir(struct inode * inode, struct file * filp,
        struct dirent * dirent, int count)
 {
-       unsigned int block,offset,i;
+       unsigned int offset,i;
        char c;
        struct buffer_head * bh;
        struct ext_dir_entry * de;
@@ -64,8 +64,8 @@ static int ext_readdir(struct inode * inode, struct file * filp,
                return -EBADF;
        while (filp->f_pos < inode->i_size) {
                offset = filp->f_pos & 1023;
-               block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
-               if (!block || !(bh = bread(inode->i_dev, block, BLOCK_SIZE))) {
+               bh = ext_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
+               if (!bh) {
                        filp->f_pos += 1024-offset;
                        continue;
                }
index ec366aa21fc0df14f1b3e5fbbd4d1be6241e23af..d8f36637291a4591720998f9781068a02a716ae1 100644 (file)
 #include <linux/fs.h>
 #include <linux/ext_fs.h>
 
+static inline void wait_on_buffer(struct buffer_head * bh)
+{
+       cli();
+       while (bh->b_lock)
+               sleep_on(&bh->b_wait);
+       sti();
+}
+
 static int ext_file_read(struct inode *, struct file *, char *, int);
 static int ext_file_write(struct inode *, struct file *, char *, int);
 
@@ -65,17 +73,9 @@ struct inode_operations ext_file_inode_operations = {
        ext_truncate            /* truncate */
 };
 
-static inline void wait_on_buffer(struct buffer_head * bh)
-{
-       cli();
-       while (bh->b_lock)
-               sleep_on(&bh->b_wait);
-       sti();
-}
-
 static int ext_file_read(struct inode * inode, struct file * filp, char * buf, int count)
 {
-       int read,left,chars,nr;
+       int read,left,chars;
        int block, blocks, offset;
        struct buffer_head ** bhb, ** bhe;
        struct buffer_head * buflist[NBUF];
@@ -104,12 +104,9 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
        do {
                if (blocks) {
                        --blocks;
-                       if (nr = ext_bmap(inode,block++)) {
-                               *bhb = getblk(inode->i_dev, nr, BLOCK_SIZE);
-                               if (!(*bhb)->b_uptodate)
-                                       ll_rw_block(READ,*bhb);
-                       } else
-                               *bhb = NULL;
+                       *bhb = ext_getblk(inode,block++,0);
+                       if (*bhb && !(*bhb)->b_uptodate)
+                               ll_rw_block(READ,*bhb);
 
                        if (++bhb == &buflist[NBUF])
                                bhb = buflist;
@@ -160,7 +157,7 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
 static int ext_file_write(struct inode * inode, struct file * filp, char * buf, int count)
 {
        off_t pos;
-       int written,block,c;
+       int written,c;
        struct buffer_head * bh;
        char * p;
 
@@ -182,7 +179,8 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
                pos = filp->f_pos;
        written = 0;
        while (written<count) {
-               if (!(block = ext_create_block(inode,pos/BLOCK_SIZE))) {
+               bh = ext_getblk(inode,pos/BLOCK_SIZE,1);
+               if (!bh) {
                        if (!written)
                                written = -ENOSPC;
                        break;
@@ -190,14 +188,15 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
                c = BLOCK_SIZE - (pos % BLOCK_SIZE);
                if (c > count-written)
                        c = count-written;
-               if (c == BLOCK_SIZE)
-                       bh = getblk(inode->i_dev, block, BLOCK_SIZE);
-               else
-                       bh = bread(inode->i_dev, block, BLOCK_SIZE);
-               if (!bh) {
-                       if (!written)
-                               written = -EIO;
-                       break;
+               if (c != BLOCK_SIZE && !bh->b_uptodate) {
+                       ll_rw_block(READ,bh);
+                       wait_on_buffer(bh);
+                       if (!bh->b_uptodate) {
+                               brelse(bh);
+                               if (!written)
+                                       written = -EIO;
+                               break;
+                       }
                }
                p = (pos % BLOCK_SIZE) + bh->b_data;
                pos += c;
index a2f6ed372a1d3a108042ca67a0dae411899c4d97..848652809d97468b30780ada91f430b22307fc57 100644 (file)
@@ -41,7 +41,7 @@ __asm__("cld\n\t" \
         "stosl" \
         ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
 
-int ext_free_block(int dev, int block)
+void ext_free_block(int dev, int block)
 {
        struct super_block * sb;
        struct buffer_head * bh;
@@ -50,21 +50,15 @@ int ext_free_block(int dev, int block)
        if (!(sb = get_super(dev)))
                panic("trying to free block on nonexistent device");
        lock_super (sb);
-       if (block < sb->u.ext_sb.s_firstdatazone
-               || block >= sb->u.ext_sb.s_nzones)
-               panic("trying to free block not in datazone");
+       if (block < sb->u.ext_sb.s_firstdatazone ||
+           block >= sb->u.ext_sb.s_nzones) {
+               printk("trying to free block not in datazone\n");
+               return;
+       }
        bh = get_hash_table(dev, block, sb->s_blocksize);
-       if (bh) {
-               if (bh->b_count > 1) {
-                       brelse(bh);
-                       free_super (sb);
-                       return 0;
-               }
+       if (bh)
                bh->b_dirt=0;
-               bh->b_uptodate=0;
-               if (bh->b_count)
-                       brelse(bh);
-       }
+       brelse(bh);
        if (sb->u.ext_sb.s_firstfreeblock)
                efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
        if (!sb->u.ext_sb.s_firstfreeblock || efb->count == 254) {
@@ -87,7 +81,7 @@ printk("ext_free_block: block full, skipping to %d\n", block);
        sb->s_dirt = 1;
        sb->u.ext_sb.s_firstfreeblock->b_dirt = 1;
        free_super (sb);
-       return 1;
+       return;
 }
 
 int ext_new_block(int dev)
index e8874e53f9e0cfa5f734467c3b1f2e802f4ac3ac..f2f37b4bd11a54a1f1057ae883e7c056596d95fc 100644 (file)
 
 int sync_dev(int dev);
 
+static inline void wait_on_buffer(struct buffer_head * bh)
+{
+       cli();
+       while (bh->b_lock)
+               sleep_on(&bh->b_wait);
+       sti();
+}
+
 void ext_put_inode(struct inode *inode)
 {
        inode->i_size = 0;
@@ -152,130 +160,190 @@ void ext_statfs (struct super_block *sb, struct statfs *buf)
        /* Don't know what value to put in buf->f_fsid */
 }
 
-static int _ext_bmap(struct inode * inode,int block,int create)
+#define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
+
+static int block_bmap(struct buffer_head * bh, int nr)
+{
+       int tmp;
+
+       if (!bh)
+               return 0;
+       tmp = ((unsigned long *) bh->b_data)[nr];
+       brelse(bh);
+       return tmp;
+}
+
+int ext_bmap(struct inode * inode,int block)
 {
-       struct buffer_head * bh;
        int i;
 
        if (block<0) {
-               printk("_ext_bmap: block<0");
+               printk("ext_bmap: block<0");
                return 0;
        }
        if (block >= 9+256+256*256+256*256*256) {
-               printk("_ext_bmap: block>big");
+               printk("ext_bmap: block>big");
                return 0;
        }
-       if (block<9) {
-               if (create && !inode->i_data[block])
-                       if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
-                               inode->i_ctime=CURRENT_TIME;
-                               inode->i_dirt=1;
-                       }
-               return inode->i_data[block];
-       }
+       if (block<9)
+               return inode_bmap(inode,block);
        block -= 9;
        if (block<256) {
-               if (create && !inode->i_data[9])
-                       if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
-                               inode->i_dirt=1;
-                               inode->i_ctime=CURRENT_TIME;
-                       }
-               if (!inode->i_data[9])
-                       return 0;
-               if (!(bh = bread(inode->i_dev, inode->i_data[9], BLOCK_SIZE)))
+               i = inode_bmap(inode,9);
+               if (!i)
                        return 0;
-               i = ((unsigned long *) (bh->b_data))[block];
-               if (create && !i)
-                       if (i=ext_new_block(inode->i_dev)) {
-                               ((unsigned long *) (bh->b_data))[block]=i;
-                               bh->b_dirt=1;
-                       }
-               brelse(bh);
-               return i;
+               return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
        }
        block -= 256;
        if (block<256*256) {
-               if (create && !inode->i_data[10])
-                       if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
-                               inode->i_dirt=1;
-                               inode->i_ctime=CURRENT_TIME;
-                       }
-               if (!inode->i_data[10])
-                       return 0;
-               if (!(bh=bread(inode->i_dev, inode->i_data[10], BLOCK_SIZE)))
-                       return 0;
-               i = ((unsigned long *)bh->b_data)[block>>8];
-               if (create && !i)
-                       if (i=ext_new_block(inode->i_dev)) {
-                               ((unsigned long *) (bh->b_data))[block>>8]=i;
-                               bh->b_dirt=1;
-                       }
-               brelse(bh);
+               i = inode_bmap(inode,10);
                if (!i)
                        return 0;
-               if (!(bh=bread(inode->i_dev, i, BLOCK_SIZE)))
+               i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
+               if (!i)
                        return 0;
-               i = ((unsigned long *)bh->b_data)[block&255];
-               if (create && !i)
-                       if (i=ext_new_block(inode->i_dev)) {
-                               ((unsigned long *) (bh->b_data))[block&255]=i;
-                               bh->b_dirt=1;
-                       }
-               brelse(bh);
-               return i;
+               return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
        }
-       if (create && !inode->i_data[11])
-               if (inode->i_data[11] = ext_new_block(inode->i_dev)) {
-                       inode->i_dirt = 1;
-                       inode->i_ctime = CURRENT_TIME;
-               }
-       if (!inode->i_data[11])
-               return 0;
-       if (!(bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE)))
-               return 0;
-       i = ((unsigned long *) bh->b_data)[block >> 16];
-       if (create && !i)
-               if (i = ext_new_block(inode->i_dev)) {
-                       ((unsigned long *) bh->b_data)[block >> 16] = i;
-                       bh->b_dirt = 1;
-               }
-       brelse (bh);
+       block -= 256*256;
+       i = inode_bmap(inode,11);
        if (!i)
                return 0;
-       if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
-               return 0;
-       i = ((unsigned long *) bh->b_data)[(block >> 8) & 255];
-       if (create && !i)
-               if (i = ext_new_block(inode->i_dev)) {
-                       ((unsigned long *) bh->b_data)[(block >> 8) & 255] = i;
-                       bh->b_dirt = 1;
-               }
-       brelse (bh);
+       i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
        if (!i)
                return 0;
-       if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
+       i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
+       if (!i)
                return 0;
-       i = ((unsigned long *) bh->b_data)[block & 255];
-       if (create && !i)
-               if (i = ext_new_block(inode->i_dev)) {
-                       ((unsigned long *) bh->b_data)[block & 255] = i;
-                       bh->b_dirt = 1;
+       return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
+}
+
+static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
+{
+       int tmp;
+       unsigned long * p;
+       struct buffer_head * result;
+
+       p = inode->u.ext_i.i_data + nr;
+repeat:
+       tmp = *p;
+       if (tmp) {
+               result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
+               if (tmp == *p)
+                       return result;
+               brelse(result);
+               goto repeat;
+       }
+       if (!create)
+               return NULL;
+       tmp = ext_new_block(inode->i_dev);
+       if (!tmp)
+               return NULL;
+       result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
+       if (*p) {
+               ext_free_block(inode->i_dev,tmp);
+               brelse(result);
+               goto repeat;
+       }
+       *p = tmp;
+       inode->i_ctime = CURRENT_TIME;
+       inode->i_dirt = 1;
+       return result;
+}
+
+static struct buffer_head * block_getblk(struct buffer_head * bh, int nr, int create)
+{
+       int tmp;
+       unsigned long * p;
+       struct buffer_head * result;
+
+       if (!bh)
+               return NULL;
+       if (!bh->b_uptodate) {
+               ll_rw_block(READ,bh);
+               wait_on_buffer(bh);
+               if (!bh->b_uptodate) {
+                       brelse(bh);
+                       return NULL;
                }
-       brelse (bh);
-       return i;
-       
-       printk("ext_bmap: triple indirection not yet implemented\n");
-       return 0;
+       }
+       p = nr + (unsigned long *) bh->b_data;
+repeat:
+       tmp = *p;
+       if (tmp) {
+               result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
+               if (tmp == *p) {
+                       brelse(bh);
+                       return result;
+               }
+               brelse(result);
+               goto repeat;
+       }
+       if (!create) {
+               brelse(bh);
+               return NULL;
+       }
+       tmp = ext_new_block(bh->b_dev);
+       if (!tmp) {
+               brelse(bh);
+               return NULL;
+       }
+       result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
+       if (*p) {
+               ext_free_block(bh->b_dev,tmp);
+               brelse(result);
+               goto repeat;
+       }
+       *p = tmp;
+       bh->b_dirt = 1;
+       brelse(bh);
+       return result;
 }
 
-int ext_bmap(struct inode * inode,int block)
+struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
 {
-       return _ext_bmap(inode,block,0);
+       struct buffer_head * bh;
+
+       if (block<0) {
+               printk("ext_getblk: block<0\n");
+               return NULL;
+       }
+       if (block >= 9+256+256*256+256*256*256) {
+               printk("ext_getblk: block>big\n");
+               return NULL;
+       }
+       if (block<9)
+               return inode_getblk(inode,block,create);
+       block -= 9;
+       if (block<256) {
+               bh = inode_getblk(inode,9,create);
+               return block_getblk(bh,block,create);
+       }
+       block -= 256;
+       if (block<256*256) {
+               bh = inode_getblk(inode,10,create);
+               bh = block_getblk(bh,block>>8,create);
+               return block_getblk(bh,block & 255,create);
+       }
+       block -= 256*256;
+       bh = inode_getblk(inode,11,create);
+       bh = block_getblk(bh,block>>16,create);
+       bh = block_getblk(bh,(block>>8) & 255,create);
+       return block_getblk(bh,block & 255,create);
 }
 
-int ext_create_block(struct inode * inode, int block)
+struct buffer_head * ext_bread(struct inode * inode, int block, int create)
 {
-       return _ext_bmap(inode,block,1);
+       struct buffer_head * bh;
+
+       bh = ext_getblk(inode,block,create);
+       if (!bh || bh->b_uptodate) 
+               return bh;
+       ll_rw_block(READ,bh);
+       wait_on_buffer(bh);
+       if (bh->b_uptodate)
+               return bh;
+       brelse(bh);
+       return NULL;
 }
 
 void ext_read_inode(struct inode * inode)
@@ -299,7 +367,7 @@ void ext_read_inode(struct inode * inode)
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                inode->i_rdev = raw_inode->i_zone[0];
        else for (block = 0; block < 12; block++)
-               inode->i_data[block] = raw_inode->i_zone[block];
+               inode->u.ext_i.i_data[block] = raw_inode->i_zone[block];
        brelse(bh);
        inode->i_op = NULL;
        if (S_ISREG(inode->i_mode))
@@ -314,8 +382,8 @@ void ext_read_inode(struct inode * inode)
                inode->i_op = &ext_blkdev_inode_operations;
        else if (S_ISFIFO(inode->i_mode)) {
                inode->i_op = &ext_fifo_inode_operations;
-               inode->i_size = 0;
                inode->i_pipe = 1;
+               PIPE_BASE(*inode) = NULL;
                PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
                PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
        }
@@ -341,7 +409,7 @@ void ext_write_inode(struct inode * inode)
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_zone[0] = inode->i_rdev;
        else for (block = 0; block < 12; block++)
-               raw_inode->i_zone[block] = inode->i_data[block];
+               raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
        bh->b_dirt=1;
        inode->i_dirt=0;
        brelse(bh);
index e63947b1edd1290ec243faf8ee726b3ba491a5eb..5c7e7f444247052e1af289fbec52657a502afa1d 100644 (file)
@@ -20,8 +20,6 @@
 
 #include <asm/segment.h>
 
-#include <const.h>
-
 /*
  * comment out this line if you want names > EXT_NAME_LEN chars to be
  * truncated. Else they will be disallowed.
@@ -90,7 +88,6 @@ static struct buffer_head * ext_find_entry(struct inode * dir,
        const char * name, int namelen, struct ext_dir_entry ** res_dir,
        struct ext_dir_entry ** prev_dir, struct ext_dir_entry ** next_dir)
 {
-       int block;
        long offset;
        struct buffer_head * bh;
        struct ext_dir_entry * de;
@@ -105,9 +102,8 @@ static struct buffer_head * ext_find_entry(struct inode * dir,
        if (namelen > EXT_NAME_LEN)
                namelen = EXT_NAME_LEN;
 #endif
-       if (!(block = dir->i_data[0]))
-               return NULL;
-       if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+       bh = ext_bread(dir,0,0);
+       if (!bh)
                return NULL;
        if (prev_dir)
                *prev_dir = NULL;
@@ -119,10 +115,9 @@ static struct buffer_head * ext_find_entry(struct inode * dir,
                if ((char *)de >= BLOCK_SIZE+bh->b_data) {
                        brelse(bh);
                        bh = NULL;
-                       if (!(block = ext_bmap(dir,offset>>BLOCK_SIZE_BITS)) ||
-                           !(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
+                       bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,0);
+                       if (!bh)
                                continue;
-                       }
                        de = (struct ext_dir_entry *) bh->b_data;
                        if (prev_dir)
                                *prev_dir = NULL;
@@ -187,7 +182,7 @@ int ext_lookup(struct inode * dir,const char * name, int len,
 static struct buffer_head * ext_add_entry(struct inode * dir,
        const char * name, int namelen, struct ext_dir_entry ** res_dir)
 {
-       int block,i;
+       int i;
        long offset;
        unsigned short rec_len;
        struct buffer_head * bh;
@@ -205,9 +200,8 @@ static struct buffer_head * ext_add_entry(struct inode * dir,
 #endif
        if (!namelen)
                return NULL;
-       if (!(block = dir->i_data[0]))
-               return NULL;
-       if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+       bh = ext_bread(dir,0,0);
+       if (!bh)
                return NULL;
        rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD;
        offset = 0;
@@ -219,13 +213,9 @@ printk ("ext_add_entry: skipping to next block\n");
 #endif
                        brelse(bh);
                        bh = NULL;
-                       block = ext_create_block(dir,offset>>BLOCK_SIZE_BITS);
-                       if (!block)
+                       bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,1);
+                       if (!bh)
                                return NULL;
-                       if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
-                               offset += BLOCK_SIZE;
-                               continue;
-                       }
                        de = (struct ext_dir_entry *) bh->b_data;
                }
                if (offset >= dir->i_size) {
@@ -248,13 +238,11 @@ printk ("ext_add_entry: skipping to next block\n");
                                }
                                brelse (bh);
                                bh = NULL;
-                               block = ext_create_block (dir,offset>>BLOCK_SIZE_BITS);
 #ifdef EXTFS_DEBUG
 printk ("ext_add_entry : creating next block\n");
 #endif
-                               if (!block)
-                                       return NULL;
-                               if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
+                               bh = ext_bread(dir,offset>>BLOCK_SIZE_BITS,1);
+                               if (!bh)
                                        return NULL; /* Other thing to do ??? */
                                de = (struct ext_dir_entry *) bh->b_data;
                        }
@@ -361,8 +349,8 @@ int ext_mknod(struct inode * dir, const char * name, int len, int mode, int rdev
                inode->i_op = &ext_blkdev_inode_operations;
        else if (S_ISFIFO(inode->i_mode)) {
                inode->i_op = &ext_fifo_inode_operations;
-               inode->i_size = 0;
                inode->i_pipe = 1;
+               PIPE_BASE(*inode) = NULL;
                PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
                PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
        }
@@ -410,21 +398,14 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
                                        - 2 bytes for the name length
                                        - 8 bytes for the name */
        inode->i_mtime = inode->i_atime = CURRENT_TIME;
-       if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+       dir_block = ext_bread(inode,0,1);
+       if (!dir_block) {
                iput(dir);
                inode->i_nlink--;
                inode->i_dirt = 1;
                iput(inode);
                return -ENOSPC;
        }
-       inode->i_dirt = 1;
-       if (!(dir_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
-               iput(dir);
-               inode->i_nlink--;
-               inode->i_dirt = 1;
-               iput(inode);
-               return -EIO;
-       }
        de = (struct ext_dir_entry *) dir_block->b_data;
        de->inode=inode->i_ino;
        de->rec_len=16;
@@ -438,7 +419,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
        inode->i_nlink = 2;
        dir_block->b_dirt = 1;
        brelse(dir_block);
-       inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
+       inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        inode->i_dirt = 1;
        bh = ext_add_entry(dir,name,len,&de);
        if (!bh) {
@@ -462,13 +443,11 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
  */
 static int empty_dir(struct inode * inode)
 {
-       int block;
        unsigned long offset;
        struct buffer_head * bh;
        struct ext_dir_entry * de, * de1;
 
-       if (inode->i_size < 2 * 12 || !inode->i_data[0] ||
-           !(bh=bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
+       if (inode->i_size < 2 * 12 || !(bh = ext_bread(inode,0,0))) {
                printk("warning - bad directory on dev %04x\n",inode->i_dev);
                return 1;
        }
@@ -484,13 +463,11 @@ static int empty_dir(struct inode * inode)
        while (offset < inode->i_size ) {
                if ((void *) de >= (void *) (bh->b_data+BLOCK_SIZE)) {
                        brelse(bh);
-                       block = ext_bmap(inode, offset >> BLOCK_SIZE_BITS);
-                       if (!block) {
+                       bh = ext_bread(inode, offset >> BLOCK_SIZE_BITS,1);
+                       if (!bh) {
                                offset += BLOCK_SIZE;
                                continue;
                        }
-                       if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
-                               return 0;
                        de = (struct ext_dir_entry *) bh->b_data;
                }
                if (de->inode) {
@@ -621,21 +598,14 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
        }
        inode->i_mode = S_IFLNK | 0777;
        inode->i_op = &ext_symlink_inode_operations;
-       if (!(inode->i_data[0] = ext_new_block(inode->i_dev))) {
+       name_block = ext_bread(inode,0,1);
+       if (!name_block) {
                iput(dir);
                inode->i_nlink--;
                inode->i_dirt = 1;
                iput(inode);
                return -ENOSPC;
        }
-       inode->i_dirt = 1;
-       if (!(name_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
-               iput(dir);
-               inode->i_nlink--;
-               inode->i_dirt = 1;
-               iput(inode);
-               return -EIO;
-       }
        i = 0;
        while (i < 1023 && (c=get_fs_byte(symname++)))
                name_block->b_data[i++] = c;
@@ -807,9 +777,8 @@ start_up:
                if (subdir(new_dir, old_inode))
                        goto end_rename;
                retval = -EIO;
-               if (!old_inode->i_data[0])
-                       goto end_rename;
-               if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0], BLOCK_SIZE)))
+               dir_bh = ext_bread(old_inode,0,0);
+               if (!dir_bh)
                        goto end_rename;
                if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
                        goto end_rename;
index 96b3b6e1695bfe8c671eea841da39bc7305c7791..210b1447c5ecd2fb65ced99bb50f0897bdc67864 100644 (file)
@@ -50,13 +50,13 @@ static int ext_follow_link(struct inode * dir, struct inode * inode,
        unsigned short fs;
        struct buffer_head * bh;
 
+       *res_inode = NULL;
        if (!dir) {
                dir = current->root;
                dir->i_count++;
        }
        if (!inode) {
                iput(dir);
-               *res_inode = NULL;
                return -ENOENT;
        }
        if (!S_ISLNK(inode->i_mode)) {
@@ -64,15 +64,18 @@ static int ext_follow_link(struct inode * dir, struct inode * inode,
                *res_inode = inode;
                return 0;
        }
-       __asm__("mov %%fs,%0":"=r" (fs));
-       if ((current->link_count > 5) || !inode->i_data[0] ||
-          !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
+       if (current->link_count > 5) {
                iput(dir);
                iput(inode);
-               *res_inode = NULL;
                return -ELOOP;
        }
+       if (!(bh = ext_bread(inode, 0, 0))) {
+               iput(inode);
+               iput(dir);
+               return -EIO;
+       }
        iput(inode);
+       __asm__("mov %%fs,%0":"=r" (fs));
        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
        current->link_count++;
        error = open_namei(bh->b_data,flag,mode,res_inode,dir);
@@ -94,10 +97,7 @@ static int ext_readlink(struct inode * inode, char * buffer, int buflen)
        }
        if (buflen > 1023)
                buflen = 1023;
-       if (inode->i_data[0])
-               bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
-       else
-               bh = NULL;
+       bh = ext_bread(inode, 0, 0);
        iput(inode);
        if (!bh)
                return 0;
index c32a0912b36ba7105f82eb499642c600fcaa3279..9d94f6418abbd1353fb2f5fe7a66a3909cb1d0e8 100644 (file)
 
 static int trunc_direct(struct inode * inode)
 {
-       int i;
-       int result = 0;
+       int i, tmp;
+       unsigned long * p;
+       struct buffer_head * bh;
+       int retry = 0;
 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
 
 repeat:
        for (i = DIRECT_BLOCK ; i < 9 ; i++) {
-               if (i < DIRECT_BLOCK)
+               p = inode->u.ext_i.i_data+i;
+               if (!(tmp = *p))
+                       continue;
+               bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
+               if (i < DIRECT_BLOCK) {
+                       brelse(bh);
                        goto repeat;
-               if (!inode->i_data[i])
+               }
+               if ((bh && bh->b_count != 1) || tmp != *p) {
+                       retry = 1;
+                       brelse(bh);
                        continue;
-               result = 1;
-               if (ext_free_block(inode->i_dev,inode->i_data[i]))
-                       inode->i_data[i] = 0;
+               }
+               *p = 0;
+               inode->i_dirt = 1;
+               brelse(bh);
+               ext_free_block(inode->i_dev,tmp);
        }
-       return result;
+       return retry;
 }
 
 static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
 {
-       int i;
-       struct buffer_head * bh = NULL;
+       int i, tmp;
+       struct buffer_head * bh;
+       struct buffer_head * ind_bh;
        unsigned long * ind;
-       int result = 0;
+       int retry = 0;
 #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
 
-       if (*p)
-               bh = bread(inode->i_dev, *p, BLOCK_SIZE);
-       if (!bh)
+       tmp = *p;
+       if (!tmp)
+               return 0;
+       ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+       if (tmp != *p) {
+               brelse(ind_bh);
+               return 1;
+       }
+       if (!ind_bh) {
+               *p = 0;
                return 0;
+       }
 repeat:
        for (i = INDIRECT_BLOCK ; i < 256 ; i++) {
                if (i < 0)
                        i = 0;
                if (i < INDIRECT_BLOCK)
                        goto repeat;
-               ind = i+(unsigned long *) bh->b_data;
-               if (!*ind)
+               ind = i+(unsigned long *) ind_bh->b_data;
+               tmp = *ind;
+               if (!tmp)
+                       continue;
+               bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
+               if (i < INDIRECT_BLOCK) {
+                       brelse(bh);
+                       goto repeat;
+               }
+               if ((bh && bh->b_count != 1) || tmp != *ind) {
+                       retry = 1;
+                       brelse(bh);
                        continue;
-               result = 1;
-               if (ext_free_block(inode->i_dev,*ind))
-                       *ind = 0;
+               }
+               *ind = 0;
+               ind_bh->b_dirt = 1;
+               brelse(bh);
+               ext_free_block(inode->i_dev,tmp);
        }
-       ind = (unsigned long *) bh->b_data;
+       ind = (unsigned long *) ind_bh->b_data;
        for (i = 0; i < 256; i++)
                if (*(ind++))
                        break;
-       brelse(bh);
-       if (i >= 256) {
-               result = 1;
-               if (ext_free_block(inode->i_dev,*p))
+       if (i >= 256)
+               if (ind_bh->b_count != 1)
+                       retry = 1;
+               else {
+                       tmp = *p;
                        *p = 0;
-       }
-       return result;
+                       inode->i_dirt = 1;
+                       ext_free_block(inode->i_dev,tmp);
+               }
+       brelse(ind_bh);
+       return retry;
 }
-               
+
 static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
 {
-       int i;
-       struct buffer_head * bh = NULL;
+       int i,tmp;
+       struct buffer_head * dind_bh;
        unsigned long * dind;
-       int result = 0;
+       int retry = 0;
 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8)
 
-       if (*p)
-               bh = bread(inode->i_dev, *p, BLOCK_SIZE);
-       if (!bh)
+       tmp = *p;
+       if (!tmp)
+               return 0;
+       dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+       if (tmp != *p) {
+               brelse(dind_bh);
+               return 1;
+       }
+       if (!dind_bh) {
+               *p = 0;
                return 0;
+       }
 repeat:
        for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) {
                if (i < 0)
                        i = 0;
                if (i < DINDIRECT_BLOCK)
                        goto repeat;
-               dind = i+(unsigned long *) bh->b_data;
-               if (!*dind)
+               dind = i+(unsigned long *) dind_bh->b_data;
+               tmp = *dind;
+               if (!tmp)
                        continue;
-               result |= trunc_indirect(inode,offset+(i<<8),dind);
+               retry |= trunc_indirect(inode,offset+(i<<8),dind);
+               dind_bh->b_dirt = 1;
        }
-       dind = (unsigned long *) bh->b_data;
+       dind = (unsigned long *) dind_bh->b_data;
        for (i = 0; i < 256; i++)
                if (*(dind++))
                        break;
-       brelse(bh);
-       if (i >= 256) {
-               result = 1;
-               if (ext_free_block(inode->i_dev,*p))
+       if (i >= 256)
+               if (dind_bh->b_count != 1)
+                       retry = 1;
+               else {
+                       tmp = *p;
                        *p = 0;
-       }
-       return result;
+                       inode->i_dirt = 1;
+                       ext_free_block(inode->i_dev,tmp);
+               }
+       brelse(dind_bh);
+       return retry;
 }
 
 static int trunc_tindirect(struct inode * inode)
 {
-       int i;
-       struct buffer_head * bh = NULL;
-       unsigned long * tind;
-       int result = 0;
+       int i,tmp;
+       struct buffer_head * tind_bh;
+       unsigned long * tind, * p;
+       int retry = 0;
 #define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16)
 
-       if (inode->i_data[11])
-               bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE);
-       if (!bh)
+       p = inode->u.ext_i.i_data+11;
+       if (!(tmp = *p))
                return 0;
+       tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
+       if (tmp != *p) {
+               brelse(tind_bh);
+               return 1;
+       }
+       if (!tind_bh) {
+               *p = 0;
+               return 0;
+       }
 repeat:
        for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) {
                if (i < 0)
                        i = 0;
                if (i < TINDIRECT_BLOCK)
                        goto repeat;
-               tind = i+(unsigned long *) bh->b_data;
-               if (!*tind)
-                       continue;
-               result |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
+               tind = i+(unsigned long *) tind_bh->b_data;
+               retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
+               tind_bh->b_dirt = 1;
        }
-       tind = (unsigned long *) bh->b_data;
+       tind = (unsigned long *) tind_bh->b_data;
        for (i = 0; i < 256; i++)
                if (*(tind++))
                        break;
-       brelse(bh);
-       if (i >= 256) {
-               result = 1;
-               if (ext_free_block(inode->i_dev,inode->i_data[11]))
-                       inode->i_data[11] = 0;
-       }
-       return result;
+       if (i >= 256)
+               if (tind_bh->b_count != 1)
+                       retry = 1;
+               else {
+                       tmp = *p;
+                       *p = 0;
+                       inode->i_dirt = 1;
+                       ext_free_block(inode->i_dev,tmp);
+               }
+       brelse(tind_bh);
+       return retry;
 }
-               
+
 void ext_truncate(struct inode * inode)
 {
-       int flag;
+       int retry;
 
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
             S_ISLNK(inode->i_mode)))
                return;
        while (1) {
-               flag = trunc_direct(inode);
-               flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
-               flag |= trunc_dindirect(inode,9+256,(unsigned long *)&inode->i_data[10]);
-               flag |= trunc_tindirect(inode);
-               if (!flag)
+               retry = trunc_direct(inode);
+               retry |= trunc_indirect(inode,9,inode->u.ext_i.i_data+9);
+               retry |= trunc_dindirect(inode,9+256,inode->u.ext_i.i_data+10);
+               retry |= trunc_tindirect(inode);
+               if (!retry)
                        break;
                current->counter = 0;
                schedule();
index 84da040a6efee1d809c53d7584d2fbe0540abbd0..319e39b31fee8c2faf5e32d0fba3052c4cf03c87 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -84,16 +84,16 @@ static int fifo_open(struct inode * inode,struct file * filp)
                wake_up(&PIPE_READ_WAIT(*inode));
        if (PIPE_READERS(*inode))
                wake_up(&PIPE_WRITE_WAIT(*inode));
-       if (retval || inode->i_size)
+       if (retval || PIPE_BASE(*inode))
                return retval;
        page = get_free_page(GFP_KERNEL);
-       if (inode->i_size) {
+       if (PIPE_BASE(*inode)) {
                free_page(page);
                return 0;
        }
        if (!page)
                return -ENOMEM;
-       inode->i_size = page;
+       PIPE_BASE(*inode) = (char *) page;
        return 0;
 }
 
index eaf3093289f4c53d084341dc93bad4ec6d3a8b03..074f70a4581b93d09dcb10f8e4be97a7827f0156 100644 (file)
@@ -117,8 +117,8 @@ void iput(struct inode * inode)
                return;
        }
        if (inode->i_pipe) {
-               wake_up(&inode->i_wait);
-               wake_up(&inode->i_wait2);
+               wake_up(&PIPE_READ_WAIT(*inode));
+               wake_up(&PIPE_WRITE_WAIT(*inode));
        }
 repeat:
        if (inode->i_count>1) {
@@ -126,8 +126,9 @@ repeat:
                return;
        }
        if (inode->i_pipe) {
-               free_page(inode->i_size);
-               inode->i_size = 0;
+               unsigned long page = (unsigned long) PIPE_BASE(*inode);
+               PIPE_BASE(*inode) = NULL;
+               free_page(page);
        }
        if (!inode->i_dev) {
                inode->i_count--;
@@ -188,7 +189,7 @@ struct inode * get_pipe_inode(void)
 
        if (!(inode = get_empty_inode()))
                return NULL;
-       if (!(inode->i_size = get_free_page(GFP_USER))) {
+       if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
                inode->i_count = 0;
                return NULL;
        }
index 69337d4e497cafd481cef2f6b56741686bb7937a..980125db7afd097d69e47044e6e4dbc5a584c433 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/stat.h>
+#include <linux/termios.h>
 
 static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
 {
@@ -17,17 +18,27 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
 
        switch (cmd) {
                case FIBMAP:
-                       if (filp->f_inode->i_op == NULL) return -EBADF;
-                       if (filp->f_inode->i_op->bmap == NULL) return -EINVAL;
+                       if (filp->f_inode->i_op == NULL)
+                               return -EBADF;
+                       if (filp->f_inode->i_op->bmap == NULL)
+                               return -EINVAL;
+                       verify_area((void *) arg,4);
                        block = get_fs_long((long *) arg);
                        block = filp->f_inode->i_op->bmap(filp->f_inode,block);
                        put_fs_long(block,(long *) arg);
                        return 0;
                case FIGETBSZ:
-                       if (filp->f_inode->i_sb == NULL) return -EBADF;
+                       if (filp->f_inode->i_sb == NULL)
+                               return -EBADF;
+                       verify_area((void *) arg,4);
                        put_fs_long(filp->f_inode->i_sb->s_blocksize,
                            (long *) arg);
                        return 0;
+               case FIONREAD:
+                       verify_area((void *) arg,4);
+                       put_fs_long(filp->f_inode->i_size - filp->f_pos,
+                           (long *) arg);
+                       return 0;
                default:
                        return -EINVAL;
        }
index 87bab09011fa5335b0fc3bcd0db498a8a6a61159..ca9808b1aec13e4f492fe2e7611255939a943a3a 100644 (file)
@@ -138,7 +138,7 @@ void minix_statfs (struct super_block *sb, struct statfs *buf)
        /* Don't know what value to put in buf->f_fsid */
 }
 
-#define inode_bmap(inode,nr) ((inode)->i_data[(nr)])
+#define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
 
 static int block_bmap(struct buffer_head * bh, int nr)
 {
@@ -185,13 +185,15 @@ int minix_bmap(struct inode * inode,int block)
 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
 {
        int tmp;
+       unsigned short *p;
        struct buffer_head * result;
 
+       p = inode->u.minix_i.i_data + nr;
 repeat:
-       tmp = inode->i_data[nr];
+       tmp = *p;
        if (tmp) {
                result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
-               if (tmp == inode->i_data[nr])
+               if (tmp == *p)
                        return result;
                brelse(result);
                goto repeat;
@@ -202,12 +204,12 @@ repeat:
        if (!tmp)
                return NULL;
        result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
-       if (inode->i_data[nr]) {
+       if (*p) {
                minix_free_block(inode->i_dev,tmp);
                brelse(result);
                goto repeat;
        }
-       inode->i_data[nr] = tmp;
+       *p = tmp;
        inode->i_ctime = CURRENT_TIME;
        inode->i_dirt = 1;
        return result;
@@ -324,7 +326,7 @@ void minix_read_inode(struct inode * inode)
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                inode->i_rdev = raw_inode->i_zone[0];
        else for (block = 0; block < 9; block++)
-               inode->i_data[block] = raw_inode->i_zone[block];
+               inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
        brelse(bh);
        inode->i_op = NULL;
        if (S_ISREG(inode->i_mode))
@@ -339,8 +341,8 @@ void minix_read_inode(struct inode * inode)
                inode->i_op = &minix_blkdev_inode_operations;
        else if (S_ISFIFO(inode->i_mode)) {
                inode->i_op = &minix_fifo_inode_operations;
-               inode->i_size = 0;
                inode->i_pipe = 1;
+               PIPE_BASE(*inode) = NULL;
                PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
                PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
        }
@@ -367,7 +369,7 @@ void minix_write_inode(struct inode * inode)
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_zone[0] = inode->i_rdev;
        else for (block = 0; block < 9; block++)
-               raw_inode->i_zone[block] = inode->i_data[block];
+               raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
        bh->b_dirt=1;
        inode->i_dirt=0;
        brelse(bh);
index 9b8ff5324dd1f66cdca53adbdf15fed8da99d961..10d8874ec82530aa09382a5b143122748dc80963 100644 (file)
@@ -14,8 +14,6 @@
 
 #include <asm/segment.h>
 
-#include <const.h>
-
 /*
  * comment out this line if you want names > MINIX_NAME_LEN chars to be
  * truncated. Else they will be disallowed.
@@ -260,8 +258,8 @@ int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rd
                inode->i_op = &minix_blkdev_inode_operations;
        else if (S_ISFIFO(inode->i_mode)) {
                inode->i_op = &minix_fifo_inode_operations;
-               inode->i_size = 0;
                inode->i_pipe = 1;
+               PIPE_BASE(*inode) = NULL;
                PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
                PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
        }
@@ -322,7 +320,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
        inode->i_nlink = 2;
        dir_block->b_dirt = 1;
        brelse(dir_block);
-       inode->i_mode = I_DIRECTORY | (mode & 0777 & ~current->umask);
+       inode->i_mode = S_IFDIR | (mode & 0777 & ~current->umask);
        inode->i_dirt = 1;
        bh = minix_add_entry(dir,name,len,&de);
        if (!bh) {
index 34c20a6e4a48960219e3b77196b7fd9cc53de637..507257fce42bab4057c23e2fdc86e38b0a05e791 100644 (file)
@@ -26,6 +26,7 @@
 
 static int trunc_direct(struct inode * inode)
 {
+       unsigned short * p;
        struct buffer_head * bh;
        int i, tmp;
        int retry = 0;
@@ -33,20 +34,20 @@ static int trunc_direct(struct inode * inode)
 
 repeat:
        for (i = DIRECT_BLOCK ; i < 7 ; i++) {
-               tmp = inode->i_data[i];
-               if (!tmp)
+               p = i + inode->u.minix_i.i_data;
+               if (!(tmp = *p))
                        continue;
                bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
                if (i < DIRECT_BLOCK) {
                        brelse(bh);
                        goto repeat;
                }
-               if ((bh && bh->b_count != 1) || tmp != inode->i_data[i]) {
+               if ((bh && bh->b_count != 1) || tmp != *p) {
                        retry = 1;
                        brelse(bh);
                        continue;
                }
-               inode->i_data[i] = 0;
+               *p = 0;
                inode->i_dirt = 1;
                brelse(bh);
                minix_free_block(inode->i_dev,tmp);
@@ -120,20 +121,20 @@ static int trunc_dindirect(struct inode * inode)
 {
        int i, tmp;
        struct buffer_head * dind_bh;
-       unsigned short * dind;
+       unsigned short * dind, * p;
        int retry = 0;
 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
 
-       tmp = inode->i_data[8];
-       if (!tmp)
+       p = 8 + inode->u.minix_i.i_data;
+       if (!(tmp = *p))
                return 0;
        dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
-       if (tmp != inode->i_data[8]) {
+       if (tmp != *p) {
                brelse(dind_bh);
                return 1;
        }
        if (!dind_bh) {
-               inode->i_data[8] = 0;
+               *p = 0;
                return 0;
        }
 repeat:
@@ -154,8 +155,8 @@ repeat:
                if (dind_bh->b_count != 1)
                        retry = 1;
                else {
-                       tmp = inode->i_data[8];
-                       inode->i_data[8] = 0;
+                       tmp = *p;
+                       *p = 0;
                        inode->i_dirt = 1;
                        minix_free_block(inode->i_dev,tmp);
                }
@@ -170,13 +171,9 @@ void minix_truncate(struct inode * inode)
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
             S_ISLNK(inode->i_mode)))
                return;
-       if (inode->i_data[7] & 0xffff0000) {
-               printk("BAD! minix inode has 16 high bits set\n");
-               inode->i_data[7] = 0;
-       }
        while (1) {
                retry = trunc_direct(inode);
-               retry |= trunc_indirect(inode,7,(unsigned short *)&inode->i_data[7]);
+               retry |= trunc_indirect(inode,7,inode->u.minix_i.i_data+7);
                retry |= trunc_dindirect(inode);
                if (!retry)
                        break;
index 1057207c5c321c5fbf5854aa9412a3882421a3fe..26d383251a9b74c16037de26a4d169b59b4fe291 100644 (file)
@@ -226,7 +226,7 @@ int get_cluster(struct inode *inode,int cluster)
                if ((this = fat_access(inode->i_sb,this,-1)) == -1) return 0;
                if (!this) return 0;
        }
-       if (!(MSDOS_I(inode)->i_busy || inode->i_nlink))
+       if (!(MSDOS_I(inode)->i_busy && inode->i_nlink))
                cache_add(inode,cluster,this);
        /* don't add clusters of moved files, because we can't invalidate them
           when this inode is returned. */
index 165096bf84d1453e5bc8828c88181f9356eb2081..648c3f25ee124a6c4c29c98c183e9d1a26c3acaa 100644 (file)
@@ -8,8 +8,6 @@
  * Some corrections by tytso.
  */
 
-#include <const.h>
-
 #include <asm/segment.h>
 
 #include <linux/errno.h>
@@ -218,7 +216,7 @@ int open_namei(const char * pathname, int flag, int mode,
        struct task_struct ** p;
 
        mode &= 07777 & ~current->umask;
-       mode |= I_REGULAR;
+       mode |= S_IFREG;
        error = dir_namei(pathname,&namelen,&basename,base,&dir);
        if (error)
                return error;
index 014f6905408086fc9615bae6161b5d3866696d27..90028775244f91405569ee98451ab61a6cc5a49a 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -32,7 +32,7 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c
                        chars = count;
                if (chars > size)
                        chars = size;
-               memcpy_tofs(buf, (char *)inode->i_size+PIPE_TAIL(*inode), chars );
+               memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars );
                read += chars;
                PIPE_TAIL(*inode) += chars;
                PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
@@ -75,7 +75,7 @@ static int pipe_write(struct inode * inode, struct file * filp, char * buf, int
                                chars = count;
                        if (chars > size)
                                chars = size;
-                       memcpy_fromfs((char *)inode->i_size+PIPE_HEAD(*inode), buf, chars );
+                       memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars );
                        written += chars;
                        PIPE_HEAD(*inode) += chars;
                        PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
index 4dc1682b50eb43861a6714b4c0021a930b846e3f..caac6990330d8424f07f4c094afb5e522ac1a22b 100644 (file)
@@ -18,8 +18,6 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 
-#include <const.h>
-
 /*
  * Ok, Peter made a complicated, but straightforward multiple_wait() function.
  * I have rewritten this, taking some shortcuts: This code may not be easy to
index 459f418a6e1bd76db0c1f677a66e036843f67719..1a5b92cc211522f60a59db86d108c736e25965eb 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -25,10 +25,7 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
        tmp.st_uid = inode->i_uid;
        tmp.st_gid = inode->i_gid;
        tmp.st_rdev = inode->i_rdev;
-       if( S_ISFIFO(inode->i_mode) )
-               tmp.st_size = 0;
-       else
-               tmp.st_size = inode->i_size;
+       tmp.st_size = inode->i_size;
        tmp.st_atime = inode->i_atime;
        tmp.st_mtime = inode->i_mtime;
        tmp.st_ctime = inode->i_ctime;
@@ -48,10 +45,7 @@ static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
        tmp.st_uid = inode->i_uid;
        tmp.st_gid = inode->i_gid;
        tmp.st_rdev = inode->i_rdev;
-       if( S_ISFIFO(inode->i_mode) )
-               tmp.st_size = 0;
-       else
-               tmp.st_size = inode->i_size;
+       tmp.st_size = inode->i_size;
        tmp.st_atime = inode->i_atime;
        tmp.st_mtime = inode->i_mtime;
        tmp.st_ctime = inode->i_ctime;
@@ -74,12 +68,10 @@ static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
                        }
                        blocks += indirect;
                }
-               tmp.st_blksize = 512;
                tmp.st_blocks = blocks;
-       } else {
-               tmp.st_blksize = inode->i_blksize;
-               tmp.st_blocks = inode->i_blocks;
-       }
+       } else
+               tmp.st_blocks = (inode->i_blocks * inode->i_blksize) / 512;
+       tmp.st_blksize = 512;
        memcpy_tofs(statbuf,&tmp,sizeof(tmp));
 }
 
index 7c54b0f5d4dab58de9cdf9af37938e91fe28e614..15cec3130654bc94fd232405ca00168a3fd2b0e2 100644 (file)
@@ -6,46 +6,51 @@
  * the two short jumps: using outb's to a nonexistent port seems
  * to guarantee better timings even on fast machines.
  *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe abou using 0x80.
+ *
  *             Linus
  */
 
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("inb $0x80,%%al":::"ax")
+#endif
+
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
 extern void inline outb(char value, unsigned short port)
 {
-__asm__ __volatile__ ("outb %0,%1"
+__asm__ __volatile__ ("outb %%al,%%dx"
                ::"a" ((char) value),"d" ((unsigned short) port));
 }
 
-extern void inline outb_p(char value, unsigned short port)
+extern unsigned int inline inb(unsigned short port)
 {
-__asm__ __volatile__ ("outb %0,%1\n\t"
-#ifdef REALLY_SLOW_IO
-                 "outb %0,$0x80\n\t"
-                 "outb %0,$0x80\n\t"
-                 "outb %0,$0x80\n\t"
-#endif
-                 "outb %0,$0x80"
-               ::"a" ((char) value),"d" ((unsigned short) port));
+       unsigned int _v;
+__asm__ __volatile__ ("inb %%dx,%%al"
+               :"=a" (_v):"d" ((unsigned short) port),"0" (0));
+       return _v;
 }
 
-extern unsigned char inline inb(unsigned short port)
+extern void inline outb_p(char value, unsigned short port)
 {
-       unsigned char _v;
-__asm__ __volatile__ ("inb %1,%0"
-               :"=a" (_v):"d" ((unsigned short) port));
-       return _v;
+__asm__ __volatile__ ("outb %%al,%%dx"
+               ::"a" ((char) value),"d" ((unsigned short) port));
+       SLOW_DOWN_IO;
 }
 
-extern unsigned char inline inb_p(unsigned short port)
+extern unsigned int inline inb_p(unsigned short port)
 {
-       unsigned char _v;
-__asm__ __volatile__ ("inb %1,%0\n\t"
-#ifdef REALLY_SLOW_IO
-                 "outb %0,$0x80\n\t"
-                 "outb %0,$0x80\n\t"
-                 "outb %0,$0x80\n\t"
-#endif
-                 "outb %0,$0x80"
-               :"=a" (_v):"d" ((unsigned short) port));
+       unsigned int _v;
+__asm__ __volatile__ ("inb %%dx,%%al"
+               :"=a" (_v):"d" ((unsigned short) port),"0" (0));
+       SLOW_DOWN_IO;
        return _v;
 }
 
index 42e5f666e443fa5963c613a5ef8980b6cdc89734..d83768eb3b4da89b295473050a10f13fc9acaf19 100644 (file)
  * Minor modifications for Linux 0.96c-pl1 by Nathan Laredo
  * gt7080a@prism.gatech.edu (13JUL92)
  *
+ * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+ *
+ * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+ *    8/28/92
+ *
+ * Microsoft Bus Mouse support folded into 0.97pl4 code
+ *    by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ * Changes:  Logitech and Microsoft support in the same kernel.
+ *           Defined new constants in busmouse.h for MS mice.
+ *           Added int mse_busmouse_type to distinguish busmouse types
+ *           Added a couple of new functions to handle differences in using
+ *             MS vs. Logitech (where the int variable wasn't appropriate).
+ *
  */
 
 #define MOUSE_IRQ              5
+#define LOGITECH_BUSMOUSE       0   /* Minor device # for Logitech  */
+#define MICROSOFT_BUSMOUSE      2   /* Minor device # for Microsoft */
+
+/*--------- LOGITECH BUSMOUSE ITEMS -------------*/
 
 #define        MSE_DATA_PORT           0x23c
 #define        MSE_SIGNATURE_PORT      0x23d
 #define MSE_DEFAULT_MODE       0x90
 #define MSE_SIGNATURE_BYTE     0xa5
 
-/* useful macros */
+/* useful Logitech Mouse macros */
 
 #define MSE_INT_OFF()  outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT)
 #define MSE_INT_ON()   outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT)
+
+/*--------- MICROSOFT BUSMOUSE ITEMS -------------*/
+
+#define        MS_MSE_DATA_PORT                0x23d
+#define        MS_MSE_SIGNATURE_PORT           0x23d
+#define        MS_MSE_CONTROL_PORT             0x23c
+#define        MS_MSE_CONFIG_PORT              0x23f
+
+#define        MS_MSE_ENABLE_INTERRUPTS        0x11
+#define        MS_MSE_DISABLE_INTERRUPTS       0x10
+
+#define        MS_MSE_READ_BUTTONS             0x00
+#define        MS_MSE_READ_X                   0x01
+#define        MS_MSE_READ_Y                   0x02
+
+#define MS_MSE_START                    0x80
+#define MS_MSE_COMMAND_MODE             0x07
+
+/* useful microsoft busmouse macros */
+
+#define MS_MSE_INT_OFF() {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); \
+                           outb(MS_MSE_DISABLE_INTERRUPTS, MS_MSE_DATA_PORT);}
+#define MS_MSE_INT_ON()  {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT); \
+                           outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT);}
+
  
 struct mouse_status
        {
@@ -54,8 +96,13 @@ struct mouse_status
        struct inode    *inode;
        };
 
+/* Variable Definitions */
+extern int mse_busmouse_type;   /* to distinguish what type mouse we're working with */
+
+
 /* Function Prototypes */
 extern long mouse_init(long);
 
+
 #endif
 
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
new file mode 100644 (file)
index 0000000..a16d547
--- /dev/null
@@ -0,0 +1,355 @@
+/****************************************************************************************
+ *                                                                                     *
+ * SCSI header library for linux                                                       *
+ * (C) 1992 David Giller rafetmad@oxy.edu                                              *
+ *                                                                                     *
+ * <linux/cdrom.h> -- CD-ROM IOCTLs and structs                                                *
+ *                                                                                     *
+ ****************************************************************************************/
+
+#ifndef        _LINUX_CDROM_H
+#define        _LINUX_CDROM_H
+
+/*
+ *
+ * For IOCTL calls, we will commandeer byte 0x53, or 'S'.
+ *
+ */
+
+/*
+ * These are flags for the SCMD_DOORLOCK command.  They really should be defined
+ * somewhere more standard.
+ */
+
+#define        SR_REMOVAL_PREVENT      1
+#define        SR_REMOVAL_ALLOW        0
+
+/*
+ * CD-ROM-specific SCSI command opcodes
+ */
+
+/*
+ * Group 2 (10-byte).  All of these are called 'optional' by SCSI-II.
+ */
+
+#define        SCMD_READ_TOC           0x43            /* read table of contents       */
+#define        SCMD_PLAYAUDIO_MSF      0x47            /* play data at time offset     */
+#define        SCMD_PLAYAUDIO_TI       0x48            /* play data at track/index     */
+#define        SCMD_PAUSE_RESUME       0x4B            /* pause/resume audio           */
+#define        SCMD_READ_SUBCHANNEL    0x42            /* read SC info on playing disc */
+#define        SCMD_PLAYAUDIO10        0x45            /* play data at logical block   */
+#define        SCMD_READ_HEADER        0x44            /* read TOC header              */
+
+/*
+ * Group 5
+ */
+
+#define        SCMD_PLAYAUDIO12        0xA5            /* play data at logical block   */
+#define        SCMD_PLAYTRACK_REL12    0xA9            /* play track at relative offset*/
+
+/*
+ * Group 6 Commands
+ */
+
+#define        SCMD_CD_PLAYBACK_CONTROL 0xC9           /* Sony vendor-specific audio   */
+#define        SCMD_CD_PLAYBACK_STATUS 0xC4            /* control opcodes. info please!*/
+
+/*
+ * CD-ROM capacity structure.
+ */
+
+struct scsi_capacity 
+       {
+       u_long  capacity;
+       u_long  lbasize;
+       };
+
+/*
+ * CD-ROM MODE_SENSE/MODE_SELECT parameters
+ */
+
+#define        ERR_RECOVERY_PARMS      0x01
+#define        DISCO_RECO_PARMS        0x02
+#define        FORMAT_PARMS            0x03
+#define        GEOMETRY_PARMS          0x04
+#define        CERTIFICATION_PARMS     0x06
+#define        CACHE_PARMS             0x38
+
+/*
+ * standard mode-select header prepended to all mode-select commands
+ */
+
+struct ccs_modesel_head 
+       {
+       u_char  _r1;                    /* reserved                             */
+       u_char  medium;                 /* device-specific medium type          */
+       u_char  _r2;                    /* reserved                             */
+       u_char  block_desc_length;      /* block descriptor length              */
+       u_char  density;                /* device-specific density code         */
+       u_char  number_blocks_hi;       /* number of blocks in this block desc  */
+       u_char  number_blocks_med;
+       u_char  number_blocks_lo;
+       u_char  _r3;
+       u_char  block_length_hi;        /* block length for blocks in this desc */
+       u_short block_length;
+       };
+
+/*
+ * error recovery parameters
+ */
+
+struct ccs_err_recovery 
+       {
+       u_char  _r1             : 2;    /* reserved                             */
+       u_char  page_code       : 6;    /* page code                            */
+       u_char  page_length;            /* page length                          */
+       u_char  awre            : 1;    /* auto write realloc enabled           */
+       u_char  arre            : 1;    /* auto read realloc enabled            */
+       u_char  tb              : 1;    /* transfer block                       */
+       u_char  rc              : 1;    /* read continuous                      */
+       u_char  eec             : 1;    /* enable early correction              */
+       u_char  per             : 1;    /* post error                           */
+       u_char  dte             : 1;    /* disable transfer on error            */
+       u_char  dcr             : 1;    /* disable correction                   */
+       u_char  retry_count;            /* error retry count                    */
+       u_char  correction_span;        /* largest recov. to be attempted, bits */
+       u_char  head_offset_count;      /* head offset (2's C) for each retry   */
+       u_char  strobe_offset_count;    /* data strobe "                        */
+       u_char  recovery_time_limit;    /* time limit on recovery attempts      */
+};
+
+/*
+ * disco/reco parameters
+ */
+
+struct ccs_disco_reco 
+       {
+       u_char  _r1             : 2;    /* reserved                             */
+       u_char  page_code       : 6;    /* page code                            */
+       u_char  page_length;            /* page length                          */
+       u_char  buffer_full_ratio;      /* write buffer reconnect threshold     */
+       u_char  buffer_empty_ratio;     /* read "                               */
+       u_short bus_inactivity_limit;   /* limit on bus inactivity time         */
+       u_short disconnect_time_limit;  /* minimum disconnect time              */
+       u_short connect_time_limit;     /* minimum connect time                 */
+       u_short _r2;                    /* reserved                             */
+};
+
+/*
+ * drive geometry parameters
+ */
+
+struct ccs_geometry 
+       {
+       u_char  _r1             : 2;    /* reserved                             */
+       u_char  page_code       : 6;    /* page code                            */
+       u_char  page_length;            /* page length                          */
+       u_char  cyl_ub;                 /* #cyls                                */
+       u_char  cyl_mb;
+       u_char  cyl_lb;
+       u_char  heads;                  /* #heads                               */
+       u_char  precomp_cyl_ub;         /* precomp start                        */
+       u_char  precomp_cyl_mb;
+       u_char  precomp_cyl_lb;
+       u_char  current_cyl_ub;         /* reduced current start                */
+       u_char  current_cyl_mb;
+       u_char  current_cyl_lb;
+       u_short step_rate;              /* stepping motor rate                  */
+       u_char  landing_cyl_ub;         /* landing zone                         */
+       u_char  landing_cyl_mb;
+       u_char  landing_cyl_lb;
+       u_char  _r2;
+       u_char  _r3;
+       u_char  _r4;
+       };
+
+/*
+ * cache parameters
+ */
+
+struct ccs_cache 
+       {
+       u_char  _r1             : 2;    /* reserved                             */
+       u_char  page_code       : 6;    /* page code                            */
+       u_char  page_length;            /* page length                          */
+       u_char  mode;                   /* cache control byte                   */
+       u_char  threshold;              /* prefetch threshold                   */
+       u_char  max_prefetch;           /* maximum prefetch size                */
+       u_char  max_multiplier;         /* maximum prefetch multiplier          */
+       u_char  min_prefetch;           /* minimum prefetch size                */
+       u_char  min_multiplier;         /* minimum prefetch multiplier          */
+       u_char  _r2[8];
+       };
+
+/*
+ * CDROM IOCTL structures
+ */
+
+struct cdrom_msf 
+       {
+       u_char  cdmsf_min0;             /* start minute                         */
+       u_char  cdmsf_sec0;             /* start second                         */
+       u_char  cdmsf_frame0;           /* start frame                          */
+       u_char  cdmsf_min1;             /* end minute                           */
+       u_char  cdmsf_sec1;             /* end second                           */
+       u_char  cdmsf_frame1;           /* end frame                            */
+       };
+
+struct cdrom_ti 
+       {
+       u_char  cdti_trk0;              /* start track                          */
+       u_char  cdti_ind0;              /* start index                          */
+       u_char  cdti_trk1;              /* end track                            */
+       u_char  cdti_ind1;              /* end index                            */
+       };
+
+struct cdrom_tochdr    
+       {
+       u_char  cdth_trk0;              /* start track                          */
+       u_char  cdth_trk1;              /* end track                            */
+       };
+
+struct cdrom_tocentry 
+       {
+       u_char  cdte_track;
+       u_char  cdte_adr        :4;
+       u_char  cdte_ctrl       :4;
+       u_char  cdte_format;
+       union
+               {
+               struct
+                       {
+                       u_char  minute;
+                       u_char  second;
+                       u_char  frame;
+                       } msf;
+               int     lba;
+               } cdte_addr;
+       u_char  cdte_datamode;
+       };
+
+/*
+ * CD-ROM address types (cdrom_tocentry.cdte_format)
+ */
+
+#define        CDROM_LBA       0x01
+#define        CDROM_MSF       0x02
+
+/*
+ * bit to tell whether track is data or audio
+ */
+
+#define        CDROM_DATA_TRACK        0x04
+
+/*
+ * The leadout track is always 0xAA, regardless of # of tracks on disc
+ */
+
+#define        CDROM_LEADOUT   0xAA
+
+struct cdrom_subchnl 
+       {
+       u_char  cdsc_format;
+       u_char  cdsc_audiostatus;
+       u_char  cdsc_adr:       4;
+       u_char  cdsc_ctrl:      4;
+       u_char  cdsc_trk;
+       u_char  cdsc_ind;
+       union
+               {
+               struct                  
+                       {
+                       u_char  minute;
+                       u_char  second;
+                       u_char  frame;
+                       } msf;
+               int     lba;
+               } cdsc_absaddr;
+       union 
+               {
+               struct 
+                       {
+                       u_char  minute;
+                       u_char  second;
+                       u_char  frame;
+                       } msf;
+               int     lba;
+               } cdsc_reladdr;
+       };
+
+/*
+ * return value from READ SUBCHANNEL DATA
+ */
+
+#define        CDROM_AUDIO_INVALID     0x00    /* audio status not supported           */
+#define        CDROM_AUDIO_PLAY        0x11    /* audio play operation in progress     */
+#define        CDROM_AUDIO_PAUSED      0x12    /* audio play operation paused          */
+#define        CDROM_AUDIO_COMPLETED   0x13    /* audio play successfully completed    */
+#define        CDROM_AUDIO_ERROR       0x14    /* audio play stopped due to error      */
+#define        CDROM_AUDIO_NO_STATUS   0x15    /* no current audio status to return    */
+
+struct cdrom_volctrl
+       {
+       u_char  channel0;
+       u_char  channel1;
+       u_char  channel2;
+       u_char  channel3;
+       };
+
+struct cdrom_read      
+       {
+       int     cdread_lba;
+       caddr_t cdread_bufaddr;
+       int     cdread_buflen;
+       };
+
+#ifdef FIVETWELVE
+#define        CDROM_MODE1_SIZE        512
+#else
+#define        CDROM_MODE1_SIZE        2048
+#endif FIVETWELVE
+#define        CDROM_MODE2_SIZE        2336
+
+/*
+ * CD-ROM IOCTL commands
+ */
+
+#define        CDROMPAUSE              0x5301          /* pause                        */
+#define        CDROMRESUME             0x5302          /* resume                       */
+
+#define        CDROMPLAYMSF            0x5303          /* (stuct cdrom_msf)            */
+                                                /* SCMD_PLAY_AUDIO_MSF         */
+
+#define        CDROMPLAYTRKIND         0x5304          /* (struct cdrom_ti)            */
+                                                /* SCMD_PLAY_AUDIO_TI          */
+
+#define        CDROMREADTOCHDR         0x5305          /* (struct cdrom_tochdr)        */
+                                                /* read the TOC header         */
+#define        CDROMREADTOCENTRY       0x5306          /* (struct cdrom_tocentry)      */
+                                                /* read a TOC entry            */
+
+#define        CDROMSTOP               0x5307          /* stop the drive motor         */
+#define        CDROMSTART              0x5308          /* turn the motor on            */
+
+#define        CDROMEJECT              0x5309          /* eject CD-ROM media           */
+
+#define        CDROMVOLCTRL            0x530a          /* (struct cdrom_volctrl)       */
+                                                /* vlume control               */
+
+#define        CDROMSUBCHNL            0x530b          /* (struct cdrom_subchnl)       */
+                                                /* read sub-channel data       */
+
+#define        CDROMREADMODE2          0x530c          /* (struct cdrom_read)          */
+                                                /* read type-2 data (not suppt)        */
+
+#define        CDROMREADMODE1          0x530d          /* (struct cdrom_read)          */
+                                                /* read type-1 data            */
+
+/*
+ * Linux-specific CD-ROM ioctls for convenience and ISO-9660 support
+ */
+
+#define CDROMDOORLOCK          0x5380          /* lock the eject mechanism     */
+#define CDROMDOORUNLOCK                0x5381          /* unlock the mechanism         */
+
+#endif  _LINUX_CDROM_H
index 816c8fc28648908af709145d8a22eac24672bd18..9595cb5a472875e0fe638b739b961d4649f7ad51 100644 (file)
@@ -24,6 +24,8 @@
 #define CONFIG_BLK_DEV_HD
 #undef CONFIG_BLK_DEV_SD
 #define CONFIG_BLK_DEV_SD
+#undef CONFIG_BLK_DEV_SR
+#define CONFIG_BLK_DEV_SR
 #undef CONFIG_BLK_DEV_ST
 #define CONFIG_BLK_DEV_ST
 
index e8ccd57bd626ae850ef33afaf66c6b0644c81661..6f79980a8afadd228a7fb4751d003f5b193f7c5d 100644 (file)
@@ -65,6 +65,7 @@
 #define CONFIG_BLK_DEV_HD
 #undef CONFIG_BLK_DEV_SD
 #undef CONFIG_BLK_DEV_ST
+#undef CONFIG_BLK_DEV_SR
 
 
 /*
@@ -80,7 +81,7 @@
 #undef CONFIG_SCSI_ULTRASTOR
 #undef CONFIG_SCSI_7000FASST
 
-#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_CD) || \
+#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_SR) || \
 defined(CONFIG_CHR_DEV_ST)
 #ifndef CONFIG_SCSI
        #define CONFIG_SCSI
index cfb3d1077c4e0992dedb798d7f46c80d1d05e49f..7e6e3aa3a8d520bc2f53910f13015babfd6f7369 100644 (file)
@@ -78,12 +78,14 @@ extern struct inode * ext_new_inode(int dev);
 extern void ext_free_inode(struct inode * inode);
 extern unsigned long ext_count_free_inodes(struct super_block *sb);
 extern int ext_new_block(int dev);
-extern int ext_free_block(int dev, int block);
+extern void ext_free_block(int dev, int block);
 extern unsigned long ext_count_free_blocks(struct super_block *sb);
 
-extern int ext_create_block(struct inode *, int);
 extern int ext_bmap(struct inode *,int);
 
+extern struct buffer_head * ext_getblk(struct inode *, int, int);
+extern struct buffer_head * ext_bread(struct inode *, int, int);
+
 extern void ext_truncate(struct inode *);
 extern void ext_put_super(struct super_block *);
 extern void ext_write_super(struct super_block *);
index c64bc62b628c42e1df8d9e6b982e31c58f173f27..32734f95f40cf2260a42dca133c2449131542bef 100644 (file)
@@ -5,6 +5,7 @@
  * extended file system inode data in memory
  */
 struct ext_inode_info {
+       unsigned long i_data[16];
 };
 
 #endif
index 4aa3dcde80bd4e125bd4bf916601ebd511d470ce..105a115a72c558cf61f4a3eef0be5621918d5bc2 100644 (file)
 /* devices are as follows: (same as minix, so we can use the minix
  * file system. These are major numbers.)
  *
- * 0 - unused (nodev)
- * 1 - /dev/mem
- * 2 - /dev/fd
- * 3 - /dev/hd
- * 4 - /dev/ttyx
- * 5 - /dev/tty
- * 6 - /dev/lp
- * 7 - unnamed pipes
- * 8 - /dev/sd
- * 9 - /dev/st
+ *  0 - unused (nodev)
+ *  1 - /dev/mem
+ *  2 - /dev/fd
+ *  3 - /dev/hd
+ *  4 - /dev/ttyx
+ *  5 - /dev/tty
+ *  6 - /dev/lp
+ *  7 -
+ *  8 - /dev/sd
+ *  9 - /dev/st
+ * 10 - mice
+ * 11 - scsi cdrom
  */
 
-#define IS_SEEKABLE(x) ((x)>=1 && (x)<=3 || (x)==8)
-
 #define MAY_EXEC 1
 #define MAY_WRITE 2
 #define MAY_READ 4
@@ -47,16 +47,6 @@ extern void buffer_init(void);
 #define NULL ((void *) 0)
 #endif
 
-#define PIPE_READ_WAIT(inode) ((inode).i_wait)
-#define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)
-#define PIPE_HEAD(inode) ((inode).i_data[0])
-#define PIPE_TAIL(inode) ((inode).i_data[1])
-#define PIPE_READERS(inode) ((inode).i_data[2])
-#define PIPE_WRITERS(inode) ((inode).i_data[3])
-#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
-#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))
-#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))
-
 #define NIL_FILP       ((struct file *)0)
 #define SEL_IN         1
 #define SEL_OUT                2
@@ -113,6 +103,7 @@ struct buffer_head {
        struct buffer_head * b_reqnext;         /* request queue */
 };
 
+#include <linux/pipe_fs_i.h>
 #include <linux/minix_fs_i.h>
 #include <linux/ext_fs_i.h>
 #include <linux/msdos_fs_i.h>
@@ -131,11 +122,9 @@ struct inode {
        time_t          i_ctime;
        unsigned long   i_blksize;
        unsigned long   i_blocks;
-       unsigned long i_data[16];
        struct inode_operations * i_op;
        struct super_block * i_sb;
        struct wait_queue * i_wait;
-       struct wait_queue * i_wait2;    /* for pipes */
        struct file_lock *i_flock;
        unsigned short i_count;
        unsigned short i_flags;
@@ -146,6 +135,7 @@ struct inode {
        unsigned char i_seek;
        unsigned char i_update;
        union {
+               struct pipe_inode_info pipe_i;
                struct minix_inode_info minix_i;
                struct ext_inode_info ext_i;
                struct msdos_inode_info msdos_i;
diff --git a/include/linux/kd.h b/include/linux/kd.h
new file mode 100644 (file)
index 0000000..c114f77
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef _LINUX_KD_H
+#define _LINUX_KD_H
+
+/* 0x4B is 'K', to avoid collision with termios and vt */
+
+#define SWAPMONO       0x4B00  /* use mca as output device */
+#define SWAPCGA                0x4B01  /* use cga as output device */
+#define SWAPEGA                0x4B02  /* use ega as output device */
+#define SWAPVGA                0x4B03  /* use vga as output device */
+#define CONS_CURRENT   0x4B04  /* return current output device */
+#define                MONO            0x01
+#define                CGA             0x02
+#define                EGA             0x03
+
+#define SW_B40x25      0x4B05  /* 40x25 mono text (cga/ega) */
+#define SW_C40x25      0x4B06  /* 40x24 color text (cga/ega) */
+#define SW_B80x25      0x4B07  /* 80x25 mono text (cga/ega) */
+#define SW_C80x25      0x4B08  /* 80x25 color text (cga/ega) */
+#define SW_BG320       0x4B09  /* 320x200 mono graphics (cga/ega) */
+#define SW_CG320       0x4B0A  /* 320x200 color graphics (cga/ega) */
+#define SW_BG640       0x4B0B  /* 640x200 mono graphics (cga/ega) */
+#define SW_CG320_D     0x4B0C  /* 320x200 graphics (ega mode d) */
+#define SW_CG640_E     0x4B0D  /* 640x200 graphics (ega mode e) */
+#define SW_EGAMONOAPA  0x4B0E  /* 640x350 graphics (ega mode f) */
+#define SW_ENH_MONOAPA2        0x4B0F  /* 640x350 graphics extd mem (ega mode f*) */
+#define SW_CG640x350   0x4B10  /* 640x350 graphics (ega mode 10) */
+#define SW_ENH_CG640   0x4B11  /* 640x350 graphics extd mem (ega mode 10*) */
+#define SW_EGAMONO80x25        0x4B12  /* 80x25 mono text (ega mode 7) */
+#define SW_ENHB40x25   0x4B13  /* enhanced 40x25 mono text (ega) */
+#define SW_ENHC40x25   0x4B14  /* enhanced 40x25 color text (ega) */
+#define SW_ENHB80x25   0x4B15  /* enhanced 80x25 mono text (ega) */
+#define SW_ENHC80x25   0x4B16  /* enhanced 80x25 color text (ega) */
+#define SW_ENHB80x43   0x4B17  /* enhanced 80x43 mono text (ega) */
+#define SW_ENHC80x43   0x4B18  /* enhanced 80x43 color text (ega) */
+#define SW_MCAMODE     0x4B19  /* reinit mca */
+#define SW_ATT640      0x4B1A  /* 640x400 16color */
+/* should add more vga modes, etc */
+
+#define CONS_GET       0x4B1B  /* get current display mode */
+#define                M_B40x25        0       /* 40x25 mono (cga/ega) */
+#define                M_C40x25        1       /* 40x25 color (cga/ega) */
+#define                M_B80x25        2       /* 80x25 mono (cga/ega) */
+#define                M_C80x25        3       /* 80x25 color (cga/ega) */
+#define                M_BG320         4       /* 320x200 mono (cga/ega) */
+#define                M_CG320         5       /* 320x200 color (cga/ega) */
+#define                M_BG640         6       /* 640x200 mono (cga/ega) */
+#define                M_EGAMONO80x25  7       /* 80x25 mono (ega) */
+#define                M_CG320_D       13      /* ega mode d */
+#define                M_CG640_E       14      /* ega mode e */
+#define                M_EFAMONOAPA    15      /* ega mode f */
+#define                M_CG640x350     16      /* ega mode 10 */
+#define                M_ENHMONOAPA2   17      /* ega mode f with ext mem */
+#define                M_ENH_CG640     18      /* ega mode 10* */
+#define                M_ENH_B40x25    19      /* ega enh 40x25 mono */
+#define                M_ENH_C40x25    20      /* ega enh 40x25 color */
+#define                M_ENH_B80x25    21      /* ega enh 80x25 mono */
+#define                M_ENH_C80x25    22      /* ega enh 80x25 color */
+#define                M_ENH_B80x43    0x70    /* ega enh 80x43 mono */
+#define                M_ENH_C80x43    0x71    /* ega enh 80x43 color */
+#define                M_MCA_MODE      0xff    /* monochrome adapter mode */
+#define MCA_GET                0x4B1C  /* get mca display mode */
+#define CGA_GET                0x4B1D  /* get cga display mode */
+#define EGA_GET                0x4B1E  /* get ega display mode */
+
+#define MAPCONS                0x4B1F  /* map current video mem into address space */
+#define MAPMONO                0x4B20  /* map mca video mem into address space */
+#define MAPCGA         0x4B21  /* map cga video mem into address space */
+#define MAPEGA         0x4B22  /* map ega video mem into address space */
+#define MAPVGA         0x4B23  /* map vga video mem into address space */
+
+struct port_io_struc {
+       char dir;                       /* direction in vs out */
+       unsigned short port;
+       char data;
+};
+#define                IN_ON_PORT      0x00
+#define                OUT_ON_PORT     0x01
+struct port_io_arg {
+       struct port_io_struc args[4];
+};
+#define MCAIO          0x4B24  /* i/o to mca video board */
+#define CGAIO          0x4B25  /* i/o to cga video board */
+#define EGAIO          0x4B26  /* i/o to ega video board */
+#define VGAIO          0x4B27  /* i/o to vga video board */
+
+#define GIO_FONT8x8    0x4B28  /* gets current 8x8 font used */
+#define PIO_FONT8x8    0x4B29  /* use supplied 8x8 font */
+#define GIO_FONT8x14   0x4B2A  /* gets current 8x14 font used */
+#define PIO_FONT8x14   0x4B2B  /* use supplied 8x14 font */
+#define GIO_FONT8x16   0x4B2C  /* gets current 8x16 font used */
+#define PIO_FONT8x16   0x4B2D  /* use supplied 8x16 font */
+
+#define MKDIOADDR      32      /* io bitmap size from <linux/sched.h> */
+struct kd_disparam {
+       long type;                      /* type of display */
+       char *addr;                     /* display mem address */
+       ushort ioaddr[MKDIOADDR];       /* valid i/o addresses */
+};
+#define KDDISPTYPE     0x4B2E  /* gets display info */
+#define                KD_MONO         0x01
+#define                KD_HERCULES     0x02
+#define                KD_CGA          0x03
+#define                KD_EGA          0x04
+
+#define KIOCSOUND      0x4B2F  /* start sound generation (0 for off) */
+#define KDMKTONE       0x4B30  /* generate tone */
+
+#define KDGETLED       0x4B31  /* return current led flags */
+#define KDSETLED       0x4B32  /* set current led flags */
+#define        LED_SCR         0x01    /* scroll lock */
+#define        LED_CAP         0x04    /* caps lock */
+#define        LED_NUM         0x02    /* num lock */
+
+#define KDGKBTYPE      0x4B33  /* get keyboard type */
+#define        KB_84           0x01
+#define        KB_101          0x02
+#define        KB_OTHER        0x03
+
+#define KDADDIO                0x4B34  /* add i/o port as valid */
+#define KDDELIO                0x4B35  /* del i/o port as valid */
+#define KDENABIO       0x4B36  /* enable i/o to video board */
+#define KDDISABIO      0x4B37  /* disable i/o to video board */
+
+struct kd_quemode {
+       int qsize;              /* desired # elem in queue */
+       int signo;              /* signal to send when queue not empty */
+       char *qaddr;            /* user virt addr of queue */
+};
+#define KDQUEMODE      0x4B38  /* enable/disable special queue mode */
+
+#define KDSBORDER      0x4B39  /* set screen boarder in ega text mode */
+
+#define KDSETMODE      0x4B3A  /* set text/grahics mode */
+#define                KD_TEXT         0x00
+#define                KD_GRAPHICS     0x01
+#define                KD_TEXT0        0x02    /* ? */
+#define                KD_TEXT1        0x03    /* ? */
+#define KDGETMODE      0x4B3B  /* get current mode */
+
+struct kd_memloc {
+       char *vaddr;            /* virt addr to map to */
+       char *physaddr;         /* phys addr to map from */
+       long length;            /* number of bytes */
+       long ioflg;             /* enable i/o if set */
+};
+#define KDMAPDISP      0x4B3C  /* map display into address space */
+#define KDUNMAPDISP    0x4B3D  /* unmap display from address space */
+
+#define KDVDCTYPE      0x4B3E  /* return vdc controller/display info */
+
+#define KIOCINFO       0x4B3F  /* tell what the device is */
+
+typedef char scrnmap_t;
+#define                E_TABSZ         256
+#define GIO_SCRNMAP    0x4B40  /* get screen mapping from kernel */
+#define PIO_SCRNMAP    0x4B41  /* put screen mapping table in kernel */
+
+#define GIO_ATTR       0x4B42  /* get screen attributes */
+#define GIO_COLOR      0x4B43  /* return nonzero if display is color */
+
+#define                K_RAW           0x00
+#define                K_XLATE         0x01
+#define KDGKBMODE      0x4B44  /* gets current keyboard mode */
+#define KDSKBMODE      0x4B45  /* sets current keyboard mode */
+
+struct kbentry {
+       u_char kb_table;
+       u_char kb_index;
+       u_char kb_value;
+};
+#define                K_NORMTAB       0x00
+#define                K_SHIFTTAB      0x01
+#define                K_ALTTAB        0x02
+#define                K_ALTSHIFTTAB   0x03
+#define                K_SRQTAB        0x04
+#define KDGKBENT       0x4B46  /* gets one entry in translation table */
+#define KDSKBENT       0x4B47  /* sets one entry in translation table */
+
+#endif /* _LINUX_KD_H */
index dabe5afa617c5ed4b30ed9c926ad92ce1799fd08..6478627bc2045a04bf06e819ecbc0c0cc4bebb2a 100644 (file)
@@ -5,6 +5,7 @@
  * minix fs inode data in memory
  */
 struct minix_inode_info {
+       unsigned short i_data[16];
 };
 
 #endif
diff --git a/include/linux/mktime.h b/include/linux/mktime.h
new file mode 100644 (file)
index 0000000..1c58e63
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _LINUX_MKTIME_H
+#define _LINUX_MKTIME_H
+
+struct mktime {
+       int sec;
+       int min;
+       int hour;
+       int day;
+       int mon;
+       int year;
+};
+
+#endif
diff --git a/include/linux/mman.h b/include/linux/mman.h
new file mode 100644 (file)
index 0000000..18e2539
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _LINUX_MMAN_H
+#define _LINUX_MMAN_H
+
+#define PROT_READ        0x1       /* page can be read */
+#define PROT_WRITE       0x2       /* page can be written */
+#define PROT_EXEC        0x4       /* page can be executed */
+#define PROT_NONE        0x0       /* page can not be accessed */
+
+#define MAP_SHARED       1         /* Share changes */
+#define MAP_PRIVATE      2         /* Changes are private */
+#define MAP_TYPE         0xf       /* Mask for type of mapping */
+#define MAP_FIXED        0x10      /* Interpret addr exactly */
+
+#endif /* _LINUX_MMAN_H */
index 7862a30cd4e11e24a9ba35c37e483b585ebf8469..f50db493ba28734bc84796a81b279fffa7e7db52 100644 (file)
@@ -3,6 +3,7 @@
 
 #define BUSMOUSE_MINOR 0
 #define PSMOUSE_MINOR  1
+#define MS_BUSMOUSE_MINOR 2
 
 long mouse_init(long);
 
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
new file mode 100644 (file)
index 0000000..7dc742d
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _LINUX_PIPE_FS_I_H
+#define _LINUX_PIPE_FS_I_H
+
+struct pipe_inode_info {
+       struct wait_queue * read_wait;
+       struct wait_queue * write_wait;
+       char * base;
+       unsigned int head;
+       unsigned int tail;
+       unsigned int readers;
+       unsigned int writers;
+};
+
+#define PIPE_READ_WAIT(inode)  ((inode).u.pipe_i.read_wait)
+#define PIPE_WRITE_WAIT(inode) ((inode).u.pipe_i.write_wait)
+#define PIPE_BASE(inode)       ((inode).u.pipe_i.base)
+#define PIPE_HEAD(inode)       ((inode).u.pipe_i.head)
+#define PIPE_TAIL(inode)       ((inode).u.pipe_i.tail)
+#define PIPE_READERS(inode)    ((inode).u.pipe_i.readers)
+#define PIPE_WRITERS(inode)    ((inode).u.pipe_i.writers)
+#define PIPE_SIZE(inode)       ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
+#define PIPE_EMPTY(inode)      (PIPE_HEAD(inode)==PIPE_TAIL(inode))
+#define PIPE_FULL(inode)       (PIPE_SIZE(inode)==(PAGE_SIZE-1))
+
+#endif
index a66f3bce9ccff42390a002a03079acb0460fbe2d..97aed5c13fb9ab7ddfdec31ca237095611ddea74 100644 (file)
@@ -160,6 +160,7 @@ struct task_struct {
        unsigned short rss;     /* number of resident pages */
        char comm[8];
        struct vm86_struct * vm86_info;
+       unsigned long screen_bitmap;
 /* file system info */
        int link_count;
        int tty;                /* -1 if no tty, so it must be signed */
@@ -211,7 +212,7 @@ struct task_struct {
 /* math */     0, \
 /* rss */      2, \
 /* comm */     "swapper", \
-/* vm86_info */        NULL, \
+/* vm86_info */        NULL, 0, \
 /* fs info */  0,-1,0022,NULL,NULL,NULL, \
 /* libraries */        { { NULL, 0, 0}, }, 0, \
 /* filp */     {NULL,}, 0, \
index d06179e690cafc538ad7de1a462d564c6d0c64d1..417ade5102c178826558d0539d62d9aed9286bd0 100644 (file)
@@ -249,6 +249,8 @@ extern void change_speed(unsigned int line);
 extern void send_break(unsigned int line);
 extern int get_serial_info(unsigned int, struct serial_struct *);
 extern int set_serial_info(unsigned int, struct serial_struct *);
+extern int get_modem_info(unsigned int, unsigned int *);
+extern int set_modem_info(unsigned int, unsigned int, unsigned int *);
 
 /* pty.c */
 
index 96b8959c5fcd73bccf9dff54affb5ac398509d79..0ef4c227221cbc0f7c8c59830cf4ca3d5c9e9f1e 100644 (file)
@@ -42,14 +42,15 @@ struct vm86_regs {
        long gs;
 };
 
-/*
- * flags isn't even used yet: it's just there as an example of
- * what kind of information we might want to give sys_vm86() (or
- * want it to return to us).
- */
 struct vm86_struct {
        struct vm86_regs regs;
        unsigned long flags;
+       unsigned long screen_bitmap;
 };
 
+/*
+ * flags masks
+ */
+#define VM86_SCREEN_BITMAP 1
+
 #endif
diff --git a/include/linux/vt.h b/include/linux/vt.h
new file mode 100644 (file)
index 0000000..477c01a
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _LINUX_VT_H
+#define _LINUX_VT_H
+
+/* 0x56 is 'V', to avoid collision with termios and kd */
+
+#define VT_OPENQRY     0x5600  /* find available vt */
+
+struct vt_mode {
+       char mode;              /* vt mode */
+       char waitv;             /* if set, hang on writes if not active */
+       short relsig;           /* signal to raise on release req */
+       short acqsig;           /* signal to raise on acquisition */
+       short frsig;            /* unused (set to 0) */
+};
+#define VT_GETMODE     0x5601  /* get mode of active vt */
+#define VT_SETMODE     0x5602  /* set mode of active vt */
+#define                VT_AUTO         0x00    /* auto vt switching */
+#define                VT_PROCESS      0x01    /* process controls switching */
+
+struct vt_stat {
+       ushort v_active;        /* active vt */
+       ushort v_signal;        /* signal to send */
+       ushort v_state;         /* vt bitmask */
+};
+#define VT_GETSTATE    0x5603  /* get global vt state info */
+#define VT_SENDSIG     0x5604  /* signal to send to bitmask of vts */
+
+#define VT_RELDISP     0x5605  /* release display */
+
+#define VT_ACTIVATE    0x5606  /* make vt active */
+
+#endif /* _LINUX_VT_H */
index f473ccbd923ff232bc283aa7854c34421a7d2c9d..110a569f060570f6837d5b35fd667f1edd00a75c 100644 (file)
@@ -5,11 +5,11 @@
  */
 
 #include <stdarg.h>
-#include <time.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
+#include <linux/mktime.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/config.h>
@@ -63,8 +63,7 @@ extern long chr_dev_init(long,long);
 extern void floppy_init(void);
 extern void sock_init(void);
 extern long rd_init(long mem_start, int length);
-extern long kernel_mktime(struct tm * tm);
-extern void malloc_grab_pages(void);
+extern long kernel_mktime(struct mktime * time);
 
 #ifdef CONFIG_SCSI
 extern void scsi_dev_init(void);
@@ -106,23 +105,23 @@ inb_p(0x71); \
 
 static void time_init(void)
 {
-       struct tm time;
+       struct mktime time;
 
        do {
-               time.tm_sec = CMOS_READ(0);
-               time.tm_min = CMOS_READ(2);
-               time.tm_hour = CMOS_READ(4);
-               time.tm_mday = CMOS_READ(7);
-               time.tm_mon = CMOS_READ(8);
-               time.tm_year = CMOS_READ(9);
-       } while (time.tm_sec != CMOS_READ(0));
-       BCD_TO_BIN(time.tm_sec);
-       BCD_TO_BIN(time.tm_min);
-       BCD_TO_BIN(time.tm_hour);
-       BCD_TO_BIN(time.tm_mday);
-       BCD_TO_BIN(time.tm_mon);
-       BCD_TO_BIN(time.tm_year);
-       time.tm_mon--;
+               time.sec = CMOS_READ(0);
+               time.min = CMOS_READ(2);
+               time.hour = CMOS_READ(4);
+               time.day = CMOS_READ(7);
+               time.mon = CMOS_READ(8);
+               time.year = CMOS_READ(9);
+       } while (time.sec != CMOS_READ(0));
+       BCD_TO_BIN(time.sec);
+       BCD_TO_BIN(time.min);
+       BCD_TO_BIN(time.hour);
+       BCD_TO_BIN(time.day);
+       BCD_TO_BIN(time.mon);
+       BCD_TO_BIN(time.year);
+       time.mon--;
        startup_time = kernel_mktime(&time);
 }
 
@@ -184,7 +183,6 @@ void start_kernel(void)
        buffer_init();
        time_init();
        floppy_init();
-       malloc_grab_pages();
        sock_init();
        sti();
 #ifdef CONFIG_SCSI
index 3bb280ed71d9c27a248960b4e551a47fee66a627..279afa87624935aae9d5ff64bc21b2135357f850 100644 (file)
@@ -45,7 +45,7 @@ clean:
 
 dep:
        sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-       for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+       $(CPP) -M *.c >> tmp_make
        cp tmp_make Makefile
        for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
 
index 55d48ca645ee8e1f364c631039bb864066d6fe5a..f4ddb35cd24496fd3f43045d05f39d4f2a114658 100644 (file)
@@ -37,7 +37,7 @@ clean:
 
 dep:
        sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-       for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+       $(CPP) -M *.c >> tmp_make
        cp tmp_make Makefile
        for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep); done
 
index 2288c57fc1e7c8c820301af3f02adfd63c5bfa11..62f1227200937b8095e922a8c8d30a93fdc5b120 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _BLK_H
 #define _BLK_H
 
-#define NR_BLK_DEV     10
+#define NR_BLK_DEV     12
 /*
  * NR_REQUEST is the number of entries in the request-queue.
  * NOTE that writes may use only the low 2/3 of these: reads
@@ -133,7 +133,16 @@ extern void set_device_ro(int dev,int flag);
 #define DEVICE_ON(device)
 #define DEVICE_OFF(device)
 
-#elif
+#elif (MAJOR_NR == 11)
+/* scsi CD-ROM */
+#define DEVICE_NAME "CD-ROM"
+#define DEVICE_INTR do_sr
+#define DEVICE_REQUEST do_sr_request
+#define DEVICE_NR(device) (MINOR(device))
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+
+#else
 /* unknown blk device */
 #error "unknown blk device"
 
index 81778be9cdecce59dbaed3681085773305b90e8b..da14ab6cebbee80b7d71925a271c11aa00bf4649 100644 (file)
@@ -75,9 +75,6 @@ static int seek = 0;
 
 extern unsigned char current_DOR;
 
-#define immoutb_p(val,port) \
-__asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port))
-
 #define TYPE(x) ((x)>>2)
 #define DRIVE(x) ((x)&0x03)
 
@@ -343,12 +340,15 @@ __asm__("cld ; rep ; movsl" \
 static void setup_DMA(void)
 {
        unsigned long addr,count;
+       unsigned char dma_code;
 
+       dma_code = DMA_WRITE;
+       if (command == FD_READ)
+               dma_code = DMA_READ;
        if (command == FD_FORMAT) {
                addr = (long) tmp_floppy_area;
                count = floppy->sect*4;
-       }
-       else {
+       } else {
                addr = (long) CURRENT->buffer;
                count = 1024;
        }
@@ -362,31 +362,30 @@ static void setup_DMA(void)
                if (command == FD_WRITE)
                        copy_buffer(CURRENT->buffer,tmp_floppy_area);
        }
-/* mask DMA 2 */
        cli();
 #ifndef HHB_SYSMACROS
-       immoutb_p(4|2,10);
+/* mask DMA 2 */
+       outb_p(4|2,10);
 /* output command byte. I don't know why, but everyone (minix, */
 /* sanches & canton) output this twice, first to 12 then to 11 */
-       __asm__("outb %%al,$12\n\tjmp 1f\n1:\tjmp 1f\n1:\t"
-       "outb %%al,$11\n\tjmp 1f\n1:\tjmp 1f\n1:"::
-       "a" ((char) ((command == FD_READ)?DMA_READ:DMA_WRITE)));
+       outb_p(dma_code,12);
+       outb_p(dma_code,11);
 /* 8 low bits of addr */
-       immoutb_p(addr,4);
+       outb_p(addr,4);
        addr >>= 8;
 /* bits 8-15 of addr */
-       immoutb_p(addr,4);
+       outb_p(addr,4);
        addr >>= 8;
 /* bits 16-19 of addr */
-       immoutb_p(addr,0x81);
+       outb_p(addr,0x81);
 /* low 8 bits of count-1 */
        count--;
-       immoutb_p(count,5);
+       outb_p(count,5);
        count >>= 8;
 /* high 8 bits of count-1 */
-       immoutb_p(count,5);
+       outb_p(count,5);
 /* activate DMA 2 */
-       immoutb_p(0|2,10);
+       outb_p(0|2,10);
 #else                  /* just to show off my macros -- hhb */
        DISABLE_DMA(DMA2);
        CLEAR_DMA_FF(DMA2);
index 058900966c731418c80baeb1747e86d9005fdc05..5e0342020141d0baa6da8d9160ffa54d8eb9efaa 100644 (file)
@@ -162,7 +162,7 @@ static void make_request(int major,int rw, struct buffer_head * bh)
        }
 repeat:
        cli();
-       if ((major == 3 ||  major == 8 )&& (req = blk_dev[major].current_request)) {
+       if ((major == 3 ||  major == 8 || major == 11)&& (req = blk_dev[major].current_request)) {
                while (req = req->next) {
                        if (req->dev == bh->b_dev &&
                            !req->waiting &&
index f9d8e57e4ff96fddfa27fac5b7a4faf45f4e4b2e..10d5305bd00e343e64c94daa2899c2ac725fafa2 100644 (file)
@@ -22,10 +22,11 @@ LOWLEVELSSRC = seagate2.s
 LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c
 LOWLEVELHSRC = aha1542.h fdomain.h seagate.h ultrastor.h 7000fasst.o
  
-CSRC = hosts.c sd.c sd_ioctl.c st.c st_ioctl.c scsi.c scsi_ioctl.c $(LOWLEVELCSRC)
-HSRC = hosts.h sd.h st.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC)
+CSRC = hosts.c sd.c sd_ioctl.c st.c st_ioctl.c sr.c sr_ioctl.c scsi.c scsi_ioctl.c $(LOWLEVELCSRC)
+HSRC = hosts.h sd.h st.h sr.h sr_ioctl.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC)
 
 OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \
+       sr.o sr_ioctl.o \
        aha1542.o fdomain.o seagate.o seagate2.o ultrastor.o 7000fasst.o
 
 all: scsi.a
index a616675a446f8ba9b80c3da47edaaeab66620036..6d974f938151227d9ced66d7d1b7edf200dbe46b 100644 (file)
@@ -188,7 +188,7 @@ int aha1542_test_port(void)
 /* What's this little function for? */
 char *aha1542_info(void)
 {
-    static char buffer[] = "Adaptec 1542";
+    static char buffer[] = "";                 /* looks nicer without anything here */
     return buffer;
 }
 
@@ -200,6 +200,8 @@ void aha1542_intr_handle(void)
 
     do_done = NULL;
 #ifdef DEBUG
+    {
+    int flag = inb(INTRFLAGS);
     printk("aha1542_intr_handle: ");
     if (!(flag&ANYINTR)) printk("no interrupt?");
     if (flag&MBIF) printk("MBIF ");
@@ -209,6 +211,7 @@ void aha1542_intr_handle(void)
     printk("status %02x\n", inb(STATUS));
     if (ccb.tarstat|ccb.hastat)
       printk("aha1542_command: returning %x (status %d)\n", ccb.tarstat + ((int) ccb.hastat << 16), mb[1].status);
+  };
 #endif
     aha1542_intr_reset();
     if (!my_done) {
@@ -236,9 +239,11 @@ void aha1542_intr_handle(void)
     if (ccb.tarstat == 2) {
        int i;
        DEB(printk("aha1542_intr_handle: sense:"));
+#ifdef DEBUG
        for (i = 0; i < 12; i++)
          printk("%02x ", ccb.cdb[ccb.cdblen+i]);
        printk("\n");
+#endif
 /*
        DEB(printk("aha1542_intr_handle: buf:"));
        for (i = 0; i < bufflen; i++)
@@ -259,6 +264,12 @@ int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int buffle
 
     DEB(if (target > 1) {done(aha1542_host, DID_TIME_OUT << 16); return 0;});
     
+    if(*cmd == REQUEST_SENSE){
+      memcpy(buff, &ccb.cdb[ccb.cdblen], bufflen);
+      done(aha1542_host, 0); 
+      return 0;
+    };
+
 #ifdef DEBUG
     if (*cmd == READ_10 || *cmd == WRITE_10)
       i = xscsi2int(cmd+2);
@@ -387,10 +398,10 @@ int aha1542_detect(int hostnum)
        aha1542_intr_reset();
     }
 
-    aha1542_stat();
+    DEB(aha1542_stat());
     setup_mailboxes();
 
-    aha1542_stat();
+    DEB(aha1542_stat());
 
     DEB(printk("aha1542_detect: enable interrupt channel %d\n", intr_chan));
     call_buh();
index 1469ce291b09fb04e120d9390fb896e06f7a0d5c..a9b175819be74ffa4f421dfe401654c7948b6e6c 100644 (file)
 #include "st.h"
 #endif
 
+#ifdef CONFIG_BLK_DEV_SR
+#include "sr.h"
+#endif
+
 /*
 static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
 */
 
-#define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic(""))
+#define INTERNAL_ERROR (printk ("Internal error in file %s, line %d.\n", __FILE__, __LINE__), panic(""))
 
 static void scsi_done (int host, int result);
 static void update_timeout (void);
+static void print_inquiry(unsigned char *data);
 
 static int time_start;
 static int time_elapsed;
@@ -214,6 +219,13 @@ static void scan_scsis (void)
                                                                scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES];
 #endif
                                                        break;
+                                                       case TYPE_ROM:
+                                                               printk("Detected scsi CD-ROM at host %d, ID  %d, lun %d \n", host_nr, dev, lun);
+#ifdef CONFIG_BLK_DEV_SR
+                                                                       if (!(maxed = (NR_SR >= MAX_SR)))
+                                                                               scsi_CDs[NR_SR].device = &scsi_devices[NR_SCSI_DEVICES];
+#endif
+                                                               break;
                                                 default :
 #ifdef DEBUG
                                                        printk("Detected scsi disk at host %d, ID  %d, lun %d \n", host_nr, dev, lun);
@@ -224,11 +236,20 @@ static void scan_scsis (void)
 #endif
                                                }
 
+                                               print_inquiry(scsi_result);
+
                                                 if (maxed)
                                                        {
-                                                       printk ("scsi : already have detected maximum number of SCSI %ss Unable to \n"
-                                                                "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ?
-                                                                "tape" : "disk", scsi_hosts[host_nr].name,
+                                                                printk ("Already have detected "
+                                                                       "maximum number of SCSI "
+                                                                       "%ss Unable to \n"
+                                                                        "add drive at SCSI host "
+                                                                       "%s, ID %d, LUN %d\n\r", 
+                                                                       (type == TYPE_TAPE) ?
+                                                                             "tape" : 
+                                                                       (type == TYPE_DISK) ?
+                                                                            "disk" : "CD-ROM", 
+                                                                       scsi_hosts[host_nr].name,
                                                                 dev, lun);
                                                         type = -1;
                                                         break;
@@ -246,7 +267,7 @@ for (; *p != ' '; ++p);
 *p = 0;
 
 printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
-       (type == TYPE_TAPE) ? 't' : 'd',
+       (type == TYPE_TAPE) ? 't' : ((type == TYPE_ROM) ? 'r' : 'd'),
        (type == TYPE_TAPE) ? 
 #ifdef CONFIG_BLK_DEV_ST
        NR_ST  
@@ -254,11 +275,20 @@ printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
        -1
 #endif
        : 
+       (type == TYPE_ROM ? 
+#ifdef CONFIG_BLK_DEV_SR
+       NR_SR
+#else
+       -1      
+#endif
+       :
 #ifdef CONFIG_BLK_DEV_SD
        NR_SD
 #else
        -1      
 #endif
+       )
+
        ,host_nr , dev, lun, p); 
                                                         if (type == TYPE_TAPE)
 #ifdef CONFIG_BLK_DEV_ST
@@ -267,11 +297,17 @@ printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
 ;
 #endif
 
-                                                       else
+                                                  else if (type == TYPE_DISK)
 #ifdef CONFIG_BLK_DEV_SD
                                                                ++NR_SD;
 #else
 ;
+#endif
+                                                               else
+#ifdef CONFIG_BLK_DEV_SR
+                                                                       ++NR_SR;
+#else
+;
 #endif
                                                                 }
                                                        ++slave;
@@ -289,17 +325,22 @@ printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
        "%d tape%s "
 #endif
 
-       "total.\n",  
+#ifdef CONFIG_BLK_DEV_SR
+"%d CD-ROM drive%s "
+#endif
+
+       "total.\n"  
 
 #ifdef CONFIG_BLK_DEV_SD
-       NR_SD, (NR_SD != 1) ? "s" : ""
-#ifdef CONFIG_BLK_DEV_ST 
-       ,
-#endif
+       , NR_SD, (NR_SD != 1) ? "s" : ""
 #endif
 
 #ifdef CONFIG_BLK_DEV_ST
-       NR_ST, (NR_ST != 1) ? "s" : ""
+       , NR_ST, (NR_ST != 1) ? "s" : ""
+#endif
+
+#ifdef CONFIG_BLK_DEV_SR
+        , NR_SR, (NR_SR != 1) ? "s" : ""
 #endif
        );
        in_scan = 0;
@@ -388,7 +429,6 @@ update_timeout();
                "bufflen = %d, done = %08x)\n", host, target, cmnd, buffer, bufflen, done);
 #endif
 
-       
         if (scsi_hosts[host].can_queue)
                {
 #ifdef DEBUG
@@ -557,8 +597,8 @@ static void reset (int host)
 
 static int check_sense (int host)
        {
-       if (((sense_buffer[0] & 0x70) >> 4) == 7)
-               switch (sense_buffer[2] & 0xf)
+       if (((last_cmnd[host].sense_buffer[0] & 0x70) >> 4) == 7)
+               switch (last_cmnd[host].sense_buffer[2] & 0xf)
                {
                case NO_SENSE:
                case RECOVERED_ERROR:
@@ -600,6 +640,7 @@ static void scsi_done (int host, int result)
 #define FINISHED 0
 #define MAYREDO  1
 #define REDO    3
+#define PENDING  4
 
 #ifdef DEBUG
        printk("In scsi_done(host = %d, result = %06x)\n", host, result);
@@ -705,6 +746,7 @@ static void scsi_done (int host, int result)
 #endif
 
                                scsi_request_sense (host, last_cmnd[host].target, last_cmnd[host].lun);
+                               status = PENDING;
                                break;          
                        
                        case CONDITION_GOOD:
@@ -786,6 +828,7 @@ static void scsi_done (int host, int result)
        switch (status) 
                {
                case FINISHED:
+               case PENDING:
                        break;
                case MAYREDO:
 
@@ -836,7 +879,7 @@ static void scsi_done (int host, int result)
 #undef FINISHED
 #undef REDO
 #undef MAYREDO
-               
+#undef PENDING
        }
 
 /*
@@ -1056,5 +1099,59 @@ void scsi_dev_init (void)
 #ifdef CONFIG_BLK_DEV_ST
         st_init();              /* init scsi tapes */
 #endif
+
+#ifdef CONFIG_BLK_DEV_SR
+       sr_init();
+#endif
        }
 #endif
+
+static void print_inquiry(unsigned char *data)
+{
+        int i;
+
+       printk("  Vendor:");
+       for (i = 8; i < 15; i++)
+               {
+               if (data[i] >= 20)
+                       printk("%c", data[i]);
+               else
+                       printk(" ");
+               }
+
+       printk("  Model:");
+       for (i = 16; i < 31; i++)
+               {
+               if (data[i] >= 20)
+                       printk("%c", data[i]);
+               else
+                       printk(" ");
+               }
+
+       printk("  Rev:");
+       for (i = 32; i < 35; i++)
+               {
+               if (data[i] >= 20)
+                       printk("%c", data[i]);
+               else
+                       printk(" ");
+               }
+
+       printk("\n");
+
+       i = data[0] & 0x1f;
+
+       printk("  Type: %s ",   i == 0x00 ? "Direct-Access    " :
+                               i == 0x01 ? "Sequential-Access" :
+                               i == 0x02 ? "Printer          " :
+                               i == 0x03 ? "Processor        " :
+                               i == 0x04 ? "WORM             " :
+                               i == 0x05 ? "CD-ROM           " :
+                               i == 0x06 ? "Scanner          " :
+                               i == 0x07 ? "Optical Device   " :
+                               i == 0x08 ? "Medium Changer   " :
+                               i == 0x09 ? "Communications   " :
+                                           "Unknown          " );
+       printk("ANSI SCSI revision: %02x\n", data[2] & 0x07);
+}
+
index 60ca1761751a5ee3d025828a72dc544ae75ab44b..a64f72876c18e830b11b32c4c8e97784685a0dfe 100644 (file)
@@ -254,6 +254,9 @@ extern void scsi_dev_init (void);
 
 /*
        You guesed it.  This sends a command to the selected SCSI host 
+
+extern void print_inquiry(unsigned char *data);
+
 */
 
 
index 5e034ccf4ecc9fe9168ea9cc89c3391bc7e46b94..e477020281736045d7f9c2f820248078020fcbf0 100644 (file)
@@ -38,7 +38,7 @@ struct hd_struct sd[MAX_SD << 4];
                                
 int NR_SD=0;
 Scsi_Disk rscsi_disks[MAX_SD];
-static int sd_sizes[MAX_SD << 4];
+static int sd_sizes[MAX_SD << 4] = {0, };
 static int this_count;
 static int the_result;
 
@@ -56,9 +56,7 @@ static struct gendisk sd_gendisk;
 static void sd_geninit (void) {
        int i;
        for (i = 0; i < NR_SD; ++i)
-               sd_sizes[i << 4] = 
-               (sd[i << 4].nr_sects = rscsi_disks[i].capacity) >>
-               (BLOCK_SIZE_BITS - 9);
+         sd[i << 4].nr_sects = rscsi_disks[i].capacity;
        sd_gendisk.nr_real = NR_SD;
 }
 
@@ -414,9 +412,8 @@ void sd_init(void)
                }
 
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
-       blk_size[MAJOR_NR] = sd_sizes;  
-       blkdev_fops[MAJOR_NR] = &sd_fops; 
+       blkdev_fops[MAJOR_NR] = &sd_fops;
        sd_gendisk.next = gendisk_head;
        gendisk_head = &sd_gendisk;
-}      
+}
 #endif
diff --git a/kernel/blk_drv/scsi/sr.c b/kernel/blk_drv/scsi/sr.c
new file mode 100644 (file)
index 0000000..c7e9bce
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ *      sr.c by David Giller
+ *
+ *      adapted from:
+ *     sd.c Copyright (C) 1992 Drew Eckhardt 
+ *     Linux scsi disk driver by
+ *             Drew Eckhardt 
+ *
+ *     <drew@colorado.edu>
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_BLK_DEV_SR
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+
+#include "scsi.h"
+#include "sr.h"
+
+#define MAJOR_NR 11
+
+#include "../blk.h"
+
+#define MAX_RETRIES 0
+#define SR_TIMEOUT 200
+
+int NR_SR=0;
+Scsi_CD scsi_CDs[MAX_SR];
+static int sr_sizes[MAX_SR << 4];
+static unsigned long int this_count;
+
+struct block_buffer
+       {
+       unsigned        block;
+       unsigned        start;
+       unsigned        use:1;
+       unsigned char   buffer[2048];
+       };
+
+static struct block_buffer bb[MAX_SR];
+
+static int sr_result;
+
+static int sr_open(struct inode *, struct file *);
+
+extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned int);
+
+static void sr_release(struct inode * inode, struct file * file)
+{
+       sync_dev(inode->i_rdev);
+}
+
+static struct file_operations sr_fops = 
+{
+       NULL,                   /* lseek - default */
+       block_read,             /* read - general block-dev read */
+       block_write,            /* write - general block-dev write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* select */
+       sr_ioctl,               /* ioctl */
+       sr_open,                /* no special open code */
+       sr_release              /* release */
+};
+
+/*
+ * The sense_buffer is where we put data for all mode sense commands performed.
+ */
+
+static unsigned char sense_buffer[255];
+
+/*
+ * rw_intr is the interrupt routine for the device driver.  It will be notified on the 
+ * end of a SCSI read / write, and will take on of several actions based on success or failure.
+ */
+
+static void rw_intr (int host, int result)
+{
+       if (SR_HOST != host)            
+               {
+               panic ("sr.o : rw_intr() recieving interrupt for different host.");
+               }
+
+       if (!result)
+               { /* No error */
+               if (bb[DEVICE_NR(CURRENT->dev)].use)
+                       {
+                       memcpy((char *)CURRENT->buffer, 
+                              bb[DEVICE_NR(CURRENT->dev)].buffer + 
+                              (bb[DEVICE_NR(CURRENT->dev)].start << 9), 
+                              this_count << 9);
+                       }
+
+               CURRENT->nr_sectors -= this_count;
+
+#ifdef DEBUG
+               printk("(%x %x %x) ",CURRENT->bh, CURRENT->nr_sectors, 
+                      this_count);
+#endif
+               if (CURRENT->nr_sectors)
+                       {        
+                       CURRENT->sector += this_count;
+                       CURRENT->errors = 0;
+                       if (!CURRENT->bh)
+                         {
+                           (char *) CURRENT->buffer += this_count << 9;
+                         } else {
+                           end_request(1);
+                           do_sr_request();
+                         }
+                       }
+               else 
+                       {
+                       end_request(1);  /* All done */
+                       do_sr_request();
+                       } 
+               }
+
+       /* We only come through here if we have an error of some kind */
+
+       if (driver_byte(result) != 0) {
+               bb[DEVICE_NR(CURRENT->dev)].block = -1;
+               
+               if ((sense_buffer[0] & 0x7f) == 0x70) {
+                       if ((sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
+                               /* detected disc change.  set a bit and quietly refuse  */
+                               /* further access.                                      */
+                   
+                               scsi_CDs[DEVICE_NR(CURRENT->dev)].changed = 1;
+                               end_request(0);
+                               return;
+                       }
+               }
+           
+               if (sense_buffer[2] == ILLEGAL_REQUEST) {
+                       printk("CD-ROM error: Drive reports ILLEGAL REQUEST.\n");
+                       if (scsi_CDs[DEVICE_NR(CURRENT->dev)].ten) {
+                               scsi_CDs[DEVICE_NR(CURRENT->dev)].ten = 0;
+                               do_sr_request();
+                               result = 0;
+                               return;
+                       } else {
+                               end_request(0);
+                               do_sr_request(); /* Do next request */
+                               return;
+                       }
+
+               }
+
+               if (sense_buffer[2] == NOT_READY) {
+                       printk("CDROM not ready.  Make sure you have a disc in the drive.\n");
+                       end_request(0);
+                       do_sr_request(); /* Do next request */
+                       return;
+               };
+             }
+       
+       /* We only get this far if we have an error we have not recognized */
+       if(result) {
+         printk("SCSI CD error : host %d id %d lun %d return code = %03x\n", 
+                scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no, 
+                scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id,
+                scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun,
+                result);
+           
+       if (status_byte(result) == CHECK_CONDITION)
+           printk("\tSense class %x, sense error %x, extended sense %x\n",
+                sense_class(sense_buffer[0]), 
+                sense_error(sense_buffer[0]),
+                sense_buffer[2] & 0xf);
+       
+       end_request(0);
+       do_sr_request();
+       }
+}
+
+static int sr_open(struct inode * inode, struct file * filp)
+{
+       if (filp->f_mode)
+               check_disk_change(inode->i_rdev);
+       return 0;
+}
+
+/*
+ * do_sr_request() is the request handler function for the sr driver.  Its function in life 
+ * is to take block device requests, and translate them to SCSI commands.
+ */
+       
+void do_sr_request (void)
+{
+       unsigned int dev, block, realcount;
+       unsigned char cmd[10], *buffer, tries;
+
+       tries = 2;
+
+      repeat:
+       INIT_REQUEST;
+       dev =  MINOR(CURRENT->dev);
+       block = CURRENT->sector;        
+
+       bb[dev].start = block % 4;
+       block = block / 4;
+
+       if (dev >= NR_SR)
+               {
+               /* printk("CD-ROM request error: invalid device.\n");                   */
+               end_request(0);
+               tries = 2;
+               goto repeat;
+               }
+
+       if (!scsi_CDs[dev].use)
+               {
+               /* printk("CD-ROM request error: device marked not in use.\n");         */
+               end_request(0);
+               tries = 2;
+               goto repeat;
+               }
+
+       if (scsi_CDs[dev].changed)
+               {
+/* 
+ * quietly refuse to do anything to a changed disc until the changed bit has been reset
+ */
+               /* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");      */
+               end_request(0);
+               tries = 2;
+               goto repeat;
+               }
+       
+       if (!CURRENT->bh)       
+               this_count = CURRENT->nr_sectors;
+       else
+               this_count = (CURRENT->bh->b_size / 512);
+
+       if (bb[dev].start)
+               {                                 
+               bb[dev].use = 1;
+
+               this_count = ((this_count > 4 - bb[dev].start) ? 
+                             (4 - bb[dev].start) : (this_count));
+
+               if (bb[dev].block == block)
+                       {
+                         rw_intr(SR_HOST, 0);
+                         return;
+                       }
+
+               buffer = bb[dev].buffer;
+               bb[dev].block = block;
+               } 
+       else if (this_count < 4)
+               {
+               bb[dev].use = 1;
+
+               if (bb[dev].block == block)
+                       {
+                         rw_intr(SR_HOST, 0);
+                         return;
+                       }
+
+               buffer = bb[dev].buffer;
+               bb[dev].block = block;
+               }
+       else
+               {
+               this_count -= this_count % 4;
+               buffer = CURRENT->buffer;
+               bb[dev].use = 0;
+               }
+
+       realcount = (this_count + 3) / 4;
+
+       switch (CURRENT->cmd)
+               {
+               case WRITE:             
+                       end_request(0);
+                       goto repeat;
+                       break;
+               case READ : 
+                       cmd[0] = READ_6;
+                       break;
+               default : 
+                       printk ("Unknown sr command %d\r\n", CURRENT->cmd);
+                       panic("");
+               }
+       
+       cmd[1] = (SR_LUN << 5) & 0xe0;
+
+       if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 
+               {
+               if (realcount > 0xffff)
+                       {
+                       realcount = 0xffff;
+                       this_count = realcount * 4;
+                       }
+
+               cmd[0] += READ_10 - READ_6 ;
+               cmd[2] = (unsigned char) (block >> 24) & 0xff;
+               cmd[3] = (unsigned char) (block >> 16) & 0xff;
+               cmd[4] = (unsigned char) (block >> 8) & 0xff;
+               cmd[5] = (unsigned char) block & 0xff;
+               cmd[6] = cmd[9] = 0;
+               cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
+               cmd[8] = (unsigned char) realcount & 0xff;
+               }
+       else
+               {
+               if (realcount > 0xff)
+                       {
+                       realcount = 0xff;
+                       this_count = realcount * 4;
+                       }
+       
+               cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
+               cmd[2] = (unsigned char) ((block >> 8) & 0xff);
+               cmd[3] = (unsigned char) block & 0xff;
+               cmd[4] = (unsigned char) realcount;
+               cmd[5] = 0;
+               }   
+
+       scsi_do_cmd (SR_HOST, SR_ID, (void *) cmd, buffer, realcount << 11, 
+                    rw_intr, SR_TIMEOUT, sense_buffer, MAX_RETRIES);
+}
+
+void sr_init(void)
+{
+       int i;
+
+       for (i = 0; i < NR_SR; ++i)
+               {
+               scsi_CDs[i].capacity = 0x1fffff;
+               scsi_CDs[i].sector_size = 2048;
+               scsi_CDs[i].use = 1;
+               scsi_CDs[i].ten = 1;
+               scsi_CDs[i].remap = 1;
+               scsi_CDs[i].changed = 0;
+               sr_sizes[i] = scsi_CDs[i].capacity;
+
+               bb[i].block = -1;
+               }
+
+       blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+       blk_size[MAJOR_NR] = sr_sizes;  
+       blkdev_fops[MAJOR_NR] = &sr_fops; 
+}      
+#endif
+
+
+
+
+
diff --git a/kernel/blk_drv/scsi/sr.h b/kernel/blk_drv/scsi/sr.h
new file mode 100644 (file)
index 0000000..5361efb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *      sr.h by David Giller
+ *      CD-ROM disk driver header file
+ *      
+ *      adapted from:
+ *     sd.h Copyright (C) 1992 Drew Eckhardt 
+ *     SCSI disk driver header file by
+ *             Drew Eckhardt 
+ *
+ *     <drew@colorado.edu>
+ */
+
+#ifndef _SR_H
+#define _SR_H
+
+#include "scsi.h"
+
+#define MAX_SR 2
+extern int NR_SR;
+
+typedef struct
+       {
+       unsigned        capacity;               /* size in blocks                       */
+       unsigned        sector_size;            /* size in bytes                        */
+       Scsi_Device     *device;                
+       unsigned char   sector_bit_size;        /* sector size = 2^sector_bit_size      */
+       unsigned char   sector_bit_shift;       /* sectors/FS block = 2^sector_bit_shift*/
+       unsigned        ten:1;                  /* support ten byte commands            */
+       unsigned        remap:1;                /* support remapping                    */
+       unsigned        use:1;                  /* is this device still supportable     */
+       unsigned        changed:1;              /* disk changed flag                    */
+       } Scsi_CD;
+       
+extern Scsi_CD scsi_CDs[MAX_SR];
+
+void sr_init(void);
+
+#define SR_HOST (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->host_no)
+#define SR_ID (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->id)
+#define SR_LUN (scsi_CDs[DEVICE_NR(CURRENT->dev)].device->lun)
+#endif
diff --git a/kernel/blk_drv/scsi/sr_ioctl.c b/kernel/blk_drv/scsi/sr_ioctl.c
new file mode 100644 (file)
index 0000000..ded0094
--- /dev/null
@@ -0,0 +1,331 @@
+#include <linux/config.h>
+#ifdef CONFIG_BLK_DEV_SR
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <asm/segment.h>
+#include <linux/errno.h>
+
+#include "../blk.h"
+#include "scsi.h"
+#include "sr.h"
+
+#include <linux/cdrom.h>
+
+#define IOCTL_RETRIES 3
+/* The CDROM is fairly slow, so we need a little extra time */
+#define IOCTL_TIMEOUT 200
+
+static u_char  sr_cmd[10];
+static u_char  data_buffer[255];
+static u_char  sense_buffer[255];
+static int     the_result;
+
+static struct wait_queue *sr_cmd_wait = NULL;   /* For waiting until cmd done*/
+static u_char  sr_lock = 0;   /* To make sure that only one person is doing
+                                 an ioctl at one time */
+static int     target;
+
+extern int scsi_ioctl (int dev, int cmd, void *arg);
+
+static void lock_sr_ioctl( void )
+{
+  /* We do not use wakeup here because there could conceivably be three
+     processes trying to get at the drive simultaneously, and we would
+     be screwed if that happened.
+     */
+
+       while (sr_lock);
+       sr_lock = 1;
+}
+
+static void unlock_sr_ioctl( void )
+{
+       sr_lock = 0;
+}
+
+static void sr_ioctl_done( int host, int result )
+{
+       the_result = result;
+       wake_up(&sr_cmd_wait);
+}
+
+/* We do our own retries because we want to know what the specific
+   error code is.  Normally the UNIT_ATTENTION code will automatically
+   clear after one error */
+
+static int do_ioctl( void )
+{
+       int retries = IOCTL_RETRIES;
+retry:     
+
+       the_result = -1;
+
+       scsi_do_cmd(scsi_CDs[target].device->host_no, scsi_CDs[target].device->id,
+                   (void *) sr_cmd, (void *) data_buffer, 255, sr_ioctl_done, 
+                   IOCTL_TIMEOUT, (void *) sense_buffer, 0);
+
+       while (the_result < 0) sleep_on(&sr_cmd_wait);
+
+       if(driver_byte(the_result) != 0 && 
+          (sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
+         scsi_CDs[target].changed = 1;
+         printk("Disc change detected.\n");
+       };
+
+       if (the_result && retries)
+               {
+               retries--;
+               goto retry;
+               }
+
+/* Minimal error checking.  Ignore cases we know about, and report the rest. */
+       if(driver_byte(the_result) != 0)
+         switch(sense_buffer[2] & 0xf) {
+         case UNIT_ATTENTION:
+           scsi_CDs[target].changed = 1;
+           printk("Disc change detected.\n");
+           break;
+         case NOT_READY: /* This happens if there is no disc in drive */
+           printk("CDROM not ready.  Make sure there is a disc in the drive.\n");
+           break;
+         case ILLEGAL_REQUEST:
+           printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
+           break;
+         default:
+           printk("SCSI CD error: host %d id %d lun %d return code = %03x\n", 
+                  scsi_CDs[target].device->host_no, 
+                  scsi_CDs[target].device->id,
+                  scsi_CDs[target].device->lun,
+                  the_result);
+           printk("\tSense class %x, sense error %x, extended sense %x\n",
+                  sense_class(sense_buffer[0]), 
+                  sense_error(sense_buffer[0]),
+                  sense_buffer[2] & 0xf);
+           
+       };
+       return the_result;
+}
+       
+/*
+ * This function checks to see if the media has been changed in the
+ * CDROM drive.  It is possible that we have already sensed a change,
+ * or the drive may have sensed one and not yet reported it.  We must
+ * be ready for either case. This function always reports the current
+ * value of the changed bit.  If flag is 0, then the changed bit is reset.
+ * This function could be done as an ioctl, but we would need to have
+ * an inode for that to work, and we do not always have one.
+ */
+
+int check_cdrom_media_change(int full_dev, int flag){
+       int retval;
+
+       lock_sr_ioctl();
+
+       target =  MINOR(full_dev);
+
+       if (target >= NR_SR) {
+               printk("CD-ROM request error: invalid device.\n");
+               unlock_sr_ioctl();
+               return 0;
+       };
+
+       sr_cmd[0] = TEST_UNIT_READY;
+       sr_cmd[1] = (scsi_CDs[target].device->lun << 5) & 0xe0;
+       sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
+
+       retval = do_ioctl();
+
+       if(retval){ /* Unable to test, unit probably not ready.  This usually
+                    means there is no disc in the drive.  Mark as changed,
+                    and we will figure it out later once the drive is
+                    available again.  */
+
+         scsi_CDs[target].changed = 1;
+         unlock_sr_ioctl();
+         return 1; /* This will force a flush, if called from
+                      check_disk_change */
+       };
+
+       retval = scsi_CDs[target].changed;
+       if(!flag) scsi_CDs[target].changed = 0;
+       unlock_sr_ioctl();
+
+       return retval;
+}
+
+int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
+{
+       int dev = inode->i_rdev;
+       int result;
+
+       target = MINOR(dev);
+
+       switch (cmd) 
+               {
+               /* linux-specific */
+               case CDROMDOORUNLOCK:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+                       sr_cmd[4] = SR_REMOVAL_ALLOW;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               case CDROMDOORLOCK:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+                       sr_cmd[4] = SR_REMOVAL_PREVENT;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               /* Sun-compatible */
+               case CDROMPAUSE:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = SCMD_PAUSE_RESUME;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
+                       sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
+                       sr_cmd[8] = 1;
+                       sr_cmd[9] = 0;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               case CDROMRESUME:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = SCMD_PAUSE_RESUME;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
+                       sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
+                       sr_cmd[8] = 0;
+                       sr_cmd[9] = 0;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               case CDROMPLAYMSF:
+                       {
+                       struct cdrom_msf msf;
+                       lock_sr_ioctl();
+
+                       memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
+
+                       sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = 0;
+                       sr_cmd[3] = msf.cdmsf_min0;
+                       sr_cmd[4] = msf.cdmsf_sec0;
+                       sr_cmd[5] = msf.cdmsf_frame0;
+                       sr_cmd[6] = msf.cdmsf_min1;
+                       sr_cmd[7] = msf.cdmsf_sec1;
+                       sr_cmd[8] = msf.cdmsf_frame1;
+                       sr_cmd[9] = 0;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+                       }
+
+               case CDROMPLAYTRKIND:
+                       {
+                       struct cdrom_ti ti;
+                       lock_sr_ioctl();
+
+                       memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
+
+                       sr_cmd[0] = SCMD_PLAYAUDIO_TI;
+                       sr_cmd[1] = scsi_CDs[target].device->lun << 5;
+                       sr_cmd[2] = 0;
+                       sr_cmd[3] = 0;
+                       sr_cmd[4] = ti.cdti_trk0;
+                       sr_cmd[5] = ti.cdti_ind0;
+                       sr_cmd[6] = 0;
+                       sr_cmd[7] = ti.cdti_trk1;
+                       sr_cmd[8] = ti.cdti_ind1;
+                       sr_cmd[9] = 0;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+                       }
+
+               case CDROMREADTOCHDR:
+                       return -EINVAL;
+               case CDROMREADTOCENTRY:
+                       return -EINVAL;
+
+               case CDROMSTOP:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = START_STOP;
+                       sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+                       sr_cmd[4] = 0;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+                       
+               case CDROMSTART:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = START_STOP;
+                       sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+                       sr_cmd[4] = 1;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               case CDROMEJECT:
+                       lock_sr_ioctl();
+
+                       sr_cmd[0] = START_STOP;
+                       sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
+                       sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
+                       sr_cmd[4] = 0x02;
+
+                       result = do_ioctl();
+
+                       unlock_sr_ioctl();
+                       return result;
+
+               case CDROMVOLCTRL:
+                       return -EINVAL;
+               case CDROMSUBCHNL:
+                       return -EINVAL;
+               case CDROMREADMODE2:
+                       return -EINVAL;
+               case CDROMREADMODE1:
+                       return -EINVAL;
+
+               RO_IOCTLS(dev,arg);
+               default:
+                       return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
+               }
+}
+
+#endif
index 9cfc0c5c0742bc763d57c310112840d6a4bf45fc..391ad889cec58f7d59842f45d548a368fb536cee 100644 (file)
@@ -23,8 +23,11 @@ chr_drv.a: $(OBJS)
        $(AR) rcs chr_drv.a $(OBJS)
        sync
 
+console.o: console.c
+       $(CC) $(CFLAGS) $(NUM_LOCK) -c -o console.o console.c
+
 keyboard.o: keyboard.c
-       $(CC) $(CFLAGS) $(KEYBOARD) -c -o keyboard.o keyboard.c
+       $(CC) $(CFLAGS) $(KEYBOARD) $(NUM_LOCK) -c -o keyboard.o keyboard.c
 
 clean:
        rm -f core *.o *.a tmp_make keyboard.s
index 943111f70b7ac0c1b37399c42cdc86f8ec2f2b42..1b7277a12aa70fd82f24e84d4f5cf22de34453f9 100644 (file)
  *   removed assignment chr_fops[10] = &mouse_fops; see mouse.c
  *   renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
  *   renamed this file mouse.c => busmouse.c
- * 
- * version 0.1
+ *
+ * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+ *
+ * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+ *    8/28/92
+ *
+ * Microsoft Bus Mouse support folded into 0.97pl4 code
+ *    by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ * Changes:  Logitech and Microsoft support in the same kernel.
+ *           Defined new constants in busmouse.h for MS mice.
+ *           Added int mse_busmouse_type to distinguish busmouse types
+ *           Added a couple of new functions to handle differences in using
+ *             MS vs. Logitech (where the int variable wasn't appropriate).
+ *
+ * version 0.2
  */
 
 #include       <linux/kernel.h>
@@ -33,6 +46,7 @@
 #include       <asm/system.h>
 #include       <asm/irq.h>
 
+
 static struct mouse_status mouse;
 
 static void mouse_interrupt(int unused)
@@ -65,11 +79,47 @@ static void mouse_interrupt(int unused)
                 wake_up(&mouse.inode->i_wait);
        
        MSE_INT_ON();
+       
+}
+
+/*  Use separate function for MS mice - keep both short & fast */
+static void ms_mouse_interrupt(int unused)
+{
+       char dx, dy, buttons;
+
+       outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
+       outb((inb(MS_MSE_DATA_PORT) | 0x20), MS_MSE_DATA_PORT);
+
+       outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT);
+       dx = inb(MS_MSE_DATA_PORT);
+
+       outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT);
+       dy = inb(MS_MSE_DATA_PORT);
+
+       outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT);
+       buttons = ~(inb(MS_MSE_DATA_PORT)) & 0x07;
+
+       outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT);
+       outb((inb(MS_MSE_DATA_PORT) & 0xdf), MS_MSE_DATA_PORT);
+
+       mouse.buttons = buttons;
+       mouse.latch_buttons |= buttons;
+       mouse.dx += dx;
+       mouse.dy += dy;
+       mouse.ready = 1;
+       if (mouse.inode && mouse.inode->i_wait)
+                wake_up(&mouse.inode->i_wait);
+       
 }
 
 static void release_mouse(struct inode * inode, struct file * file)
 {
-       MSE_INT_OFF();
+        if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+         MSE_INT_OFF();
+       } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) {
+         MS_MSE_INT_OFF();
+       } /* else if next mouse type, etc. */
+
        mouse.active = 0;
        mouse.ready = 0; 
        mouse.inode = NULL;
@@ -88,15 +138,31 @@ static int open_mouse(struct inode * inode, struct file * file)
        mouse.dx = 0;
        mouse.dy = 0;   
        mouse.buttons = mouse.latch_buttons = 0x80;
-       if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
-               /* once we get to here mouse is unused, IRQ is busy */
-               mouse.active = 0;  /* it's not active, fix it */
-               return -EBUSY;     /* IRQ is busy, so we're BUSY */
-       } /* if we can't get the IRQ and mouse not active */
-       MSE_INT_ON();   
+
+       if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+         if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
+           /* once we get to here mouse is unused, IRQ is busy */
+           mouse.active = 0;  /* it's not active, fix it */
+           return -EBUSY;     /* IRQ is busy, so we're BUSY */
+         } /* if we can't get the IRQ and mouse not active */
+         MSE_INT_ON();
+
+       } else if (mse_busmouse_type == MICROSOFT_BUSMOUSE) {
+
+         if (request_irq(MOUSE_IRQ, ms_mouse_interrupt)) {
+           /* once we get to here mouse is unused, IRQ is busy */
+           mouse.active = 0;  /* it's not active, fix it */
+           return -EBUSY;     /* IRQ is busy, so we're BUSY */
+         } /* if we can't get the IRQ and mouse not active */
+         outb(MS_MSE_START, MS_MSE_CONTROL_PORT);
+         MS_MSE_INT_ON();      
+
+       }
+
        return 0;
 }
 
+
 static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count)
 {
        return -EINVAL;
@@ -108,8 +174,10 @@ static int read_mouse(struct inode * inode, struct file * file, char * buffer, i
 
        if (count < 3) return -EINVAL;
        if (!mouse.ready) return -EAGAIN;
-       
-       MSE_INT_OFF();
+
+       if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+         MSE_INT_OFF();
+       }
                
        put_fs_byte(mouse.latch_buttons | 0x80, buffer);
        
@@ -131,7 +199,10 @@ static int read_mouse(struct inode * inode, struct file * file, char * buffer, i
        mouse.latch_buttons = mouse.buttons;
        mouse.ready = 0;
        
-       MSE_INT_ON();
+       if (mse_busmouse_type == LOGITECH_BUSMOUSE) {
+         MSE_INT_ON();
+       }
+
        return i;       
 }
 
@@ -165,7 +236,7 @@ long bus_mouse_init(long kmem_start)
        
        for (i = 0; i < 100000; i++); /* busy loop */
        if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
-               printk("No bus mouse detected.\n");
+               printk("No Logitech bus mouse detected.\n");
                mouse.present = 0;
                return kmem_start;
        }
@@ -179,6 +250,19 @@ long bus_mouse_init(long kmem_start)
        mouse.buttons = mouse.latch_buttons = 0x80;
        mouse.dx = 0;
        mouse.dy = 0;
-       printk("Bus mouse detected and installed.\n");
+       printk("Logitech Bus mouse detected and installed.\n");
+       return kmem_start;
+}
+
+long ms_bus_mouse_init(long kmem_start)
+{      
+       
+       MS_MSE_INT_OFF();
+       
+       mouse.present = 1;
+       mouse.active = mouse.ready = 0;
+       mouse.buttons = mouse.latch_buttons = 0x80;
+       mouse.dx = mouse.dy = 0;
+       printk("Microsoft Bus mouse detected and installed.\n");
        return kmem_start;
 }
index 4880d35df967e55b408a78589441542dade69ccd..a2845971e8716c6accef4dc691f0698a046f8f80 100644 (file)
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include <linux/kd.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/segment.h>
 
-#include <sys/kd.h>
 #include "vt_kern.h"
 
 #define NPAR 16
@@ -187,6 +187,13 @@ static int console_blanked = 0;
 #define kbdleds                (vt_cons[currcons].vc_kbdleds)
 #define vtmode         (vt_cons[currcons].vt_mode)
 
+#if defined KBD_NUMERIC_LOCK
+#define NUMLED_DEFAULT 0x02
+
+#else
+#define NUMLED_DEFAULT 0
+#endif
+
 #define SET(mode,fg,v) \
        (mode) = (v); \
        if (currcons == fg_console) \
@@ -866,7 +873,7 @@ static void reset_terminal(int currcons, int do_clear)
                ckmode          = 0;
                kapplic         = 0;
                lfnlmode        = 0;
-               kleds           = 2;
+               kleds           = NUMLED_DEFAULT;
                kmode           = 0;
                set_leds();
        } else {
@@ -874,7 +881,7 @@ static void reset_terminal(int currcons, int do_clear)
                decckm          = 0;
                kbdapplic       = 0;
                lnm             = 0;
-               kbdleds         = 2;
+               kbdleds         = NUMLED_DEFAULT;
                kbdmode         = 0;
        }
 
index 8e4e52130ce345f693a3b3728eb6e89cd696080f..acc88b70d49c45b596d1aee64ac78f264b8db672 100644 (file)
 #define NUMLED   0x02
 #define CAPSLED  0x04
 
+#if defined KBD_NUMERIC_LOCK
+#define NUMLED_DEFAULT NUMLED
+
+#else
+#define NUMLED_DEFAULT 0
+#endif
+
 #define NO_META_BIT 0x80
 
 unsigned char kapplic = 0;
 unsigned char ckmode = 0;
 unsigned char krepeat = 1;
 unsigned char kmode = 0;
-unsigned char kleds = NUMLED;
+unsigned char kleds = NUMLED_DEFAULT;
 unsigned char ke0 = 0;
 unsigned char kraw = 0;
 unsigned char kbd_flags = KBDFLAGS;
@@ -48,7 +55,7 @@ extern struct tty_queue *table_list[];
 
 typedef void (*fptr)(int);
 
-static unsigned char old_leds = 2;
+static unsigned char old_leds = NUMLED;
 static int diacr = -1;
 static int npadch = 0;
 fptr key_table[];
index 319af3733b5f054639f9854ac1bfa054bf942184..6b4ae4fb6f10b3c86538a3ee51b1828de67a7ffb 100644 (file)
@@ -4,6 +4,11 @@
  * Generic mouse open routine by Johan Myreen
  *
  * Based on code from Linus
+ *
+ * Teemu Rantanen's Microsoft Busmouse support and Derrick Cole's
+ *   changes incorporated into 0.97pl4
+ *   by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+ *   See busmouse.c for particulars.
  */
 
 #include <linux/fs.h>
@@ -14,6 +19,9 @@ extern struct file_operations bus_mouse_fops;
 extern struct file_operations psaux_fops;
 extern long bus_mouse_init(long);
 extern long psaux_init(long);
+extern long ms_bus_mouse_init(long);
+
+int mse_busmouse_type;
 
 static int mouse_open(struct inode * inode, struct file * file)
 {
@@ -21,8 +29,11 @@ static int mouse_open(struct inode * inode, struct file * file)
                 file->f_op = &bus_mouse_fops;
         else if (MINOR(inode->i_rdev) == PSMOUSE_MINOR)
                 file->f_op = &psaux_fops;
+       else if (MINOR(inode->i_rdev) == MS_BUSMOUSE_MINOR)
+               file->f_op = &bus_mouse_fops;
         else
                 return -ENODEV;
+       mse_busmouse_type = (int) MINOR(inode->i_rdev);
         return file->f_op->open(inode,file);
 }
 
@@ -41,6 +52,8 @@ long mouse_init(long kmem_start)
 {
        kmem_start = bus_mouse_init(kmem_start);
        kmem_start = psaux_init(kmem_start);
+       kmem_start = ms_bus_mouse_init(kmem_start);
+       mse_busmouse_type = -1;
        chrdev_fops[10] = &mouse_fops;
        return kmem_start;
 }
index 13e15b8b34eb4979aa1906e5e809ca43cccc4323..737669c6dba22ab1b0a6f5c087bb554714c3a0a7 100644 (file)
@@ -444,6 +444,54 @@ int set_serial_info(unsigned int line, struct serial_struct * info)
        return 0;
 }
 
+int get_modem_info(unsigned int line, unsigned int *value)
+{
+       unsigned port = (serial_table + line)->port;
+       unsigned char control = inb(port+4);
+       unsigned char status = inb(port+6);
+       unsigned int result;
+
+       result =  ((control & 0x02) ? TIOCM_RTS : 0)
+               | ((control & 0x01) ? TIOCM_DTR : 0)
+               | ((status  & 0x80) ? TIOCM_CAR : 0)
+               | ((status  & 0x40) ? TIOCM_RNG : 0)
+               | ((status  & 0x20) ? TIOCM_DSR : 0)
+               | ((status  & 0x10) ? TIOCM_CTS : 0);
+       put_fs_long(result,(unsigned long *) value);
+       return 0;
+}
+
+int set_modem_info(unsigned int line, unsigned int cmd, unsigned int *value)
+{
+       unsigned port = (serial_table + line)->port;
+       unsigned char control = inb(port+4);
+       unsigned int arg = get_fs_long((unsigned long *) value);
+       
+       switch (cmd) {
+               case TIOCMBIS:
+                       if (arg & TIOCM_RTS)
+                               control |= 0x02;
+                       if (arg & TIOCM_DTR)
+                               control |= 0x01;
+                       break;
+               case TIOCMBIC:
+                       if (arg & TIOCM_RTS)
+                               control &= ~0x02;
+                       if (arg & TIOCM_DTR)
+                               control &= ~0x01;
+                       break;
+               case TIOCMSET:
+                       control = (control & ~0x03)
+                               | ((arg & TIOCM_RTS) ? 0x02 : 0)
+                               | ((arg & TIOCM_DTR) ? 0x01 : 0);
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       outb(port,control);
+       return 0;
+}
+
 long rs_init(long kmem_start)
 {
        int i;
index e5bce7230037abf1ab1cf8c4993fb114323e7868..2deb8508cb6abcb335aa6970cfe76022b49a441b 100644 (file)
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/ctype.h>
+#include <linux/kd.h>
 
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 
-#include <sys/kd.h>
 #include "vt_kern.h"
 
 #define QUEUES (3*(NR_CONSOLES+NR_SERIALS+2*NR_PTYS))
index 5212b50f1c5849c70c902723525957ffed0ad794..b92dcb4b073b6219073bd91dd0356e25ac95b0d6 100644 (file)
@@ -375,13 +375,16 @@ int tty_ioctl(struct inode * inode, struct file * file,
                                set_window_size(other_tty,(struct winsize *) arg);
                        return set_window_size(tty,(struct winsize *) arg);
                case TIOCMGET:
-                       return -EINVAL; /* not implemented */
+                       if (!IS_A_SERIAL(dev))
+                               return -EINVAL;
+                       verify_area((void *) arg,sizeof(unsigned int *));
+                       return get_modem_info(dev-64,(unsigned int *) arg);
                case TIOCMBIS:
-                       return -EINVAL; /* not implemented */
                case TIOCMBIC:
-                       return -EINVAL; /* not implemented */
                case TIOCMSET:
-                       return -EINVAL; /* not implemented */
+                       if (!IS_A_SERIAL(dev))
+                               return -EINVAL;
+                       return set_modem_info(dev-64,cmd,(unsigned int *) arg);
                case TIOCGSOFTCAR:
                        return -EINVAL; /* not implemented */
                case TIOCSSOFTCAR:
index 580e6b5c6293e946295cb4b21b5fec756cb37e6c..81702d66a8b48f264b9ce441b87a1843d6d8c300 100644 (file)
 #include <linux/tty.h>
 #include <linux/timer.h>
 #include <linux/kernel.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
 
 #include <asm/io.h>
 #include <asm/segment.h>
 
 #include "vt_kern.h"
-#include <sys/kd.h>
-#include <sys/vt.h>
 
 /*
  * console (vt and kd) routines, as defined by usl svr4 manual
index 5de9c67b00501dea91a0c3b8bf5f2f9aeb2b1cbc..26abae25838744063df86789285756a228805e78 100644 (file)
@@ -4,7 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <time.h>
+#include <linux/mktime.h>
 
 /*
  * This isn't the library routine, it is only used in the kernel.
@@ -38,21 +38,21 @@ static int month[12] = {
        DAY*(31+29+31+30+31+30+31+31+30+31+30)
 };
 
-long kernel_mktime(struct tm * tm)
+long kernel_mktime(struct mktime * time)
 {
        long res;
        int year;
 
-       year = tm->tm_year - 70;
+       year = time->year - 70;
 /* magic offsets (y+1) needed to get leapyears right.*/
        res = YEAR*year + DAY*((year+1)/4);
-       res += month[tm->tm_mon];
+       res += month[time->mon];
 /* and (y+2) here. If it wasn't a leap-year, we have to adjust */
-       if (tm->tm_mon>1 && ((year+2)%4))
+       if (time->mon>1 && ((year+2)%4))
                res -= DAY;
-       res += DAY*(tm->tm_mday-1);
-       res += HOUR*tm->tm_hour;
-       res += MINUTE*tm->tm_min;
-       res += tm->tm_sec;
+       res += DAY*(time->day-1);
+       res += HOUR*time->hour;
+       res += MINUTE*time->min;
+       res += time->sec;
        return res;
 }
index ced53029d46ab243cce1aa7c5838f55b3923f841..0df6ff205cdc8135c8c91cebc1f9b338f8bb574e 100644 (file)
@@ -139,12 +139,33 @@ unsigned long save_v86_state(int signr,struct vm86_regs * regs)
                do_exit(SIGSEGV);
        }
        memcpy_tofs(&(current->vm86_info->regs),regs,sizeof(*regs));
+       put_fs_long(current->screen_bitmap,&(current->vm86_info->screen_bitmap));
        stack = current->tss.esp0;
        current->tss.esp0 = current->saved_kernel_stack;
        current->saved_kernel_stack = 0;
        return stack;
 }
 
+static void mark_screen_rdonly(struct task_struct * tsk)
+{
+       unsigned long tmp;
+       unsigned long *pg_table;
+
+       if (tmp = tsk->tss.cr3) {
+               tmp = *(unsigned long *) tmp;
+               if (tmp & PAGE_PRESENT) {
+                       tmp &= 0xfffff000;
+                       pg_table = (0xA00000 >> PAGE_SHIFT) + (unsigned long *) tmp;
+                       tmp = 32;
+                       while (tmp--) {
+                               if (PAGE_PRESENT & *pg_table)
+                                       *pg_table &= ~PAGE_RW;
+                               pg_table++;
+                       }
+               }
+       }
+}
+
 int sys_vm86(struct vm86_struct * v86)
 {
        struct vm86_struct info;
@@ -171,6 +192,9 @@ int sys_vm86(struct vm86_struct * v86)
        current->saved_kernel_stack = current->tss.esp0;
        current->tss.esp0 = (unsigned long) pt_regs;
        current->vm86_info = v86;
+       current->screen_bitmap = info.screen_bitmap;
+       if (info.flags & VM86_SCREEN_BITMAP)
+               mark_screen_rdonly(current);
        __asm__ __volatile__("movl %0,%%esp\n\t"
                "pushl $ret_from_sys_call\n\t"
                "ret"::"g" ((long) &(info.regs)),"a" (info.regs.eax));
index 916455ef628a3b1edc5d0d7238a24bf82ae70b37..6de8470a077a6f31041983286a46dcdb76a318d4 100644 (file)
@@ -126,17 +126,17 @@ _system_call:
        movl %eax,EAX(%esp)             # save the return value
        .align 4,0x90
 ret_from_sys_call:
-       movl EFLAGS(%esp),%eax
-       testl $VM_MASK,%eax
-       jne 1f
+       movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
+       testl $VM_MASK,%eax             # different then
+       jne 4f
        cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
        jne 2f
        cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
        jne 2f
-1:     orl $IF_MASK,%eax               # these just try to make sure
+4:     orl $IF_MASK,%eax               # these just try to make sure
        andl $~NT_MASK,%eax             # the program doesn't do anything
        movl %eax,EFLAGS(%esp)          # stupid
-       cmpl $0,_need_resched
+1:     cmpl $0,_need_resched
        jne reschedule
        movl _current,%eax
        cmpl _task,%eax                 # task[0] cannot have signals
index 3501d8a41f354b87f7588042d345c6f62c1a978f..7f4a62e19884e4c691d18dae261b4d8ae68a428c 100644 (file)
@@ -50,6 +50,9 @@
    big buffers around for itself.)  I guess I'll have return from
    syscall fill up the free page descriptors. -RAB */
 
+/* since the advent of GFP_ATOMIC, I've changed the malloc code to
+   use it and return NULL if it can't get a page. -RAB */
+
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <asm/system.h>
@@ -91,84 +94,6 @@ struct _bucket_dir bucket_dir[] = {
        { 4096, (struct bucket_desc *) 0},
        { 0,    (struct bucket_desc *) 0}};   /* End of list marker */
 
-/* Where to keep the extra pages, and how many. */
-#define FREE_PAGES 20
-static volatile unsigned long free_pages[FREE_PAGES]={0,};
-volatile short free_page_ptr=0; /* this -1 is next free page. */
-
-/* malloc_free_page makes sure that we have all the free pages we
-   want around before actually freeing the page. */
-
-/* called with interrupts off. */
-void
-malloc_free_page (unsigned long addr)
-{
-   if (free_page_ptr < FREE_PAGES)
-     free_pages[free_page_ptr++] = addr;
-   else
-     free_page (addr);
-}
-
-/* Fill up the extra page buffer. Should be called quite often to make
-   sure we have some floating around. */
-
-void
-malloc_grab_pages(void)
-{
-   while (free_page_ptr < FREE_PAGES)
-     {
-       unsigned long page;
-
-       page = get_free_page (GFP_KERNEL);
-       if (page == 0)
-         {
-            printk ("malloc_grab_pages: Can't happen. no memory.\n");
-            continue;
-         }
-       /* see if we still need the page. This can only happen if
-           we get interrupted while we are trying to get some pages,
-           and we are out of pages.  It shouldn't happen, but it
-           could and we had better check for it. */
-       cli();
-       if (free_page_ptr < FREE_PAGES)
-         {
-            free_pages[free_page_ptr] = page;
-            free_page_ptr++;
-         }
-       else
-         {
-            free_page(page);
-         }
-       sti();
-     }
-}
-
-/* called with interrupts off. */
-static inline unsigned long
-malloc_get_free_page (void)
-{
-   unsigned long page;
-   int page_ptr;
-
-   if (free_page_ptr > 0)
-     {
-       page_ptr = --free_page_ptr;
-       page = free_pages[page_ptr];
-       free_pages[page_ptr] = 0;
-       return (page);
-     }
-
-   printk ("malloc_get_free_page: Calling malloc_grab_pages\n");
-   /* this routine turns on interrupts.  Maybe we should do a pushflags
-      pop flags around it. */
-   malloc_grab_pages();
-   cli();
-   page_ptr = --free_page_ptr;
-   page = free_pages[page_ptr];
-   free_pages[page_ptr] = 0;
-   return (page);
-}
-
 /*
  * This contains a linked list of free bucket descriptor blocks
  */
@@ -177,24 +102,26 @@ static struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0;
 /*
  * This routine initializes a bucket description page.
  */
-static inline void init_bucket_desc()
+static inline int init_bucket_desc()
 {
        struct bucket_desc *bdesc, *first;
-       int     i;
+       int i;
        /* this turns interrupt on, so we should be carefull. */
-       first = bdesc = (struct bucket_desc *) malloc_get_free_page();
+       first = bdesc = (struct bucket_desc *) get_free_page(GFP_ATOMIC);
        if (!bdesc)
-               panic("Out of memory in init_bucket_desc()");
+               return 1;
        for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {
                bdesc->next = bdesc+1;
                bdesc++;
        }
        /*
-        * This is done last, to avoid race conditions in case 
+        * This is done last, to avoid race conditions in case
         * get_free_page() sleeps and this routine gets called again....
         */
+       /* Get free page will not sleep because of the GFP_ATOMIC */
        bdesc->next = free_bucket_desc;
        free_bucket_desc = first;
+       return (0);
 }
 
 void *malloc(unsigned int len)
@@ -210,36 +137,41 @@ void *malloc(unsigned int len)
        for (bdir = bucket_dir; bdir->size; bdir++)
                if (bdir->size >= len)
                        break;
+
        if (!bdir->size) {
-               printk("malloc called with impossibly large argument (%d)\n",
-                       len);
-               panic("malloc: bad arg");
+               printk("malloc called with impossibly large argument (%d)\n", len);
+               return NULL;
        }
        /*
         * Now we search for a bucket descriptor which has free space
         */
        cli();  /* Avoid race conditions */
-       for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) 
+       for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
                if (bdesc->freeptr)
                        break;
        /*
-        * If we didn't find a bucket with free space, then we'll 
+        * If we didn't find a bucket with free space, then we'll
         * allocate a new one.
         */
        if (!bdesc) {
-               char            *cp;
-               int             i;
-
-               if (!free_bucket_desc)  
-                       init_bucket_desc();
+               char *cp;
+               int i;
+
+               if (!free_bucket_desc)
+                       if (init_bucket_desc()) {
+                               sti();
+                               return NULL;
+                       }
                bdesc = free_bucket_desc;
                free_bucket_desc = bdesc->next;
                bdesc->refcnt = 0;
                bdesc->bucket_size = bdir->size;
                bdesc->page = bdesc->freeptr =
-                 (void *) cp = malloc_get_free_page();
-               if (!cp)
-                       panic("Out of memory in kernel malloc()");
+                 (void *) cp = get_free_page(GFP_ATOMIC);
+               if (!cp) {
+                       sti();
+                       return NULL;
+               }
                /* Set up the chain of free objects */
                for (i=PAGE_SIZE/bdir->size; i > 1; i--) {
                        *((char **) cp) = cp + bdir->size;
@@ -253,14 +185,14 @@ void *malloc(unsigned int len)
        bdesc->freeptr = *((void **) retval);
        bdesc->refcnt++;
        sti();  /* OK, we're safe again */
-       return(retval);
+       return retval;
 }
 
 /*
  * Here is the free routine.  If you know the size of the object that you
  * are freeing, then free_s() will use that information to speed up the
  * search for the bucket descriptor.
- * 
+ *
  * We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"
  */
 void free_s(void *obj, int size)
@@ -278,7 +210,7 @@ void free_s(void *obj, int size)
                if (bdir->size < size)
                        continue;
                for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) {
-                       if (bdesc->page == page) 
+                       if (bdesc->page == page)
                                goto found;
                        prev = bdesc;
                }
@@ -307,11 +239,10 @@ found:
                                panic("malloc bucket chains corrupted");
                        bdir->chain = bdesc->next;
                }
-               malloc_free_page((unsigned long) bdesc->page);
+               free_page((unsigned long) bdesc->page);
                bdesc->next = free_bucket_desc;
                free_bucket_desc = bdesc;
        }
        sti();
        return;
 }
-
index 8551505ffa68b5b4daf15b7794d10ed974ffa929..fc2ad1c868ad7065602e11c7d2e2e0ed81a71d5b 100644 (file)
@@ -350,7 +350,7 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
                         * when the page is referenced. current assumptions
                         * cause it to be treated as demand allocation.
                         */
-                       if (mask == 4 || to >= high_memory)
+                       if (mask == 4 || to >= high_memory || !mem_map[MAP_NR(to)])
                                *page_table++ = 0;      /* not present */
                        else {
                                ++current->rss;
@@ -788,14 +788,19 @@ void show_mem(void)
 void do_page_fault(unsigned long *esp, unsigned long error_code)
 {
        unsigned long address;
-       unsigned long user_esp;
+       unsigned long user_esp = 0;
 
-       if ((0xffff & esp[1]) == 0xf)
-               user_esp = esp[3];
-       else
-               user_esp = 0;
        /* get the address */
        __asm__("movl %%cr2,%0":"=r" (address));
+       if (esp[2] & VM_MASK) {
+               unsigned int bit;
+
+               bit = (address - 0xA0000) >> PAGE_SHIFT;
+               if (bit < 32)
+                       current->screen_bitmap |= 1 << bit;
+       } else
+               if ((0xffff & esp[1]) == 0xf)
+                       user_esp = esp[3];
        if (!(error_code & 1))
                do_no_page(error_code, address, current, user_esp);
        else
index bee90196950931e76128d244547cedc1047b254f..550d747ddfebad2e87621114314092aa93344c47 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -8,12 +8,11 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
+#include <linux/mman.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
 
-#include <sys/mman.h>
-
 /*
  * description of effects of mapping type and prot in current implementation.
  * this is due to the current handling of page faults in memory.c. the expected
index d036b7f03d6cd790741ac36c0004485e0f2d32b5..e0f180986e5c99022e5882367452f5b8cc21c40f 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -247,7 +247,7 @@ static int try_to_swap_out(unsigned long * table_ptr)
        *table_ptr = 0;
        invalidate();
        free_page(page);
-       return !mem_map[MAP_NR(page)];
+       return 1 + mem_map[MAP_NR(page)];
 }
 
 /*
@@ -316,9 +316,10 @@ check_table:
                swap_table++;
                goto check_dir;
        }
-       if (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
-               p->rss--;
-               return 1;
+       switch (try_to_swap_out(swap_page + (unsigned long *) pg_table)) {
+               case 0: break;
+               case 1: p->rss--; return 1;
+               default: p->rss--;
        }
        swap_page++;
        goto check_table;
@@ -517,6 +518,7 @@ repeat:
                                read_swap_page(page>>1, (char *) tmp);
                                if (*ppage == page) {
                                        *ppage = tmp | (PAGE_DIRTY | 7);
+                                       ++p->rss;
                                        swap_free(page>>1);
                                        tmp = 0;
                                }
index 0122f70316dc95ca2544ded53174a734ec096656..75afc2fea6fb0ef4eb6d1064acf3b20f579f4bd0 100644 (file)
@@ -35,7 +35,7 @@ clean:
 
 dep:
        sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
-       for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+       $(CPP) -M *.c >> tmp_make
        cp tmp_make Makefile
        @for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE) dep) || exit; done