]> git.neil.brown.name Git - history.git/commitdiff
Second patch to 0.96a 0.96a-patch2
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:01 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:01 +0000 (15:09 -0500)
I have just sent off the second patch to 0.96a: it should be on the
normal ftp-sites (nic, tsx-11 and banjo), although the only site which I
can make it directly readable on is banjo, so on the other sites it will
take the site-managers to make the patch available.

Patch 2 implements:

- itimers (by Darren Senn), which are now also used to implement the
  alarm() system call.

- ultrastor scsi driver patches (by gentzel)

- [f]statfs() system call is implemented (so df can be made fs-
  independent). Also some other minor fs-changes for the upcoming new
  filesystem. Patches by Remy Card.

- preliminary core-file dumping code (linux creates a core-file, but
  it's not in the correct format yet [*]).

- minor changes/bugfixes.

While patching in patch1 is a good idea for anybody, patch 2 isn't
really vital. I've made it available just so kernel hackers can keep up
with the kernel I have right now if they wish. Patch 2 is relative to
patch 1: you have to patch that in first.

[*] The current core-file is very simple, and the kernel code is there
just so that some enterprising character can expand it. A core-file
looks like this right now:

offset data
0x0000 "core-dump: regs=\n"
0x0040 struct pt_regs (see <sys/ptrace.c>)
0x0400 "floating-point regs:\n"
0x0440 struct i387 (see <linux/sched.h>)
0x0800 the first 1kB of user-space

Not very practical, but it /might/ help if the X-server dies of a
segmentation fault or similar (you can use pt_regs.eip to see where it
happened). The kernel code is very easy to change to accomodate for the
real core-file format, I just didn't know what it should be.

                Linus

39 files changed:
boot/bootsect.S
fs/exec.c
fs/minix/bitmap.c
fs/minix/blkdev.c
fs/minix/chrdev.c
fs/minix/dir.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/symlink.c
fs/namei.c
fs/open.c
fs/pipe.c
include/asm/io.h
include/linux/fs.h
include/linux/minix_fs.h
include/linux/sched.h
include/linux/sys.h
include/linux/unistd.h
include/signal.h
include/sys/time.h
kernel/Makefile
kernel/blk_drv/blk.h
kernel/blk_drv/floppy.c
kernel/blk_drv/hd.c
kernel/blk_drv/ll_rw_blk.c
kernel/blk_drv/scsi/ultrastor.c
kernel/blk_drv/scsi/ultrastor.h
kernel/chr_drv/console.c
kernel/chr_drv/keyboard.c
kernel/chr_drv/tty_io.c
kernel/fork.c
kernel/itimer.c [new file with mode: 0644]
kernel/math/ea.c
kernel/sched.c
kernel/signal.c
kernel/sys.c
kernel/sys_call.S
lib/Makefile
tools/build.c

index 837be3219e07c1ba4e16c7a73d01573fb4a5d5a1..22ebdea74a8e0c7d60071777e4bb61c0e5e000c6 100644 (file)
@@ -224,8 +224,7 @@ got_sectors:
        mov     ax,#0x021c              ! /dev/PS0 - 1.44Mb
        cmp     bx,#18
        je      root_defined
-undef_root:
-       jmp undef_root
+       mov     ax,#0x0200              ! /dev/fd0 - autodetect
 root_defined:
        seg cs
        mov     root_dev,ax
index 48d727f4bb1c439094e35c631d9d052fde05180a..48cc8edb9d1d0941911202897a6deaaa9da1d838 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -21,7 +21,9 @@
 #include <errno.h>
 #include <linux/string.h>
 #include <sys/stat.h>
+#include <sys/ptrace.h>
 #include <a.out.h>
+#include <fcntl.h>
 
 #include <linux/fs.h>
 #include <linux/sched.h>
@@ -39,6 +41,86 @@ extern int sys_close(int fd);
  */
 #define MAX_ARG_PAGES 32
 
+/*
+ * These are the only things you should do on a core-file: use only these
+ * macros to write out all the necessary info.
+ */
+#define DUMP_WRITE(addr,nr) \
+while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
+
+#define DUMP_SEEK(offset) \
+if (file.f_op->lseek) { \
+       if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
+               goto close_coredump; \
+} else file.f_pos = (offset)           
+
+/*
+ * Routine writes a core dump image in the current directory.
+ * Currently only a stub-function.
+ *
+ * Note that setuid/setgid files won't make a core-dump if the uid/gid
+ * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
+ * field, which also makes sure the core-dumps won't be recursive if the
+ * dumping of the process results in another error..
+ */
+int core_dump(long signr, struct pt_regs * regs)
+{
+       struct inode * inode = NULL;
+       struct file file;
+       unsigned short fs;
+       int has_dumped = 0;
+
+       if (!current->dumpable)
+               return 0;
+       current->dumpable = 0;
+       __asm__("mov %%fs,%0":"=r" (fs));
+       __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+       if (open_namei("core",O_CREAT | O_WRONLY | O_TRUNC,0600,&inode))
+               goto end_coredump;
+       if (!S_ISREG(inode->i_mode))
+               goto end_coredump;
+       if (!inode->i_op || !inode->i_op->default_file_ops)
+               goto end_coredump;
+       file.f_mode = 3;
+       file.f_flags = 0;
+       file.f_count = 1;
+       file.f_inode = inode;
+       file.f_pos = 0;
+       file.f_reada = 0;
+       file.f_op = inode->i_op->default_file_ops;
+       if (file.f_op->open)
+               if (file.f_op->open(inode,&file))
+                       goto end_coredump;
+       if (!file.f_op->write)
+               goto close_coredump;
+       has_dumped = 1;
+/* write and seek example: from kernel space */
+       __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+       DUMP_WRITE("core-dump, regs=\n",17);
+       DUMP_SEEK(64);
+       DUMP_WRITE(regs,sizeof(*regs));
+       if (current->used_math) {
+               if (last_task_used_math == current)
+                       __asm__("clts ; fnsave %0"::"m" (current->tss.i387));
+               DUMP_SEEK(1024);
+               DUMP_WRITE("floating-point regs=\n",21);
+               DUMP_SEEK(1088);
+               DUMP_WRITE(&current->tss.i387,sizeof(current->tss.i387));
+       }
+/* now we start writing out the user space info */
+       __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x17));
+/* the dummy dump-file contains the first block of user space... */
+       DUMP_SEEK(2048);
+       DUMP_WRITE(0,1024);
+close_coredump:
+       if (file.f_op->release)
+               file.f_op->release(inode,&file);
+end_coredump:
+       __asm__("mov %0,%%fs"::"r" (fs));
+       iput(inode);
+       return has_dumped;
+}
+
 /*
  * Note that a shared library must be both readable and executable due to
  * security reasons.
@@ -406,6 +488,7 @@ restart_interp:
                }
        }
 /* OK, This is the point of no return */
+       current->dumpable = 1;
        for (i=0; (ch = get_fs_byte(filename++)) != '\0';)
                if (ch == '/')
                        i = 0;
@@ -421,6 +504,9 @@ restart_interp:
                iput(current->libraries[i].library);
                current->libraries[i].library = NULL;
        }
+       if (e_uid != current->euid || e_gid != current->egid ||
+           !permission(inode,MAY_READ))
+               current->dumpable = 0;
        current->numlibraries = 0;
        current->executable = inode;
        current->signal = 0;
@@ -454,7 +540,7 @@ restart_interp:
        eip[0] = ex.a_entry;            /* eip, magic happens :-) */
        eip[3] = p;                     /* stack pointer */
        if (current->flags & PF_PTRACED)
-         send_sig(SIGTRAP, current, 0);
+               send_sig(SIGTRAP, current, 0);
        return 0;
 exec_error2:
        iput(inode);
index a7fd3c32619ab26641dcbb742552ff04f7eb1852..fe185a704909ac3c0f00c20922bb30f4f2ffc6c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/bitmap.c
+ *  linux/fs/minix/bitmap.c
  *
  *  (C) 1991  Linus Torvalds
  */
@@ -44,6 +44,35 @@ __asm__("cld\n" \
        :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
 __res;})
 
+static int nibblemap[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
+
+static unsigned long count_used(struct buffer_head *map[], unsigned numblocks,
+       unsigned numbits)
+{
+       unsigned i, j, end, sum = 0;
+       struct buffer_head *bh;
+  
+       for (i=0; (i<numblocks) && numbits; i++) {
+               if (!(bh=map[i])) 
+                       return(0);
+               if (numbits >= (8*BLOCK_SIZE)) { 
+                       end = BLOCK_SIZE;
+                       numbits -= 8*BLOCK_SIZE;
+               } else {
+                       int tmp;
+                       end = numbits >> 3;
+                       numbits &= 0x7;
+                       tmp = bh->b_data[end] & ((1<<numbits)-1);
+                       sum += nibblemap[tmp&0xf] + nibblemap[(tmp>>4)&0xf];
+                       numbits = 0;
+               }  
+               for (j=0; j<end; j++)
+                       sum += nibblemap[bh->b_data[j] & 0xf] 
+                               + nibblemap[(bh->b_data[j]>>4)&0xf];
+       }
+       return(sum);
+}
+
 int minix_free_block(int dev, int block)
 {
        struct super_block * sb;
@@ -107,6 +136,12 @@ int minix_new_block(int dev)
        return j;
 }
 
+unsigned long minix_count_free_blocks(struct super_block *sb)
+{
+       return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones))
+                << sb->s_log_zone_size;
+}
+
 void minix_free_inode(struct inode * inode)
 {
        struct buffer_head * bh;
@@ -182,3 +217,8 @@ struct inode * minix_new_inode(int dev)
        inode->i_op = NULL;
        return inode;
 }
+
+unsigned long minix_count_free_inodes(struct super_block *sb)
+{
+       return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes);
+}
index fec1bc9533f8938c25ef551f424bdcc67108e3b5..a70b513c769dc317c9040f728495b0f03872ce24 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/chrdev.c
+ *  linux/fs/minix/blkdev.c
  *
  *  (C) 1991  Linus Torvalds
  */
@@ -19,7 +19,6 @@ static int blkdev_open(struct inode * inode, struct file * filp)
 {
        int i;
 
-       check_disk_change(inode->i_rdev);
        i = MAJOR(inode->i_rdev);
        if (i < MAX_BLKDEV) {
                filp->f_op = blkdev_fops[i];
index 489849f11eab39587da019201bc4e31f24ab2f67..8957eb4ad1d19077f464a8536e5dc2c43c4ceed2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  linux/fs/chrdev.c
+ *  linux/fs/minix/chrdev.c
  *
  *  (C) 1991  Linus Torvalds
  */
index d09585ae72209dbccada8f4a696afc42a8227aa9..467d227cd11192bd98bc3f83db68a83c9f22abd8 100644 (file)
@@ -1,7 +1,9 @@
 /*
- * linux/fs/minix/dir.c
+ *  linux/fs/minix/dir.c
  *
- * minix directory hadnling functions
+ *  (C) 1991 Linus Torvalds
+ *
+ *  minix directory handling functions
  */
 
 #include <errno.h>
index 9ebeebb178c0db30c2685b367435e58e9ea09007..7b6e033c58e92d3f8bd9225c8aeaee3943241524 100644 (file)
@@ -1,7 +1,9 @@
 /*
- * linux/fs/minix/file.c
+ *  linux/fs/minix/file.c
  *
- * minix regular file handling primitives
+ *  (C) 1991 Linus Torvalds
+ *
+ *  minix regular file handling primitives
  */
 
 #include <errno.h>
@@ -212,10 +214,8 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
                brelse(bh);
        }
        inode->i_mtime = CURRENT_TIME;
-       if (!(filp->f_flags & O_APPEND)) {
-               filp->f_pos = pos;
-               inode->i_ctime = CURRENT_TIME;
-       }
+       inode->i_ctime = CURRENT_TIME;
+       filp->f_pos = pos;
        inode->i_dirt = 1;
        return written;
 }
index 4ddf5c2472049f49dc453d03fdb3920b8d5e068b..df68ec59b5c1837f37ddca7c2006e9e40125082b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <asm/system.h>
+#include <asm/segment.h>
 
 int sync_dev(int dev);
 
@@ -40,12 +41,14 @@ static struct super_operations minix_sops = {
        minix_read_inode,
        minix_write_inode,
        minix_put_inode,
-       minix_put_super
+       minix_put_super,
+       minix_statfs
 };
 
 struct super_block *minix_read_super(struct super_block *s,void *data)
 {
        struct buffer_head *bh;
+       struct minix_super_block *ms;
        int i,dev=s->s_dev,block;
 
        lock_super(s);
@@ -55,8 +58,17 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
                printk("bread failed\n");
                return NULL;
        }
-       *((struct minix_super_block *) s) =
-               *((struct minix_super_block *) bh->b_data);
+/*     *((struct minix_super_block *) s) =
+               *((struct minix_super_block *) bh->b_data); */
+       ms = (struct minix_super_block *) bh->b_data;
+       s->s_ninodes = ms->s_ninodes;
+       s->s_nzones = ms->s_nzones;
+       s->s_imap_blocks = ms->s_imap_blocks;
+       s->s_zmap_blocks = ms->s_zmap_blocks;
+       s->s_firstdatazone = ms->s_firstdatazone;
+       s->s_log_zone_size = ms->s_log_zone_size;
+       s->s_max_size = ms->s_max_size;
+       s->s_magic = ms->s_magic;
        brelse(bh);
        if (s->s_magic != MINIX_SUPER_MAGIC) {
                s->s_dev = 0;
@@ -103,6 +115,21 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
        return s;
 }
 
+void minix_statfs (struct super_block *sb, struct statfs *buf)
+{
+       long tmp;
+
+       put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
+       put_fs_long(1024, &buf->f_bsize);
+       put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks);
+       tmp = minix_count_free_blocks(sb);
+       put_fs_long(tmp, &buf->f_bfree);
+       put_fs_long(tmp, &buf->f_bavail);
+       put_fs_long(sb->s_ninodes, &buf->f_files);
+       put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
+       /* Don't know what value to put in buf->f_fsid */
+}
+
 static int _minix_bmap(struct inode * inode,int block,int create)
 {
        struct buffer_head * bh;
index 70fbeb02415b3e1b17f60315c0f2d9405abc156d..0b5c5dc5b5eb5f6db4cdb9eb91aa43528762cbd6 100644 (file)
@@ -1,7 +1,9 @@
 /*
- * linux/fs/minix/symlink.c
+ *  linux/fs/minix/symlink.c
  *
- * minix symlink handling code
+ *  (C) 1991 Linus Torvalds
+ *
+ *  minix symlink handling code
  */
 
 #include <errno.h>
index c4f4acca3e1482d4c790c065f007d3095ffbb317..0a59da81dde9244324f336ca56d96ec858dd612e 100644 (file)
@@ -201,7 +201,7 @@ int open_namei(const char * pathname, int flag, int mode,
 
        if ((flag & O_TRUNC) && !(flag & O_ACCMODE))
                flag |= O_WRONLY;
-       mode &= 0777 & ~current->umask;
+       mode &= 07777 & ~current->umask;
        mode |= I_REGULAR;
        if (!(dir = dir_namei(pathname,&namelen,&basename,NULL)))
                return -ENOENT;
index 3e47592ce1777498dd1ea779b6cd4ca4d129daf1..33e395703b3a10679672e0dde28efe442f8a6254 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -33,14 +33,34 @@ int sys_ustat(int dev, struct ustat * ubuf)
 
 int sys_statfs(const char * path, struct statfs * buf)
 {
-       printk("statfs not implemented\n");
-       return -ENOSYS;
+       struct inode * inode;
+
+       verify_area(buf, sizeof(struct statfs));
+       if (!(inode = namei(path)))
+               return -ENOENT;
+       if (!inode->i_sb->s_op->statfs) {
+               iput(inode);
+               return -ENOSYS;
+       }
+       inode->i_sb->s_op->statfs(inode->i_sb, buf);
+       iput(inode);
+       return 0;
 }
 
 int sys_fstatfs(unsigned int fd, struct statfs * buf)
 {
-       printk("fstatfs not implemented\n");
-       return -ENOSYS;
+       struct inode * inode;
+       struct file * file;
+
+       verify_area(buf, sizeof(struct statfs));
+       if (fd >= NR_OPEN || !(file = current->filp[fd]))
+               return -EBADF;
+       if (!(inode = file->f_inode))
+               return -ENOENT;
+       if (!inode->i_sb->s_op->statfs)
+               return -ENOSYS;
+       inode->i_sb->s_op->statfs(inode->i_sb, buf);
+       return 0;
 }
 
 int sys_truncate(const char * path, unsigned int length)
@@ -256,13 +276,13 @@ int sys_open(const char * filename,int flag,int mode)
                if (!current->filp[fd])
                        break;
        if (fd>=NR_OPEN)
-               return -EINVAL;
+               return -EMFILE;
        current->close_on_exec &= ~(1<<fd);
        f=0+file_table;
        for (i=0 ; i<NR_FILE ; i++,f++)
                if (!f->f_count) break;
        if (i>=NR_FILE)
-               return -EINVAL;
+               return -ENFILE;
        (current->filp[fd] = f)->f_count++;
        if ((i = open_namei(filename,flag,mode,&inode))<0) {
                current->filp[fd]=NULL;
index 1657ccb529d540143ca7ba22341399a202956e00..fa91c01dd2b4e72c5e4dcd99233affffffb9a494 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -174,6 +174,7 @@ int sys_pipe(unsigned long * fildes)
        }
        f[0]->f_inode = f[1]->f_inode = inode;
        f[0]->f_pos = f[1]->f_pos = 0;
+       f[0]->f_flags = f[1]->f_flags = 0;
        f[0]->f_op = &read_pipe_fops;
        f[0]->f_mode = 1;               /* read */
        f[1]->f_op = &write_pipe_fops;
index af1c72feb6ecae64c08b8aeb16e74fc69366816b..dd7cb44feef5e90c48bd072ce5660e5f8868043b 100644 (file)
@@ -18,9 +18,11 @@ __asm__ volatile ("outb %0,%1"
 extern void inline outb_p(char value, 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));
 }
@@ -37,9 +39,11 @@ extern unsigned char 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));
        return _v;
index c4bcb8420e2c5f49eec11fe687a3dae1d696110c..304b374c345959cd648f2de7e8632bd12cc707e9 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <sys/types.h>
 #include <sys/dirent.h>
+#include <sys/vfs.h>
 
 /* devices are as follows: (same as minix, so we can use the minix
  * file system. These are major numbers.)
@@ -135,12 +136,12 @@ typedef struct select_table_struct {
 } select_table;
 
 struct super_block {
-       unsigned short s_ninodes;
-       unsigned short s_nzones;
-       unsigned short s_imap_blocks;
-       unsigned short s_zmap_blocks;
-       unsigned short s_firstdatazone;
-       unsigned short s_log_zone_size;
+       unsigned long s_ninodes;
+       unsigned long s_nzones;
+       unsigned long s_imap_blocks;
+       unsigned long s_zmap_blocks;
+       unsigned long s_firstdatazone;
+       unsigned long s_log_zone_size;
        unsigned long s_max_size;
        unsigned short s_magic;
 /* These are only in memory */
@@ -191,6 +192,7 @@ struct super_operations {
        void (*write_inode) (struct inode *inode);
        void (*put_inode) (struct inode *inode);
        void (*put_super)(struct super_block *sb);
+       void (*statfs) (struct super_block *sb, struct statfs *buf);
 };
 
 struct file_system_type {
index a51b60c77fc93e3559c0492ef5c45a28af97b638..76f8f518d11d92d95ade69e4e54d0a77d9514d09 100644 (file)
@@ -60,8 +60,10 @@ extern int minix_rename(struct inode * old_dir, const char * old_name, int old_l
        struct inode * new_dir, const char * new_name, int new_len);
 extern struct inode * minix_new_inode(int dev);
 extern void minix_free_inode(struct inode * inode);
+extern unsigned long minix_count_free_inodes(struct super_block *sb);
 extern int minix_new_block(int dev);
 extern int minix_free_block(int dev, int block);
+extern unsigned long minix_count_free_blocks(struct super_block *sb);
 
 extern int minix_create_block(struct inode *, int);
 extern int minix_bmap(struct inode *,int);
@@ -72,6 +74,7 @@ extern struct super_block *minix_read_super(struct super_block *,void *);
 extern void minix_read_inode(struct inode *);
 extern void minix_write_inode(struct inode *);
 extern void minix_put_inode(struct inode *);
+extern void minix_statfs(struct super_block *, struct statfs *);
 
 extern int minix_lseek(struct inode *, struct file *, off_t, int);
 extern int minix_read(struct inode *, struct file *, char *, int);
index b52578dad7d68452217c1061ed168df9c7ac54c5..e301b347c8c62ed603bf565fa7b1a47a8d885af8 100644 (file)
@@ -119,6 +119,7 @@ struct task_struct {
        long blocked;   /* bitmap of masked signals */
 /* various fields */
        int exit_code;
+       int dumpable;
        unsigned long start_code,end_code,end_data,brk,start_stack;
        long pid,pgrp,session,leader;
        int     groups[NGROUPS];
@@ -134,7 +135,9 @@ struct task_struct {
        struct task_struct *next_wait;
        unsigned short uid,euid,suid;
        unsigned short gid,egid,sgid;
-       unsigned long timeout,alarm;
+       unsigned long timeout;
+       unsigned long it_real_value, it_prof_value, it_virt_value;
+       unsigned long it_real_incr, it_prof_incr, it_virt_incr;
        long utime,stime,cutime,cstime,start_time;
        unsigned long min_flt, maj_flt;
        unsigned long cmin_flt, cmaj_flt;
@@ -181,12 +184,12 @@ struct task_struct {
 #define INIT_TASK \
 /* state etc */        { 0,15,15, \
 /* signals */  0,{{},},0, \
-/* ec,brk... */        0,0,0,0,0,0, \
+/* ec,brk... */        0,0,0,0,0,0,0, \
 /* pid etc.. */        0,0,0,0, \
 /* suppl grps*/ {NOGROUP,}, \
 /* proc links*/ &init_task.task,NULL,NULL,NULL,NULL, \
 /* uid etc */  0,0,0,0,0,0, \
-/* timeout */  0,0,0,0,0,0,0, \
+/* timeout */  0,0,0,0,0,0,0,0,0,0,0,0, \
 /* min_flt */  0,0,0,0, \
 /* rlimits */   { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff},  \
                  {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
index d35b1d7d64a4838636c32fe79e72b66c99ed4df2..79640f1c736220ea4e5b5e69e80d6d05e2ed9017 100644 (file)
@@ -106,6 +106,8 @@ extern int sys_fstatfs();
 extern int sys_ioperm();
 extern int sys_socketcall();
 extern int sys_syslog();
+extern int sys_getitimer();
+extern int sys_setitimer();
 
 fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
 sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
@@ -126,7 +128,7 @@ sys_select, sys_symlink, sys_lstat, sys_readlink, sys_uselib,
 sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap,
 sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority,
 sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm,
-sys_socketcall, sys_syslog };
+sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer };
 
 /* So we don't have to do any more manual updating.... */
 int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
index 21e19ba6d854c79bc8354992ffa019dab423e75f..a9e850100f5ae48e0aedeacc448353562a856a83 100644 (file)
 
 extern int errno;
 
+#define __NR_setitimer         104
+#define __NR_getitimer         105
+
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
 type name(void) \
index e4126d339125ca312733e527299adc26bf526773..91df52e020df5f5e68732f48b63e9cd95b94e5b6 100644 (file)
@@ -43,9 +43,10 @@ typedef unsigned int sigset_t;               /* 32 bits */
 #define SIGPOLL                SIGIO
 #define SIGXCPU                24
 #define SIGXFSZ                25
+*/
+
 #define SIGVTALRM      26
 #define SIGPROF                27
-*/
 
 #define SIGWINCH       28
 
index 1165c2632cc7fe6785c327a7984bec0bac878ddf..9d1f7850c46ac24eb3993f8e2c54af134452c9a7 100644 (file)
@@ -54,6 +54,9 @@ struct        itimerval {
        struct  timeval it_value;       /* current value */
 };
 
+int getitimer(int which, struct itimerval *value);
+int setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
+
 #include <time.h>
 #include <sys/types.h>
 
index 716bcfd9d67d23fc9f23bf8e3b1518621b29c3d9..8930f3fcd1420bb222784574041f7422ffa0c92d 100644 (file)
@@ -28,7 +28,7 @@ CPP   =cpp -nostdinc -I../include
 
 OBJS  = sched.o sys_call.o traps.o asm.o fork.o \
        panic.o printk.o vsprintf.o sys.o exit.o \
-       signal.o mktime.o ptrace.o ioport.o
+       signal.o mktime.o ptrace.o ioport.o itimer.o
 
 kernel.o: $(OBJS)
        $(LD) -r -o kernel.o $(OBJS)
index 1bc455cb261fa7a3ab5b42aa9a8bbd029a94b29e..4535f6d36b0fdddd245daf0e92db289622c52e07 100644 (file)
@@ -149,47 +149,40 @@ extern inline void unlock_buffer(struct buffer_head * bh)
        wake_up(&bh->b_wait);
 }
 
-extern inline void end_request(int uptodate)
+static void end_request(int uptodate)
 {
-       struct request * tmp;
-
-       tmp = CURRENT;
-       DEVICE_OFF(tmp->dev);
-       CURRENT = tmp->next;
-       if (tmp->bh) {
-               tmp->bh->b_uptodate = uptodate;
-               unlock_buffer(tmp->bh);
-       }
-       if (!uptodate) {
-               printk(DEVICE_NAME " I/O error\n\r");
-               printk("dev %04x, block %d\n\r",tmp->dev,
-                       tmp->bh->b_blocknr);
-       }
-       wake_up(&tmp->waiting);
-       tmp->dev = -1;
-       wake_up(&wait_for_request);
-}
-
-extern inline void next_buffer(int uptodate)
-{
-       struct buffer_head *tmp;
+       struct request * req;
+       struct buffer_head * bh;
 
-       tmp = CURRENT->bh;
-       CURRENT->bh = tmp->b_reqnext;
-       tmp->b_reqnext = NULL;
-       tmp->b_uptodate = uptodate;
-       unlock_buffer(tmp);
+       req = CURRENT;
+       req->errors = 0;
        if (!uptodate) {
                printk(DEVICE_NAME " I/O error\n\r");
-               printk("dev %04x, block %d\n\r",tmp->b_dev, tmp->b_blocknr);
+               printk("dev %04x, sector %d\n\r",req->dev,req->sector);
+               req->nr_sectors--;
+               req->nr_sectors &= ~1;
+               req->sector += 2;
+               req->sector &= ~1;              
        }
-       if (!CURRENT->bh) {
-               printk("next_buffer: request buffer list destroyed\r\n");
-               end_request(0);
-               return;
+       if (bh = req->bh) {
+               req->bh = bh->b_reqnext;
+               bh->b_reqnext = NULL;
+               bh->b_uptodate = uptodate;
+               unlock_buffer(bh);
+               if (bh = req->bh) {
+                       if (req->nr_sectors < 2) {
+                               req->nr_sectors = 2;
+                               printk("end_request: buffer-list destroyed\n");
+                       }
+                       req->buffer = bh->b_data;
+                       return;
+               }
        }
-       CURRENT->buffer = CURRENT->bh->b_data;
-       CURRENT->errors = 0;
+       DEVICE_OFF(req->dev);
+       CURRENT = req->next;
+       wake_up(&req->waiting);
+       req->dev = -1;
+       wake_up(&wait_for_request);
 }
 
 #ifdef DEVICE_INTR
index 2b9d2384b12dba816d7a7cb690de9e30b455f02f..c4af79e281dfc5b71d16ca769ae4217963e9d691 100644 (file)
@@ -35,7 +35,7 @@
 /*
  * Automatic floppy-detection and formatting written by Werner Almesberger
  * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with
- * the floppy-change signa| detection.
+ * the floppy-change signal detection.
  */
 
 #include <linux/sched.h>
@@ -942,7 +942,8 @@ static void config_types(void)
 {
        printk("Floppy drive(s): ");
        base_type[0] = find_base(0,(CMOS_READ(0x10) >> 4) & 15);
-       if (((CMOS_READ(0x14) >> 6) & 1) == 0) base_type[0] = NULL;
+       if (((CMOS_READ(0x14) >> 6) & 1) == 0)
+               base_type[1] = NULL;
        else {
                printk(", ");
                base_type[1] = find_base(1,CMOS_READ(0x10) & 15);
index 6244567dc7a45798eae788cbaa20a50a6918d4f1..e573315ffb9a908608a8fb0d558190b77fea63af 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/hdreg.h>
+
+#define REALLY_SLOW_IO
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/segment.h>
@@ -423,17 +425,8 @@ static void bad_rw_intr(void)
        if (!CURRENT)
                return;
        if (++CURRENT->errors >= MAX_ERRORS)
-               if (CURRENT->bh && CURRENT->nr_sectors > 2) {
-                       CURRENT->nr_sectors--;
-                       CURRENT->sector++;
-                       if (CURRENT->nr_sectors & 1) {
-                               CURRENT->nr_sectors--;
-                               CURRENT->sector++;
-                       }
-                       next_buffer(0);
-               } else
-                       end_request(0);
-       if (CURRENT->errors > MAX_ERRORS/2)
+               end_request(0);
+       else if (CURRENT->errors > MAX_ERRORS/2)
                reset = 1;
        else
                recalibrate = 1;
@@ -457,16 +450,15 @@ static void read_intr(void)
                if ((i & STAT_MASK) != STAT_OK)
                        goto bad_read;
        CURRENT->errors = 0;
-       if (CURRENT->bh && (CURRENT->nr_sectors&1) && CURRENT->nr_sectors > 2)
-               next_buffer(1);
-       else
-               CURRENT->buffer += 512;
+       CURRENT->buffer += 512;
        CURRENT->sector++;
-       if (--CURRENT->nr_sectors) {
+       i = --CURRENT->nr_sectors;
+       if (!i || (CURRENT->bh && !(i&1)))
+               end_request(1);
+       if (i > 0) {
                SET_INTR(&read_intr);
                return;
        }
-       end_request(1);
 #if (HD_DELAY > 0)
        last_req = read_timer();
 #endif
@@ -487,24 +479,22 @@ static void write_intr(void)
        i = (unsigned) inb_p(HD_STATUS);
        if ((i & STAT_MASK) != STAT_OK)
                goto bad_write;
-       if (CURRENT->nr_sectors < 2) {
+       if (CURRENT->nr_sectors > 1 && !(i & DRQ_STAT))
+               goto bad_write;
+       CURRENT->sector++;
+       i = --CURRENT->nr_sectors;
+       CURRENT->buffer += 512;
+       if (!i || (CURRENT->bh && !(i & 1)))
                end_request(1);
+       if (i > 0) {
+               SET_INTR(&write_intr);
+               port_write(HD_DATA,CURRENT->buffer,256);
+       } else {
 #if (HD_DELAY > 0)
                last_req = read_timer();
 #endif
                do_hd_request();
-               return;
        }
-       if (!(i & DRQ_STAT))
-               goto bad_write;
-       CURRENT->sector++;
-       CURRENT->nr_sectors--;
-       if (CURRENT->bh && !(CURRENT->nr_sectors & 1))
-               next_buffer(1);
-       else
-               CURRENT->buffer += 512;
-       SET_INTR(&write_intr);
-       port_write(HD_DATA,CURRENT->buffer,256);
        return;
 bad_write:
        if (i & ERR_STAT)
@@ -534,16 +524,7 @@ static void hd_times_out(void)
        printk("HD timeout\n\r");
        cli();
        if (++CURRENT->errors >= MAX_ERRORS)
-               if (CURRENT->bh && CURRENT->nr_sectors > 2) {
-                       CURRENT->nr_sectors--;
-                       CURRENT->sector++;
-                       if (CURRENT->nr_sectors & 1) {
-                               CURRENT->nr_sectors--;
-                               CURRENT->sector++;
-                       }
-                       next_buffer(0);
-               } else
-                       end_request(0);
+               end_request(0);
        do_hd_request();
 }
 
@@ -558,7 +539,7 @@ static void do_hd_request(void)
        dev = MINOR(CURRENT->dev);
        block = CURRENT->sector;
        nsect = CURRENT->nr_sectors;
-       if (dev >= (NR_HD<<6) || block+nsect > hd[dev].nr_sects) {
+       if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects) {
                end_request(0);
                goto repeat;
        }
index 18f58d48443fc4760db7e89956bb11a23ba66e37..cd6aef7d1303d678d34a6e6e416a6ae0a4119cf2 100644 (file)
@@ -125,6 +125,11 @@ static void make_request(int major,int rw, struct buffer_head * bh)
                printk("Bad block dev command, must be R/W/RA/WA\n");
                return;
        }
+       if (blk_size[major])
+               if (blk_size[major][MINOR(bh->b_dev)] <= bh->b_blocknr) {
+                       bh->b_dirt = bh->b_uptodate = 0;
+                       return;
+               }
        lock_buffer(bh);
        if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
                unlock_buffer(bh);
index 049fdd8cab388461ecd5a69723043c08924651b6..085e10f213d88ee14850d24725cd669a8e9bcea8 100644 (file)
@@ -1,16 +1,39 @@
 /*
  *     ultrastor.c     (C) 1991 David B. Gentzel
- *     Low-level scsi driver for UltraStor 14F
+ *     Low-level SCSI driver for UltraStor 14F
  *     by David B. Gentzel, Whitfield Software Services, Carnegie, PA
  *         (gentzel@nova.enet.dec.com)
  *     Thanks to UltraStor for providing the necessary documentation
  */
 
-/* ??? Caveats:
-   This driver is VERY stupid.  It takes no advantage of much of the power of
-   the UltraStor controller.  We just sit-and-spin while waiting for commands
-   to complete.  I hope to go back and beat it into shape, but PLEASE, anyone
-   else who would like to, please make improvements! */
+/*
+ * NOTES:
+ *    The UltraStor 14F is an intelligent, high performance ISA SCSI-2 host
+ *    adapter.  It is essentially an ISA version of the UltraStor 24F EISA
+ *    adapter.  It supports first-party DMA, command queueing, and
+ *    scatter/gather I/O.  It can also emulate the standard AT MFM/RLL/IDE
+ *    interface for use with OS's which don't support SCSI.
+ *
+ *    This driver may also work (with some small changes) with the UltraStor
+ *    24F.  I have no way of confirming this...
+ *
+ *    Places flagged with a triple question-mark are things which are either
+ *    unfinished, questionable, or wrong.
+ */
+
+/*
+ * CAVEATS: ???
+ *    This driver is VERY stupid.  It takes no advantage of much of the power
+ *    of the UltraStor controller.  We just sit-and-spin while waiting for
+ *    commands to complete.  I hope to go back and beat it into shape, but
+ *    PLEASE, anyone else who would like to, please make improvements!
+ *
+ *    By defining USE_QUEUECOMMAND as TRUE in ultrastor.h, you enable the
+ *    queueing feature of the mid-level SCSI driver.  This should improve
+ *    performance somewhat.  However, it does not seem to work.  I believe
+ *    this is due to a bug in the mid-level driver, but I haven't looked
+ *    too closely.
+ */
 
 #include <linux/config.h>
 
 #include <stddef.h>
 
 #include <linux/string.h>
-#include <linux/config.h>
 #include <linux/sched.h>
-#include <linux/fs.h>
 #include <linux/kernel.h>
-#include <linux/hdreg.h>
-#include <asm/system.h>
 #include <asm/io.h>
-#include <asm/segment.h>
+#include <asm/system.h>
 
+#define ULTRASTOR_PRIVATE      /* Get the private stuff from ultrastor.h */
 #include "ultrastor.h"
 #include "scsi.h"
 #include "hosts.h"
 
-#define VERSION "1.0 alpha"
+#define VERSION "1.0 beta"
 
 #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
+#define BIT(n) (1ul << (n))
 #define BYTE(num, n) ((unsigned char)((unsigned int)(num) >> ((n) * 8)))
 
 /* Simply using "unsigned long" in these structures won't work as it causes
@@ -44,21 +65,32 @@ typedef struct {
     unsigned char bytes[4];
 } Longword;
 
+/* Used to fetch the configuration info from the config i/o registers.  We
+   then store (in a friendlier format) in config. */
+struct config_1 {
+    unsigned char bios_segment: 3;
+    unsigned char reserved: 1;
+    unsigned char interrupt: 2;
+    unsigned char dma_channel: 2;
+};
+struct config_2 {
+    unsigned char ha_scsi_id: 3;
+    unsigned char mapping_mode: 2;
+    unsigned char bios_drive_number: 1;
+    unsigned char tfr_port: 2;
+};
+
 /* Used to store configuration info read from config i/o registers.  Most of
    this is not used yet, but might as well save it. */
 struct config {
-    struct {
-       unsigned char bios_segment: 3;
-       unsigned char reserved: 1;
-       unsigned char interrupt: 2;
-       unsigned char dma_channel: 2;
-    } config_1;
-    struct {
-       unsigned char ha_scsi_id: 3;
-       unsigned char mapping_mode: 2;
-       unsigned char bios_drive_number: 1;
-       unsigned char tfr_port: 2;
-    } config_2;
+    unsigned short port_address;
+    const void *bios_segment;
+    unsigned char interrupt: 4;
+    unsigned char dma_channel: 3;
+    unsigned char ha_scsi_id: 3;
+    unsigned char heads: 6;
+    unsigned char sectors: 6;
+    unsigned char bios_drive_number: 1;
 };
 
 /* MailBox SCSI Command Packet.  Basic command structure for communicating
@@ -97,12 +129,11 @@ static const unsigned char interrupt_table[4] = { 15, 14, 11, 10 };
 /* Allowed DMA channels for 14f (0 indicates reserved) */
 static const unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
 
-#if 0  /* Not currently used, head/sector mappings allowed by 14f */
+/* Head/sector mappings allowed by 14f */
 static const struct {
     unsigned char heads;
     unsigned char sectors;
 } mapping_table[4] = { { 16, 63 }, { 64, 32 }, { 64, 63 }, { 0, 0 } };
-#endif
 
 /* Config info */
 static struct config config;
@@ -114,8 +145,7 @@ static int host_number;
 #ifdef PORT_OVERRIDE
 # define PORT_ADDRESS PORT_OVERRIDE
 #else
-static unsigned short port_address = 0;
-# define PORT_ADDRESS port_address
+# define PORT_ADDRESS (config.port_address)
 #endif
 
 static volatile int aborted = 0;
@@ -126,6 +156,10 @@ static const unsigned short ultrastor_ports[] = {
 };
 #endif
 
+void ultrastor_interrupt(void);
+
+static void (*ultrastor_done)(int, int) = 0;
+
 static const struct {
     const char *signature;
     size_t offset;
@@ -138,75 +172,105 @@ int ultrastor_14f_detect(int hostnum)
 {
     size_t i;
     unsigned char in_byte;
-    const void *base_address;
+    struct config_1 config_1;
+    struct config_2 config_2;
 
-#ifdef DEBUG
-    printk("ultrastor_14f_detect: called\n");
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+    printk("US14F: detect: called\n");
 #endif
 
 #ifndef PORT_OVERRIDE
-/* ??? This is easy to implement, but I'm not sure how "friendly" it is to
-   go off and read random i/o ports. */
-# error Not implemented!
+    PORT_ADDRESS = 0;
+    for (i = 0; i < ARRAY_SIZE(ultrastor_ports); i++) {
+       PORT_ADDRESS = ultrastor_ports[i];
 #endif
 
-    if (!PORT_ADDRESS) {
-#ifdef DEBUG
-       printk("ultrastor_14f_detect: no port address found!\n");
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+       printk("US14F: detect: testing port address %03X\n", PORT_ADDRESS);
 #endif
-       return FALSE;
-    }
 
-#ifdef DEBUG
-    printk("ultrastor_14f_detect: port address = %X\n", PORT_ADDRESS);
+       in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 0));
+       if (in_byte != US14F_PRODUCT_ID_0) {
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+# ifdef PORT_OVERRIDE
+           printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
+# else
+           printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS);
+# endif
 #endif
-
-    in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 0));
-    if (in_byte != US14F_PRODUCT_ID_0) {
-#ifdef DEBUG
-       printk("ultrastor_14f_detect: unknown product ID 0 - %02X\n", in_byte);
+#ifdef PORT_OVERRIDE
+           return FALSE;
+#else
+           continue;
 #endif
-       return FALSE;
-    }
-    in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 1));
-    /* Only upper nibble is defined for Product ID 1 */
-    if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
-#ifdef DEBUG
-       printk("ultrastor_14f_detect: unknown product ID 1 - %02X\n", in_byte);
+       }
+       in_byte = inb(PRODUCT_ID(PORT_ADDRESS + 1));
+       /* Only upper nibble is defined for Product ID 1 */
+       if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+# ifdef PORT_OVERRIDE
+           printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
+# else
+           printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS);
+# endif
+#endif
+#ifdef PORT_OVERRIDE
+           return FALSE;
+#else
+           continue;
 #endif
+       }
+#ifndef PORT_OVERRIDE
+       break;
+    }
+    if (i == ARRAY_SIZE(ultrastor_ports)) {
+# if (ULTRASTOR_DEBUG & UD_DETECT)
+       printk("US14F: detect: no port address found!\n");
+# endif
        return FALSE;
     }
+#endif
+
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+    printk("US14F: detect: adapter found at port address %03X\n",
+          PORT_ADDRESS);
+#endif
 
     /* All above tests passed, must be the right thing.  Get some useful
        info. */
-    *(char *)&config.config_1 = inb(CONFIG(PORT_ADDRESS + 0));
-    *(char *)&config.config_2 = inb(CONFIG(PORT_ADDRESS + 1));
+    *(char *)&config_1 = inb(CONFIG(PORT_ADDRESS + 0));
+    *(char *)&config_2 = inb(CONFIG(PORT_ADDRESS + 1));
+    config.bios_segment = bios_segment_table[config_1.bios_segment];
+    config.interrupt = interrupt_table[config_1.interrupt];
+    config.dma_channel = dma_channel_table[config_1.dma_channel];
+    config.ha_scsi_id = config_2.ha_scsi_id;
+    config.heads = mapping_table[config_2.mapping_mode].heads;
+    config.sectors = mapping_table[config_2.mapping_mode].sectors;
+    config.bios_drive_number = config_2.bios_drive_number;
 
     /* To verify this card, we simply look for the UltraStor SCSI from the
        BIOS version notice. */
-    base_address = bios_segment_table[config.config_1.bios_segment];
-    if (base_address != NULL) {
+    if (config.bios_segment != NULL) {
        int found = 0;
 
        for (i = 0; !found && i < ARRAY_SIZE(signatures); i++)
-           if (memcmp((char *)base_address + signatures[i].offset,
+           if (memcmp((char *)config.bios_segment + signatures[i].offset,
                       signatures[i].signature, signatures[i].length))
                found = 1;
        if (!found)
-           base_address = NULL;
+           config.bios_segment = NULL;
     }
-    if (!base_address) {
-#ifdef DEBUG
-       printk("ultrastor_14f_detect: not detected.\n");
+    if (!config.bios_segment) {
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+       printk("US14F: detect: not detected.\n");
 #endif
        return FALSE;
     }
 
     /* Final consistancy check, verify previous info. */
-    if (!dma_channel_table[config.config_1.dma_channel]
-       || !(config.config_2.tfr_port & 0x2)) {
-#ifdef DEBUG
-       printk("ultrastor_14f_detect: consistancy check failed\n");
+    if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+       printk("US14F: detect: consistancy check failed\n");
 #endif
        return FALSE;
     }
@@ -216,18 +280,25 @@ int ultrastor_14f_detect(int hostnum)
        exhausted! */
 
     /* Finally!  Now I'm satisfied... */
-#ifdef DEBUG
-    printk("ultrastor_14f_detect: detect succeeded\n"
+#if (ULTRASTOR_DEBUG & UD_DETECT)
+    printk("US14F: detect: detect succeeded\n"
+          "  Port address: %03X\n"
           "  BIOS segment: %05X\n"
-          "  Interrupt: %d\n"
-          "  DMA channel: %d\n"
-          "  H/A SCSI ID: %d\n",
-          base_address, interrupt_table[config.config_1.interrupt],
-          dma_channel_table[config.config_1.dma_channel],
-          config.config_2.ha_scsi_id);
+          "  Interrupt: %u\n"
+          "  DMA channel: %u\n"
+          "  H/A SCSI ID: %u\n",
+          PORT_ADDRESS, config.bios_segment, config.interrupt,
+          config.dma_channel, config.ha_scsi_id);
 #endif
     host_number = hostnum;
-    scsi_hosts[hostnum].this_id = config.config_2.ha_scsi_id;
+    scsi_hosts[hostnum].this_id = config.ha_scsi_id;
+#if USE_QUEUECOMMAND
+    set_intr_gate(0x20 + config.interrupt, ultrastor_interrupt);
+    /* gate to PIC 2 */
+    outb_p(inb_p(0x21) & ~BIT(2), 0x21);
+    /* enable the interrupt */
+    outb(inb_p(0xA1) & ~BIT(config.interrupt - 8), 0xA1);
+#endif
     return TRUE;
 }
 
@@ -238,64 +309,86 @@ const char *ultrastor_14f_info(void)
           " by David B. Gentzel\n";
 }
 
-#if 0
+static struct mscp mscp = {
+    OP_SCSI, DTD_SCSI, FALSE, TRUE, FALSE      /* This stuff doesn't change */
+};
+
 int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd,
                               void *buff, int bufflen, void (*done)(int, int))
-#else
-int ultrastor_14f_command(unsigned char target, const void *cmnd,
-                         void *buff, int bufflen)
-#endif
 {
-    struct mscp mscp = {
-       OP_SCSI, DTD_SCSI, FALSE, TRUE, FALSE,
-       target, 0, 0 /* LUN??? */,
-       *(Longword *)&buff,
-       *(Longword *)&bufflen,
-       { 0, 0, 0, 0 },
-       0,
-       0,
-       0,
-       ((*(char *)cmnd <= 0x1F) ? 6 : 10),
-       { 0 },  /* Filled in via memcpy below */
-       0,
-       0,
-       { 0, 0, 0, 0 }
-    };
     unsigned char in_byte;
 
+#if (ULTRASTOR_DEBUG & UD_COMMAND)
+    printk("US14F: queuecommand: called\n");
+#endif
+
+    /* Skip first (constant) byte */
+    memset((char *)&mscp + 1, 0, sizeof (struct mscp) - 1);
+    mscp.target_id = target;
+    /* mscp.lun = ???; */
+    mscp.transfer_data = *(Longword *)&buff;
+    mscp.transfer_data_length = *(Longword *)&bufflen,
+    mscp.length_of_scsi_cdbs = ((*(unsigned char *)cmnd <= 0x1F) ? 6 : 10);
     memcpy(mscp.scsi_cdbs, cmnd, mscp.length_of_scsi_cdbs);
 
     /* Find free OGM slot (OGMINT bit is 0) */
     do
-       in_byte = inb(LCL_DOORBELL_INTR(PORT_ADDRESS));
+       in_byte = inb_p(LCL_DOORBELL_INTR(PORT_ADDRESS));
     while (!aborted && (in_byte & 1));
     if (aborted)
        /* ??? is this right? */
        return (aborted << 16);
 
     /* Store pointer in OGM address bytes */
-    outb(BYTE(&mscp, 0), OGM_DATA_PTR(PORT_ADDRESS + 0));
-    outb(BYTE(&mscp, 1), OGM_DATA_PTR(PORT_ADDRESS + 1));
-    outb(BYTE(&mscp, 2), OGM_DATA_PTR(PORT_ADDRESS + 2));
-    outb(BYTE(&mscp, 3), OGM_DATA_PTR(PORT_ADDRESS + 3));
+    outb_p(BYTE(&mscp, 0), OGM_DATA_PTR(PORT_ADDRESS + 0));
+    outb_p(BYTE(&mscp, 1), OGM_DATA_PTR(PORT_ADDRESS + 1));
+    outb_p(BYTE(&mscp, 2), OGM_DATA_PTR(PORT_ADDRESS + 2));
+    outb_p(BYTE(&mscp, 3), OGM_DATA_PTR(PORT_ADDRESS + 3));
 
     /* Issue OGM interrupt */
-    outb(0x1, LCL_DOORBELL_INTR(PORT_ADDRESS));
+    outb_p(0x1, LCL_DOORBELL_INTR(PORT_ADDRESS));
+
+    ultrastor_done = done;
+
+#if (ULTRASTOR_DEBUG & UD_COMMAND)
+    printk("US14F: queuecommand: returning\n");
+#endif
+
+    return 0;
+}
+
+#if !USE_QUEUECOMMAND
+int ultrastor_14f_command(unsigned char target, const void *cmnd,
+                         void *buff, int bufflen)
+{
+    unsigned char in_byte;
+
+#if (ULTRASTOR_DEBUG & UD_COMMAND)
+    printk("US14F: command: called\n");
+#endif
+
+    (void)ultrastor_14f_queuecommand(target, cmnd, buff, bufflen, 0);
 
     /* Wait for ICM interrupt */
     do
-       in_byte = inb(SYS_DOORBELL_INTR(PORT_ADDRESS));
+       in_byte = inb_p(SYS_DOORBELL_INTR(PORT_ADDRESS));
     while (!aborted && !(in_byte & 1));
     if (aborted)
        /* ??? is this right? */
        return (aborted << 16);
 
     /* Clean ICM slot (set ICMINT bit to 0) */
-    outb(0x1, SYS_DOORBELL_INTR(PORT_ADDRESS));
+    outb_p(0x1, SYS_DOORBELL_INTR(PORT_ADDRESS));
+
+#if (ULTRASTOR_DEBUG & UD_COMMAND)
+    printk("US14F: command: returning %08X\n",
+          (mscp.adapter_status << 16) | mscp.target_status);
+#endif
 
     /* ??? not right, but okay for now? */
     return (mscp.adapter_status << 16) | mscp.target_status;
 }
+#endif
 
 int ultrastor_14f_abort(int code)
 {
@@ -307,23 +400,71 @@ int ultrastor_14f_reset(void)
 {
     unsigned char in_byte;
 
-#ifdef DEBUG
-    printk("ultrastor_14f_reset: called\n");
+#if (ULTRASTOR_DEBUG & UD_RESET)
+    printk("US14F: reset: called\n");
 #endif
 
     /* Issue SCSI BUS reset */
-    outb(0x20, LCL_DOORBELL_INTR(PORT_ADDRESS));
+    outb_p(0x20, LCL_DOORBELL_INTR(PORT_ADDRESS));
+
     /* Wait for completion... */
     do
-       in_byte = inb(LCL_DOORBELL_INTR(PORT_ADDRESS));
+       in_byte = inb_p(LCL_DOORBELL_INTR(PORT_ADDRESS));
     while (in_byte & 0x20);
 
     aborted = DID_RESET;
 
-#ifdef DEBUG
-    printk("ultrastor_14f_reset: returning\n");
+#if (ULTRASTOR_DEBUG & UD_RESET)
+    printk("US14F: reset: returning\n");
 #endif
     return 0;
 }
 
+#if USE_QUEUECOMMAND
+void ultrastor_interrupt_service(void)
+{
+    if (ultrastor_done == 0) {
+       printk("US14F: unexpected ultrastor interrupt\n\r");
+       /* ??? Anything else we should do here?  Reset? */
+       return;
+    }
+    printk("US14F: got an ultrastor interrupt: %u\n\r",
+          (mscp.adapter_status << 16) | mscp.target_status);
+    ultrastor_done(host_number,
+                  (mscp.adapter_status << 16) | mscp.target_status);
+    ultrastor_done = 0;
+}
+
+__asm__("
+_ultrastor_interrupt:
+       cld
+       pushl %eax
+       pushl %ecx
+       pushl %edx
+       push %ds
+       push %es
+       push %fs
+       movl $0x10,%eax
+       mov %ax,%ds
+       mov %ax,%es
+       movl $0x17,%eax
+       mov %ax,%fs
+       movb $0x20,%al
+       outb %al,$0xA0          # EOI to interrupt controller #1
+       outb %al,$0x80          # give port chance to breathe
+       outb %al,$0x80
+       outb %al,$0x80
+       outb %al,$0x80
+       outb %al,$0x20
+       call _ultrastor_interrupt_service
+       pop %fs
+       pop %es
+       pop %ds
+       popl %edx
+       popl %ecx
+       popl %eax
+       iret
+");
+#endif
+
 #endif
index 13ded237dcf3e89b140eca84ec7e91b363456d06..dfe34ee947b2c44e6dfc9ca58054de7468abb550 100644 (file)
@@ -9,10 +9,6 @@
 #ifndef _ULTRASTOR_H
 #define _ULTRASTOR_H
 
-/* ??? Some of the stuff in this file is really private to ultrastor.c and
-   should be moved elsewhere (as this file is included by higher-level driver
-   files). */
-
 /* ??? These don't really belong here */
 #ifndef TRUE
 # define TRUE 1
 # define FALSE 0
 #endif
 
+/* ??? This should go eventually, once the queueing bug is fixed */
+#define USE_QUEUECOMMAND FALSE
+
 int ultrastor_14f_detect(int);
 const char *ultrastor_14f_info(void);
-#if 0  /* ??? Future direction... */
 int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd,
                               void *buff, int bufflen,
                               void (*done)(int, int));
-#else
+#if !USE_QUEUECOMMAND
 int ultrastor_14f_command(unsigned char target, const void *cmnd,
                          void *buff, int bufflen);
 #endif
 int ultrastor_14f_abort(int);
 int ultrastor_14f_reset(void);
 
-#if 0  /* ??? Future direction... */
-# define ULTRASTOR_14F \
-    { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, 0, \
-      ultrastor_14f_queuecommand, ultrastor_14f_abort, ultrastor_14f_reset, \
-      TRUE, 0, 0 }
-#else
-# define ULTRASTOR_14F \
+#if !USE_QUEUECOMMAND
+#define ULTRASTOR_14F \
     { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, \
       ultrastor_14f_command, 0, ultrastor_14f_abort, ultrastor_14f_reset, \
       FALSE, 0, 0 }
+#else
+#define ULTRASTOR_14F \
+    { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, 0, \
+      ultrastor_14f_queuecommand, ultrastor_14f_abort, ultrastor_14f_reset, \
+      TRUE, 0, 0 }
 #endif
 
-#define PORT_OVERRIDE 0x330
+#define UD_DETECT 0x1
+#define UD_COMMAND 0x2
+#define UD_RESET 0x4
+
+#ifdef ULTRASTOR_PRIVATE
+
+/* #define PORT_OVERRIDE 0x330 */
 
 /* Port addresses (relative to the base address) */
 #define LCL_DOORBELL_MASK(port) ((port) + 0x0)
@@ -82,3 +86,5 @@ int ultrastor_14f_reset(void);
 #define HA_CMD_WRITE_BUFF 0x4
 
 #endif
+
+#endif
index 8709a22100be7aa374a3f8ecd808d2f9c84553fa..746692c382c3a67841916ea6d3e9eceb2815d727 100644 (file)
@@ -883,6 +883,8 @@ void con_init(void)
        char *display_ptr;
        int currcons = 0;
        long base;
+       int orig_x = ORIG_X;
+       int orig_y = ORIG_Y;
 
        video_num_columns = ORIG_VIDEO_COLS;
        video_size_row = video_num_columns * 2;
@@ -975,7 +977,7 @@ void con_init(void)
        vt_cons[0].vt_mode = KD_TEXT;
         vc_cons[0].vc_bold_attr = -1;
 
-       gotoxy(currcons,ORIG_X,ORIG_Y);
+       gotoxy(currcons,orig_x,orig_y);
        for (currcons = 1; currcons<NR_CONSOLES; currcons++) {
                vc_cons[currcons] = vc_cons[0];
                vt_cons[currcons] = vt_cons[0];
index 1398059d93853e6d0e0891321946bd1b14a44fbc..82f711dcc6ecc638dbf4d0012e27e32c009c328a 100644 (file)
@@ -1012,7 +1012,7 @@ void kb_ack(void)
        int i;
 
        for(i=0; i<0x10000; i++)
-               if (inb(0x64) == 0xfa)
+               if (inb(0x60) == 0xfa)
                        break;
 }
 
index 413ee86f20b66a6b7e26390da7e84c2348913d19..e5cb171932223b7966fe6de3d37657489d9aed68 100644 (file)
@@ -25,6 +25,9 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 
+#include <sys/kd.h>
+#include "vt_kern.h"
+
 #ifndef MIN
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
@@ -65,6 +68,8 @@ struct tty_queue * table_list[]={
 
 void change_console(unsigned int new_console)
 {
+       if (vt_cons[fg_console].vt_mode == KD_GRAPHICS)
+               return;
        if (new_console == fg_console || new_console >= NR_CONSOLES)
                return;
        table_list[0] = con_queues + 0 + new_console*3;
@@ -124,9 +129,14 @@ void copy_to_cooked(struct tty_struct * tty)
                                        ((EOF_CHAR(tty) != _POSIX_VDISABLE) &&
                                         (c==EOF_CHAR(tty))))) {
                                        if (L_ECHO(tty)) {
-                                               if (c<32)
-                                                       PUTCH(127,tty->write_q);
-                                               PUTCH(127,tty->write_q);
+                                               if (c<32) {
+                                                       PUTCH(8,tty->write_q);
+                                                       PUTCH(' ',tty->write_q);
+                                                       PUTCH(8,tty->write_q);
+                                               }
+                                               PUTCH(8,tty->write_q);
+                                               PUTCH(' ',tty->write_q);
+                                               PUTCH(8,tty->write_q);
                                                TTY_WRITE_FLUSH(tty);
                                        }
                                        DEC(tty->secondary->head);
@@ -141,9 +151,14 @@ void copy_to_cooked(struct tty_struct * tty)
                                    (c==EOF_CHAR(tty))))
                                        continue;
                                if (L_ECHO(tty)) {
-                                       if (c<32)
-                                               PUTCH(127,tty->write_q);
-                                       PUTCH(127,tty->write_q);
+                                       if (c<32) {
+                                               PUTCH(8,tty->write_q);
+                                               PUTCH(' ',tty->write_q);
+                                               PUTCH(8,tty->write_q);
+                                       }
+                                       PUTCH(8,tty->write_q);
+                                       PUTCH(32,tty->write_q);
+                                       PUTCH(8,tty->write_q);
                                        TTY_WRITE_FLUSH(tty);
                                }
                                DEC(tty->secondary->head);
index 8a0dbe88772d278513507dcf67ea5b1d335b70ef..784cbad872cbfa8659eb63d81a426f835b8162b8 100644 (file)
@@ -116,7 +116,8 @@ int sys_fork(long ebx,long ecx,long edx,
        current->p_cptr = p;
        p->counter = p->priority;
        p->signal = 0;
-       p->alarm = 0;
+       p->it_real_value = p->it_virt_value = p->it_prof_value = 0;
+       p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;
        p->leader = 0;          /* process leadership doesn't inherit */
        p->utime = p->stime = 0;
        p->cutime = p->cstime = 0;
diff --git a/kernel/itimer.c b/kernel/itimer.c
new file mode 100644 (file)
index 0000000..7362dc8
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * linux/kernel/itimer.c
+ *
+ * (C) 1992 Darren Senn
+ */
+
+/* These are all the functions necessary to implement itimers */
+
+#include <linux/sched.h>
+#include <asm/segment.h>
+
+#include <signal.h>
+#include <sys/time.h>
+#include <errno.h>
+
+static unsigned long tvtojiffies(struct timeval *value)
+{
+       return((unsigned long )value->tv_sec * HZ +
+               (unsigned long )value->tv_usec / (1000000 / HZ));
+}
+
+static void jiffiestotv(unsigned long jiffies, struct timeval *value)
+{
+       value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
+       value->tv_sec = jiffies / HZ;
+       return;
+}
+
+int _getitimer(int which, struct itimerval *value)
+{
+       register unsigned long val, interval;
+
+       switch (which) {
+       case ITIMER_REAL:
+               val = current->it_real_value;
+               interval = current->it_real_incr;
+               break;
+       case ITIMER_VIRTUAL:
+               val = current->it_virt_value;
+               interval = current->it_virt_incr;
+               break;
+       case ITIMER_PROF:
+               val = current->it_prof_value;
+               interval = current->it_prof_incr;
+               break;
+       default:
+               return(-EINVAL);
+       }
+       jiffiestotv(val, &value->it_value);
+       jiffiestotv(interval, &value->it_interval);
+       return(0);
+}
+
+int sys_getitimer(int which, struct itimerval *value)
+{
+       struct itimerval get_buffer;
+       int k;
+
+       if (!value)
+               return -EFAULT;
+       k = _getitimer(which, &get_buffer);
+       if (k < 0)
+               return k;
+       verify_area(value, sizeof(struct itimerval));
+       memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
+       return 0;
+}
+
+int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+{
+       register unsigned long i, j;
+       int k;
+
+       i = tvtojiffies(&value->it_interval);
+       j = tvtojiffies(&value->it_value);
+       if (ovalue && (k = _getitimer(which, ovalue)) < 0)
+               return k;
+       switch (which) {
+               case ITIMER_REAL:
+                       current->it_real_value = j;
+                       current->it_real_incr = i;
+                       break;
+               case ITIMER_VIRTUAL:
+                       current->it_virt_value = j;
+                       current->it_virt_incr = i;
+                       break;
+               case ITIMER_PROF:
+                       current->it_prof_value = j;
+                       current->it_prof_incr = i;
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+{
+       struct itimerval set_buffer, get_buffer;
+       int k;
+
+       if (!value)
+               return -EFAULT;
+       memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
+       k = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
+       if (k < 0 || !ovalue)
+               return k;
+       verify_area(ovalue, sizeof(struct itimerval));
+       memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer));
+       return 0;
+}
index 85a1131c9dedd39aaa67128715d2b3540a6e55ff..c4a219b03ffd6ff52cfd448ce23767be3f4c7450 100644 (file)
@@ -58,7 +58,7 @@ static char * sib(struct info * info, int mod)
 char * ea(struct info * info, unsigned short code)
 {
        unsigned char mod,rm;
-       long * tmp = &EAX;
+       long * tmp;
        int offset = 0;
 
        mod = (code >> 6) & 3;
index 01d04a975aa76fdbf5d058af242bc8c9f1595f0f..2d960bbc35fd65c41bbea8add9683c69f65ec831 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/segment.h>
+#include <sys/time.h>
 
 #include <signal.h>
 #include <errno.h>
@@ -68,7 +69,7 @@ union task_union {
        char stack[PAGE_SIZE];
 };
 
-static union task_union init_task = {INIT_TASK,};
+static union task_union init_task = {INIT_TASK, };
 
 unsigned long volatile jiffies=0;
 unsigned long startup_time=0;
@@ -134,10 +135,6 @@ void schedule(void)
                                        (*p)->timeout = 0;
                                        (*p)->state = TASK_RUNNING;
                                }
-                       if ((*p)->alarm && (*p)->alarm < jiffies) {
-                               (*p)->signal |= (1<<(SIGALRM-1));
-                               (*p)->alarm = 0;
-                       }
                        if (((*p)->signal & ~(*p)->blocked) &&
                        (*p)->state==TASK_INTERRUPTIBLE)
                                (*p)->state=TASK_RUNNING;
@@ -352,7 +349,7 @@ static unsigned long cexp[3] = {
        2014,   /* 0.9834714538216174 * FSCALE,  exp(-1/60) */
        2037,   /* 0.9944598480048967 * FSCALE,  exp(-1/180) */
 };
-unsigned long averunnable[3] /* fixed point numbers */
+unsigned long averunnable[3] = { 0, }; /* fixed point numbers */
 
 void update_avg(void)
 {
@@ -376,7 +373,8 @@ void do_timer(long cpl)
 {
        unsigned long mask;
        struct timer_struct *tp = timer_table+0;
-       static int avg_cnt;
+       struct task_struct ** task_p;
+       static int avg_cnt = 0;
 
        for (mask = 1 ; mask ; tp++,mask += mask) {
                if (mask > timer_active)
@@ -390,6 +388,25 @@ void do_timer(long cpl)
                sti();
        }
 
+       /* Update ITIMER_REAL for every task */
+       for (task_p = &LAST_TASK; task_p >= &FIRST_TASK; task_p--)
+               if (*task_p && (*task_p)->it_real_value
+                       && !(--(*task_p)->it_real_value)) {
+                       (*task_p)->signal |= (1<<(SIGALRM-1));
+                       (*task_p)->it_real_value = (*task_p)->it_real_incr;
+                       need_resched = 1;
+               }
+       /* Update ITIMER_PROF for the current task */
+       if (current->it_prof_value && !(--current->it_prof_value)) {
+               current->it_prof_value = current->it_prof_incr;
+               current->signal |= (1<<(SIGPROF-1));
+       }
+       /* Update ITIMER_VIRT for current task if not in a system call */
+       if (cpl && current->it_virt_value && !(--current->it_virt_value)) {
+               current->it_virt_value = current->it_virt_incr;
+               current->signal |= (1<<(SIGVTALRM-1));
+       }
+
        if (cpl)
                current->utime++;
        else
@@ -420,12 +437,14 @@ void do_timer(long cpl)
 
 int sys_alarm(long seconds)
 {
-       int old = current->alarm;
-
-       if (old)
-               old = (old - jiffies) / HZ;
-       current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
-       return (old);
+       extern int _setitimer(int, struct itimerval *, struct itimerval *);
+       struct itimerval new, old;
+
+       new.it_interval.tv_sec = new.it_interval.tv_usec = 0;
+       new.it_value.tv_sec = seconds;
+       new.it_value.tv_usec = 0;
+       _setitimer(ITIMER_REAL, &new, &old);
+       return(old.it_value.tv_sec + (old.it_value.tv_usec / 1000000));
 }
 
 int sys_getpid(void)
index d1d5afd8df0aeaebf5fab6a0eedfdf1614a04d10..77dd96de5e1ea1de16a5087bb0ff4dd8dd4132a8 100644 (file)
 
 #include <signal.h>
 #include <sys/wait.h>
+#include <sys/ptrace.h>
 #include <errno.h>
 
+extern int core_dump(long signr,struct pt_regs * regs);
+
 int sys_sgetmask()
 {
        return current->blocked;
@@ -117,44 +120,29 @@ int sys_sigaction(int signum, const struct sigaction * action,
        return 0;
 }
 
-/*
- * Routine writes a core dump image in the current directory.
- * Currently not implemented.
- */
-int core_dump(long signr)
-{
-       return(0);      /* We didn't do a dump */
-}
-
 extern int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
 
-int do_signal(long signr,long ebx, long ecx, long edx,
-             long esi, long edi, long ebp, long eax,
-             long ds, long es, long fs, long gs,
-             long orig_eax,
-       long eip, long cs, long eflags,
-       unsigned long * esp, long ss)
+int do_signal(long signr,struct pt_regs * regs)
 {
        unsigned long sa_handler;
-       long old_eip=eip;
+       long old_eip = regs->eip;
        struct sigaction * sa = current->sigaction + signr - 1;
        int longs;
-
        unsigned long * tmp_esp;
 
 #ifdef notdef
        printk("pid: %d, signr: %x, eax=%d, oeax = %d, int=%d\n", 
-               current->pid, signr, eax, orig_eax, 
+               current->pid, signr, regs->eax, regs->orig_eax, 
                sa->sa_flags & SA_INTERRUPT);
 #endif
-       if ((orig_eax != -1) &&
-           ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) {
-               if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||
+       if ((regs->orig_eax != -1) &&
+           ((regs->eax == -ERESTARTSYS) || (regs->eax == -ERESTARTNOINTR))) {
+               if ((regs->eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||
                    signr < SIGCONT || signr > SIGTTOU))
-                       *(&eax) = -EINTR;
+                       regs->eax = -EINTR;
                else {
-                       *(&eax) = orig_eax;
-                       *(&eip) = old_eip -= 2;
+                       regs->eax = regs->orig_eax;
+                       regs->eip = old_eip -= 2;
                }
        }
        sa_handler = (unsigned long) sa->sa_handler;
@@ -191,7 +179,7 @@ int do_signal(long signr,long ebx, long ecx, long edx,
                case SIGIOT:
                case SIGFPE:
                case SIGSEGV:
-                       if (core_dump(signr))
+                       if (core_dump(signr,regs))
                                do_exit(signr|0x80);
                        /* fall through */
                default:
@@ -203,19 +191,19 @@ int do_signal(long signr,long ebx, long ecx, long edx,
         */
        if (sa->sa_flags & SA_ONESHOT)
                sa->sa_handler = NULL;
-       *(&eip) = sa_handler;
-       longs = (sa->sa_flags & SA_NOMASK)?7:8;
-       *(&esp) -= longs;
-       verify_area(esp,longs*4);
-       tmp_esp=esp;
+       regs->eip = sa_handler;
+       longs = (sa->sa_flags & SA_NOMASK)?(7*4):(8*4);
+       regs->esp -= longs;
+       tmp_esp = (unsigned long *) regs->esp;
+       verify_area(tmp_esp,longs);
        put_fs_long((long) sa->sa_restorer,tmp_esp++);
        put_fs_long(signr,tmp_esp++);
        if (!(sa->sa_flags & SA_NOMASK))
                put_fs_long(current->blocked,tmp_esp++);
-       put_fs_long(eax,tmp_esp++);
-       put_fs_long(ecx,tmp_esp++);
-       put_fs_long(edx,tmp_esp++);
-       put_fs_long(eflags,tmp_esp++);
+       put_fs_long(regs->eax,tmp_esp++);
+       put_fs_long(regs->ecx,tmp_esp++);
+       put_fs_long(regs->edx,tmp_esp++);
+       put_fs_long(regs->eflags,tmp_esp++);
        put_fs_long(old_eip,tmp_esp++);
        current->blocked |= sa->sa_mask;
 /* force a supervisor-mode page-in of the signal handler to reduce races */
index 2318a7ed1bca5397cba3c28766ad6cd5184ea01d..75a86ba18d7ed30062c1cb7e2873588135622cc1 100644 (file)
@@ -180,14 +180,14 @@ void ctrl_alt_del(void)
  */
 int sys_setregid(int rgid, int egid)
 {
-       if (rgid>0) {
+       if (rgid >= 0) {
                if ((current->gid == rgid) || 
                    suser())
                        current->gid = rgid;
                else
                        return(-EPERM);
        }
-       if (egid>0) {
+       if (egid >= 0) {
                if ((current->gid == egid) ||
                    (current->egid == egid) ||
                    suser()) {
@@ -267,17 +267,17 @@ int sys_setreuid(int ruid, int euid)
 {
        int old_ruid = current->uid;
        
-       if (ruid>0) {
+       if (ruid >= 0) {
                if ((current->euid==ruid) ||
-                    (old_ruid == ruid) ||
+                   (old_ruid == ruid) ||
                    suser())
                        current->uid = ruid;
                else
                        return(-EPERM);
        }
-       if (euid>0) {
+       if (euid >= 0) {
                if ((old_ruid == euid) ||
-                    (current->euid == euid) ||
+                   (current->euid == euid) ||
                    suser()) {
                        current->euid = euid;
                        current->suid = euid;
index ad70318b680018658b62f60ba190c1e87ea20148..41014da9d94cda9ae612d4cfac891ddbc4b4fbce 100644 (file)
@@ -187,10 +187,13 @@ ret_from_sys_call:
        je 2f
        btrl %ecx,%ebx
        movl %ebx,signal(%eax)
+       movl %esp,%ebx
+       pushl %ebx
        incl %ecx
        pushl %ecx
        call _do_signal
        popl %ecx
+       popl %ebx
        testl %eax, %eax
        jne 1b                  # see if we need to switch tasks, or do more signals
 2:     popl %ebx
index 94b649f0a68a7162b06be7437bb49580d40104f6..e58abc07643a1e94350c3d0f0eff0f82124e75bb 100644 (file)
@@ -23,7 +23,7 @@ CPP   =gcc -E -nostdinc -I../include
        -c -o $*.o $<
 
 OBJS  = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \
-       execve.o wait.o string.o malloc.o
+       execve.o wait.o string.o malloc.o itimer.o
 
 lib.a: $(OBJS)
        $(AR) rcs lib.a $(OBJS)
index 1fa477bad97a1f392a9aa2d474c73364e03521b4..e3a8a73dfc1ce51d94fae2a2ad470f65ae498e8b 100644 (file)
@@ -81,7 +81,7 @@ int main(int argc, char ** argv)
        }
        fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
        if ((major_root != 2) && (major_root != 3) &&
-           (major_root != 0)) {
+           (major_root != 8) && (major_root != 0)) {
                fprintf(stderr, "Illegal root device (major = %d)\n",
                        major_root);
                die("Bad root device --- major #");