]> git.neil.brown.name Git - history.git/commitdiff
Import 0.99.15c 0.99.15c
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:22 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:22 +0000 (15:09 -0500)
32 files changed:
Makefile
drivers/block/floppy.c
drivers/block/xd.c
drivers/char/keyboard.c
drivers/char/tty_ioctl.c
drivers/char/vt.c
drivers/net/3c509.c
drivers/scsi/scsi.c
drivers/sound/os.h
fs/ext2/balloc.c
fs/ext2/namei.c
fs/hpfs/hpfs_fs.c
fs/inode.c
fs/namei.c
fs/proc/array.c
include/asm/bitops.h
include/linux/fs.h
include/linux/if_ether.h
include/linux/route.h
include/linux/sched.h
include/linux/sockios.h
include/linux/timer.h
include/linux/wait.h
include/linux/xd.h
kernel/module.c
kernel/sched.c
kernel/signal.c
kernel/traps.c
net/inet/arp.c
net/inet/datagram.c
net/inet/route.c
net/inet/sock.c

index 47407f6c798f0d7c8ba49ff4744dc0be34124a35..5c71b86d4e5219243889f661532838d5f699611c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 0.99
 PATCHLEVEL = 15
-ALPHA = b
+ALPHA = c
 
 all:   Version zImage
 
index ff9b04a3f751bd6c5207016ae0a8d71e98c0b011..84cf7e404f22c7b0677cd120ccc2f3d7bf100be9 100644 (file)
@@ -301,7 +301,7 @@ static void select_callback(unsigned long unused)
 
 static void floppy_select(unsigned int nr)
 {
-       static struct timer_list select = { NULL, 0, 0, select_callback };
+       static struct timer_list select = { NULL, NULL, 0, 0, select_callback };
 
        if (current_drive == (current_DOR & 3)) {
                floppy_ready();
@@ -324,10 +324,10 @@ static void motor_on_callback(unsigned long nr)
 }
 
 static struct timer_list motor_on_timer[4] = {
-       { NULL, 0, 0, motor_on_callback },
-       { NULL, 0, 1, motor_on_callback },
-       { NULL, 0, 2, motor_on_callback },
-       { NULL, 0, 3, motor_on_callback }
+       { NULL, NULL, 0, 0, motor_on_callback },
+       { NULL, NULL, 0, 1, motor_on_callback },
+       { NULL, NULL, 0, 2, motor_on_callback },
+       { NULL, NULL, 0, 3, motor_on_callback }
 };
 
 static void motor_off_callback(unsigned long nr)
@@ -341,10 +341,10 @@ static void motor_off_callback(unsigned long nr)
 }
 
 static struct timer_list motor_off_timer[4] = {
-       { NULL, 0, 0, motor_off_callback },
-       { NULL, 0, 1, motor_off_callback },
-       { NULL, 0, 2, motor_off_callback },
-       { NULL, 0, 3, motor_off_callback }
+       { NULL, NULL, 0, 0, motor_off_callback },
+       { NULL, NULL, 0, 1, motor_off_callback },
+       { NULL, NULL, 0, 2, motor_off_callback },
+       { NULL, NULL, 0, 3, motor_off_callback }
 };
 
 static void floppy_on(unsigned int nr)
index 07a4a42454e2bc84faf23f665bb3c9bae85d392f..ef8fa07754cf851a9978581568c114bd85ba66ec 100644 (file)
@@ -60,6 +60,7 @@ static XD_SIGNATURE xd_sigs[] = {
        { 0x0008,"06/24/88(C) Copyright 1988 Western Digital Corp.",xd_wd_init_controller,xd_wd_init_drive," Western Digital WDXT-GEN2" }, /* Dan Newcombe, newcombe@aa.csc.peachnet.edu */
        { 0x0015,"SEAGATE ST11 BIOS REVISION",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Salvador Abreu, spa@fct.unl.pt */
        { 0x0010,"ST11R BIOS",xd_seagate_init_controller,xd_seagate_init_drive," Seagate ST11M/R" }, /* Risto Kankkunen, risto.kankkunen@cs.helsinki.fi */
+       { 0x1000,"(c)Copyright 1987 SMS",xd_omti_init_controller,xd_omti_init_drive,"n OMTI 5520" }, /* Dirk Melchers, dirk@merlin.nbg.sub.org */
 };
 static u_char *xd_bases[] =
 {
@@ -580,6 +581,34 @@ static void xd_seagate_init_drive (u_char drive)
                printk("xd_seagate_init_drive: error reading geometry from drive %d\n",drive);
 }
 
+/* Omti support courtesy Dirk Melchers */
+static void xd_omti_init_controller (u_char *address)
+{
+       switch ((u_long) address) {
+               case 0xC8000:   xd_iobase = 0x320; break;
+               case 0xD0000:   xd_iobase = 0x324; break;
+               case 0xD8000:   xd_iobase = 0x328; break;
+               case 0xE0000:   xd_iobase = 0x32C; break;
+               default:        printk("xd_omti_init_controller: unsupported BIOS address %p\n",address);
+                               xd_iobase = 0x320; break;
+       }
+       
+       xd_irq = 5;                     /* the IRQ and DMA channel are fixed on the Omti controllers */
+       xd_dma = 3;
+       xd_maxsectors = 0x40;
+
+       outb(0,XD_RESET);               /* reset the controller */
+}
+
+static void xd_omti_init_drive (u_char drive)
+{
+       /* gets infos from drive */
+       xd_override_init_drive(drive);
+
+       /* set other parameters, Hardcoded, not that nice :-) */
+       xd_info[drive].control = 2;
+}
+
 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
    etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
 static void xd_override_init_drive (u_char drive)
index 9bad94db48af85567dad4bd29ad145cfd6bdf3cb..4ef9f6279ddf782689fd64254804b1ca65be4bc6 100644 (file)
 #endif
 
 #ifndef KBD_DEFLEDS
-#define KBD_DEFLEDS (1 << VC_NUMLOCK)
+/*
+ * Some laptops take the 789uiojklm,. keys as number pad when NumLock
+ * is on. This seems a good reason to start with NumLock off.
+ */
+#define KBD_DEFLEDS 0
 #endif
 
 #ifndef KBD_DEFLOCK
index bb9474da6a509283da103fd8225aaa24b40b8f8e..38952621ba8f26861cfdac91773548d19c4df63f 100644 (file)
@@ -523,6 +523,9 @@ int tty_ioctl(struct inode * inode, struct file * file,
                case TIOCSTI:
                        if ((current->tty != dev) && !suser())
                                return -EACCES;
+                       retval = verify_area(VERIFY_READ, (void *) arg, 1);
+                       if (retval)
+                               return retval;
                        put_tty_queue(get_fs_byte((char *) arg), &tty->read_q);
                        TTY_READ_FLUSH(tty);
                        return 0;
index 2fb3731da57f63f6e32797130db110851feeb51f..07385b0be3977f9ef342d7001ae031453ac928e8 100644 (file)
@@ -86,7 +86,7 @@ kd_nosound(unsigned long ignored)
 void
 kd_mksound(unsigned int count, unsigned int ticks)
 {
-       static struct timer_list sound_timer = { NULL, 0, 0, kd_nosound };
+       static struct timer_list sound_timer = { NULL, NULL, 0, 0, kd_nosound };
 
        cli();
        del_timer(&sound_timer);
index 7e18ce77913a18a188d5a12aa011c1c91f48c9a5..148d91ba1c3132faabaa3bcf82c54cdfc30cb978 100644 (file)
@@ -377,7 +377,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
                return 0;
 
        if (el3_debug > 4) {
-               printk("%s: el3_start_xmit(lenght = %d) called, status %4.4x.\n",
+               printk("%s: el3_start_xmit(lenght = %ld) called, status %4.4x.\n",
                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
        }
 #ifndef final_version
index 60257554b0a5722a9f416b03d22d6d95ed67c008..4eecd8b5204703ccf682c609198e1f6626ef0340 100644 (file)
@@ -127,10 +127,12 @@ static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
 static struct blist blacklist[] = 
 {
    {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
+   {"MAXTOR","XT-3280","PR02"},  /* Locks-up when LUN>0 polled. */
    {"MAXTOR","XT-4380S","B3C"},  /* Locks-up when LUN>0 polled. */
    {"MAXTOR","MXT-1240S","I1.2"}, /* Locks up when LUN > 0 polled */
    {"MAXTOR","XT-4170S","B5A"},  /* Locks-up sometimes when LUN>0 polled. */
    {"NEC","CD-ROM DRIVE:841","1.0"},  /* Locks-up when LUN>0 polled. */
+   {"RODIME","RO3000S","2.33"},  /* Locks up if polled for lun != 0 */
    {"SEAGATE", "ST157N", "\004|j"}, /* causes failed REQUEST SENSE on lun 1 for aha152x
                                     * controller, which causes SCSI code to reset bus.*/
    {"SEAGATE", "ST296","921"},   /* Responds to all lun */
@@ -387,7 +389,7 @@ static void scan_scsis (void)
 
                        scsi_devices[NR_SCSI_DEVICES].tagged_queue = 0;
 
-                       if ((scsi_devices[NR_SCSI_DEVICES].scsi_level == SCSI_2) &&
+                       if ((scsi_devices[NR_SCSI_DEVICES].scsi_level >= SCSI_2) &&
                            (scsi_result[7] & 2)) {
                            scsi_devices[NR_SCSI_DEVICES].tagged_supported = 1;
                            scsi_devices[NR_SCSI_DEVICES].current_tag = 0;
@@ -451,6 +453,9 @@ static void scan_scsis (void)
                        /* Some scsi devices cannot be polled for lun != 0
                           due to firmware bugs */
                        if(blacklisted(scsi_result)) break;
+                       /* Old drives like the MAXTOR XT-3280 say vers=0 */
+                       if ((scsi_result[2] & 0x07) == 0)
+                           break;
                        /* Some scsi-1 peripherals do not handle lun != 0.
                           I am assuming that scsi-2 peripherals do better */
                        if((scsi_result[2] & 0x07) == 1 && 
index bff4a43384f4a497fa5b46f9666f0aab15122db6..fbad9eabeabd239cade75658426d12f2ea1bf426 100644 (file)
@@ -140,7 +140,7 @@ struct snd_wait {
 
 #define DEFINE_TIMER(name, proc) \
   static struct timer_list name = \
-  {NULL, 0, 0, proc}
+  {NULL, NULL, 0, 0, proc}
 
 /*
  * The ACTIVATE_TIMER requests system to call 'proc' after 'time' ticks.
index b34778b769d7c91a4153b39ddf91400820c0722a..e6c3dbe8aecd320657a9cf76e223638867fd892f 100644 (file)
@@ -363,11 +363,9 @@ repeat:
        /*
         * First, test whether the goal block is free.
         */
-       i = ((goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb));
-       if (i >= EXT2_BLOCKS_PER_GROUP(sb) || i < 0) {
-               i = 0;
+       if (goal < es->s_first_data_block || goal >= es->s_blocks_count)
                goal = es->s_first_data_block;
-       }
+       i = (goal - es->s_first_data_block) / EXT2_BLOCKS_PER_GROUP(sb);
        gdp = get_group_desc (sb, i, &bh2);
        if (gdp->bg_free_blocks_count > 0) {
                j = ((goal - es->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(sb));
index d5a47b2a920f0e5c679cebd7636d1dce4b3067b0..960fae9bc8a02a80a8d636f456c4e93d587949f2 100644 (file)
@@ -653,15 +653,13 @@ repeat:
                retval = -ENOTDIR;
                goto end_rmdir;
        }
-       if (!empty_dir (inode)) {
+       down(&inode->i_sem);
+       if (!empty_dir (inode))
                retval = -ENOTEMPTY;
-               goto end_rmdir;
-       }
-       if (de->inode != inode->i_ino) {
+       else if (de->inode != inode->i_ino)
                retval = -ENOENT;
-               goto end_rmdir;
-       }
-       if (inode->i_count > 1) {
+       else {
+               if (inode->i_count > 1) {
                /*
                 * Are we deleting the last instance of a busy directory?
                 * Better clean up if so.
@@ -669,9 +667,11 @@ repeat:
                 * Make directory empty (it will be truncated when finally
                 * dereferenced).  This also inhibits ext2_add_entry.
                 */
-               inode->i_size = 0;
+                       inode->i_size = 0;
+               }
+               retval = ext2_delete_entry (de, bh);
        }
-       retval = ext2_delete_entry (de, bh);
+       up(&inode->i_sem);
        if (retval)
                goto end_rmdir;
        bh->b_dirt = 1;
index 0bd09f2cf4a61c7617321115bd64ffb30ea2751b..9498f5a25965aec4b241ba739e34e9f4cfbcbd23 100644 (file)
@@ -124,7 +124,7 @@ typedef void nonconst;
 static void hpfs_read_inode(struct inode *);
 static void hpfs_put_super(struct super_block *);
 static void hpfs_statfs(struct super_block *, struct statfs *);
-static int hpfs_remount_fs(struct super_block *, int *);
+static int hpfs_remount_fs(struct super_block *, int *, char *);
 
 static const struct super_operations hpfs_sops =
 {
@@ -752,7 +752,7 @@ static void hpfs_statfs(struct super_block *s, struct statfs *buf)
  * remount.  Don't let read only be turned off.
  */
 
-static int hpfs_remount_fs(struct super_block *s, int *flags)
+static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
 {
        if (!(*flags & MS_RDONLY))
                return -EINVAL;
index 0db43c984112fc3b33f60bdda4a6c22fbf485979..b95e9c957dd2949d833bc1f6355b30e211c19403 100644 (file)
@@ -384,6 +384,7 @@ repeat:
        clear_inode(inode);
        inode->i_count = 1;
        inode->i_nlink = 1;
+       inode->i_sem.count = 1;
        nr_free_inodes--;
        if (nr_free_inodes < 0) {
                printk ("VFS: get_empty_inode: bad free inode count.\n");
index 92736274b1921c2925ce78a03ff5404025ecbe20..03ff84baca0aef577c663d34803cbdd767989d37 100644 (file)
@@ -275,7 +275,7 @@ int open_namei(const char * pathname, int flag, int mode,
        struct inode ** res_inode, struct inode * base)
 {
        const char * basename;
-       int namelen,error,i;
+       int namelen,error;
        struct inode * dir, *inode;
        struct task_struct ** p;
 
@@ -297,43 +297,35 @@ int open_namei(const char * pathname, int flag, int mode,
                *res_inode=dir;
                return 0;
        }
-       for (i = 0; i < 5; i++) {       /* races... */
-               dir->i_count++;         /* lookup eats the dir */
+       dir->i_count++;         /* lookup eats the dir */
+       if (flag & O_CREAT) {
+               down(&dir->i_sem);
                error = lookup(dir,basename,namelen,&inode);
-               if (!error)
-                       break;
-               if (!(flag & O_CREAT)) {
-                       iput(dir);
-                       return error;
-               }
-               if (!permission(dir,MAY_WRITE | MAY_EXEC)) {
-                       iput(dir);
-                       return -EACCES;
-               }
-               if (!dir->i_op || !dir->i_op->create) {
-                       iput(dir);
-                       return -EACCES;
-               }
-               if (IS_RDONLY(dir)) {
-                       iput(dir);
-                       return -EROFS;
-               }
-               dir->i_count++;         /* create eats the dir */
-               error = dir->i_op->create(dir,basename,namelen,mode,res_inode);
-               if (error != -EEXIST) {
+               if (!error) {
+                       if (flag & O_EXCL) {
+                               iput(inode);
+                               error = -EEXIST;
+                       }
+               } else if (!permission(dir,MAY_WRITE | MAY_EXEC))
+                       error = -EACCES;
+               else if (!dir->i_op || !dir->i_op->create)
+                       error = -EACCES;
+               else if (IS_RDONLY(dir))
+                       error = -EROFS;
+               else {
+                       dir->i_count++;         /* create eats the dir */
+                       error = dir->i_op->create(dir,basename,namelen,mode,res_inode);
+                       up(&dir->i_sem);
                        iput(dir);
                        return error;
                }
-       }
+               up(&dir->i_sem);
+       } else
+               error = lookup(dir,basename,namelen,&inode);
        if (error) {
                iput(dir);
                return error;
        }
-       if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
-               iput(dir);
-               iput(inode);
-               return -EEXIST;
-       }
        error = follow_link(dir,inode,flag,mode,&inode);
        if (error)
                return error;
@@ -415,7 +407,10 @@ int do_mknod(const char * filename, int mode, dev_t dev)
                iput(dir);
                return -EPERM;
        }
-       return dir->i_op->mknod(dir,basename,namelen,mode,dev);
+       down(&dir->i_sem);
+       error = dir->i_op->mknod(dir,basename,namelen,mode,dev);
+       up(&dir->i_sem);
+       return error;
 }
 
 asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
@@ -467,7 +462,10 @@ static int do_mkdir(const char * pathname, int mode)
                iput(dir);
                return -EPERM;
        }
-       return dir->i_op->mkdir(dir,basename,namelen,mode);
+       down(&dir->i_sem);
+       error = dir->i_op->mkdir(dir,basename,namelen,mode);
+       up(&dir->i_sem);
+       return error;
 }
 
 asmlinkage int sys_mkdir(const char * pathname, int mode)
@@ -590,7 +588,10 @@ static int do_symlink(const char * oldname, const char * newname)
                iput(dir);
                return -EPERM;
        }
-       return dir->i_op->symlink(dir,basename,namelen,oldname);
+       down(&dir->i_sem);
+       error = dir->i_op->symlink(dir,basename,namelen,oldname);
+       up(&dir->i_sem);
+       return error;
 }
 
 asmlinkage int sys_symlink(const char * oldname, const char * newname)
@@ -646,7 +647,10 @@ static int do_link(struct inode * oldinode, const char * newname)
                iput(oldinode);
                return -EPERM;
        }
-       return dir->i_op->link(oldinode, dir, basename, namelen);
+       down(&dir->i_sem);
+       error = dir->i_op->link(oldinode, dir, basename, namelen);
+       up(&dir->i_sem);
+       return error;
 }
 
 asmlinkage int sys_link(const char * oldname, const char * newname)
@@ -719,8 +723,11 @@ static int do_rename(const char * oldname, const char * newname)
                iput(new_dir);
                return -EPERM;
        }
-       return old_dir->i_op->rename(old_dir, old_base, old_len, 
+       down(&new_dir->i_sem);
+       error = old_dir->i_op->rename(old_dir, old_base, old_len, 
                new_dir, new_base, new_len);
+       up(&new_dir->i_sem);
+       return error;
 }
 
 asmlinkage int sys_rename(const char * oldname, const char * newname)
index 2605d7f35175af1342297fee95ed8584ff8b204e..1a4f2c26aaba3712a6c16e5ac19ec58fcbede505 100644 (file)
@@ -441,7 +441,7 @@ static int get_maps(int pid, char *buf)
        return sz;
 }
 
-asmlinkage int get_module_list( char *);
+extern int get_module_list(char *);
 
 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
 {
index 41b4f2916b56378e529ebcf9b3bc2a6a58c08411..4a18616be853315d8002d1e189891b20103b2ee8 100644 (file)
@@ -89,7 +89,7 @@ extern __inline__ int clear_bit(int nr, int * addr)
        addr += nr >> 5;
        mask = 1 << (nr & 0x1f);
        cli();
-       retval = (mask & *addr) == 0;
+       retval = (mask & *addr) != 0;
        *addr &= ~mask;
        sti();
        return retval;
index eaf22afd4240ab777b9511bc570cb8d77c416fd3..be397d6b1989050e144932f9aae7ad9d173fb648 100644 (file)
@@ -171,6 +171,7 @@ struct inode {
        time_t          i_ctime;
        unsigned long   i_blksize;
        unsigned long   i_blocks;
+       struct semaphore i_sem;
        struct inode_operations * i_op;
        struct super_block * i_sb;
        struct wait_queue * i_wait;
index 6eeee460f50fc35691fdd989491dd6168f4d171a..68d533099a7b634e67a7e7ee9cc36103401b88b3 100644 (file)
@@ -21,7 +21,7 @@
 /* IEEE 802.3 Ethernet magic constants. */
 #define ETH_ALEN       6               /* #bytes in eth addr           */
 #define ETH_HLEN       14              /* #bytes in eth header         */
-#define ETH_ZLEN       64              /* min #bytes in frame          */
+#define ETH_ZLEN       60              /* min #bytes in frame          */
 #define ETH_FLEN       1536            /* max #bytes in frame          */
 #define ETH_DLEN       (ETH_FLEN - ETH_HLEN)   /* max #bytes of data   */
 
index 6326a10b8b0d8685d4314fc4ddaa57fd28168e11..eb0ca2ef2e510e58ab4c862a9e5d6c4c05c0e657 100644 (file)
 #include <linux/if.h>
 
 
+/* This structure gets passed by the SIOCADDRTOLD and SIOCDELRTOLD calls. */
+struct old_rtentry {
+       unsigned long   rt_genmask;
+       struct sockaddr rt_dst;
+       struct sockaddr rt_gateway;
+       short           rt_flags;
+       short           rt_refcnt;
+       unsigned long   rt_use;
+       char            *rt_dev; 
+};
+
 /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
 struct rtentry {
-  unsigned long                rt_hash;        /* hash key for lookups         */
-#define rt_genmask rt_hash
-  struct sockaddr      rt_dst;
-  struct sockaddr      rt_gateway;
-  short                        rt_flags;
-  short                        rt_refcnt;
-  unsigned long                rt_use;
-#ifdef BSD_COMPATIBLE
-  struct ifnet         *rt_ifp;
-#else
-  void                 *rt_dev; 
-#endif
+       unsigned long   rt_hash;        /* hash key for lookups         */
+       struct sockaddr rt_dst;         /* target address               */
+       struct sockaddr rt_gateway;     /* gateway addr (RTF_GATEWAY)   */
+       struct sockaddr rt_genmask;     /* target network mask (IP)     */
+       short           rt_flags;
+       short           rt_refcnt;
+       unsigned long   rt_use;
+       struct ifnet    *rt_ifp;
+       short           rt_metric;      /* +1 for binary compatibility! */
+       char            *rt_dev;        /* forcing the device at add    */
 };
+
+
 #define        RTF_UP          0x0001          /* route useable                */
 #define        RTF_GATEWAY     0x0002          /* destination is a gateway     */
 #define        RTF_HOST        0x0004          /* host entry (net otherwise)   */
index 6ee77bf7a37a7f47beb9c38f877b14098f5f67fe..932d26c57dc4e38fbd891d5c97245e4a67825e4c 100644 (file)
@@ -479,6 +479,21 @@ extern inline void select_wait(struct wait_queue ** wait_address, select_table *
        p->nr++;
 }
 
+extern void __down(struct semaphore * sem);
+
+extern inline void down(struct semaphore * sem)
+{
+       if (sem->count <= 0)
+               __down(sem);
+       sem->count--;
+}
+
+extern inline void up(struct semaphore * sem)
+{
+       sem->count++;
+       wake_up(&sem->wait);
+}      
+
 static inline unsigned long _get_base(char * addr)
 {
        unsigned long __base;
index 2090c33c93317c11de0a4aa57b183432addfdf28..ed5aeed3bee1a5621f130c548afdf1657f9414cb 100644 (file)
@@ -39,6 +39,10 @@ struct ip_config {
 #define SIOCGPGRP      0x8904
 #define SIOCATMARK     0x8905
 
+/* Routing table calls. */
+#define SIOCADDRT      0x890B          /* add routing table entry      */
+#define SIOCDELRT      0x890C          /* delete routing table entry   */
+
 /* Socket configuration controls. */
 #define SIOCGIFNAME    0x8910          /* get iface name               */
 #define SIOCSIFLINK    0x8911          /* set iface channel            */
@@ -64,9 +68,9 @@ struct ip_config {
 #define SIOCGIFENCAP   0x8925          /* get/set slip encapsulation   */
 #define SIOCSIFENCAP   0x8926          
 
-/* Routing table calls. */
-#define SIOCADDRT      0x8940          /* add routing table entry      */
-#define SIOCDELRT      0x8941          /* delete routing table entry   */
+/* Routing table calls (oldrtent - don't use) */
+#define SIOCADDRTOLD   0x8940          /* add routing table entry      */
+#define SIOCDELRTOLD   0x8941          /* delete routing table entry   */
 
 /* ARP cache control calls. */
 #define SIOCDARP       0x8950          /* delete ARP table entry       */
index ad23e32d60c0fdeb03cb78c208a56b50733c889c..448bc2a1fdcbef68ae4f9e2f5a5c5f13342d2495 100644 (file)
@@ -75,6 +75,7 @@ extern struct timer_struct timer_table[32];
  */
 struct timer_list {
        struct timer_list *next;
+       struct timer_list *prev;
        unsigned long expires;
        unsigned long data;
        void (*function)(unsigned long);
index 92fb67dc61ac48831b1d5ba58ea60bacf2afafd4..3af5609ec2bef904081bea9738465d50abe6fe47 100644 (file)
@@ -11,6 +11,13 @@ struct wait_queue {
        struct wait_queue * next;
 };
 
+struct semaphore {
+       int count;
+       struct wait_queue * wait;
+};
+
+#define MUTEX ((struct semaphore) { 1, NULL })
+
 struct select_table_entry {
        struct wait_queue wait;
        struct wait_queue ** wait_address;
index 567584b17e6c5bbda33fc7a185bc90527132baa9..c4146a4cde09f78387e96cbfbb5a7d811728fdc3 100644 (file)
@@ -131,6 +131,8 @@ static void xd_wd_init_controller (u_char *address);
 static void xd_wd_init_drive (u_char drive);
 static void xd_seagate_init_controller (u_char *address);
 static void xd_seagate_init_drive (u_char drive);
+static void xd_omti_init_controller (u_char *address);
+static void xd_omti_init_drive (u_char drive);
 static void xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc);
 static void xd_override_init_drive (u_char drive);
 
index 2e38de595c0d29a9b73d54cdbd7a576508e793d6..789ca4a2e49cee2b9ec3b968907781eb23e9aca4 100644 (file)
@@ -233,8 +233,7 @@ free_modules( void)
 /*
  * Called by the /proc file system to return a current list of modules.
  */
-int
-get_module_list( char *buf)
+int get_module_list(char *buf)
 {
        char *p;
        char *q;
index 43c648953ebececae64567da899bcd2fc6b5b3d2..a9f52cea6e09e21c1c198d0e2b707ff5ae1cbd1c 100644 (file)
@@ -361,6 +361,19 @@ void wake_up_interruptible(struct wait_queue **q)
        } while (tmp != *q);
 }
 
+void __down(struct semaphore * sem)
+{
+       struct wait_queue wait = { current, NULL };
+       add_wait_queue(&sem->wait, &wait);
+       current->state = TASK_UNINTERRUPTIBLE;
+       while (sem->count <= 0) {
+               schedule();
+               current->state = TASK_UNINTERRUPTIBLE;
+       }
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&sem->wait, &wait);
+}
+
 static inline void __sleep_on(struct wait_queue **p, int state)
 {
        unsigned long flags;
index a284eea757a56b3ab578fd7c6ec2675316fdcacd..db3df6d497e0fb498edb606f339996b27a8650d1 100644 (file)
@@ -211,30 +211,34 @@ asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
  */
 asmlinkage int sys_sigreturn(unsigned long __unused)
 {
-#define CHECK_SEG(x) if (x) x |= 3
 #define COPY(x) regs->x = context.x
+#define COPY_SEG(x) \
+if ((context.x & 0xfffc) && (context.x & 3) != 3) goto badframe; COPY(x);
+#define COPY_SEG_STRICT(x) \
+if (!(context.x & 0xfffc) || (context.x & 3) != 3) goto badframe; COPY(x);
        struct sigcontext_struct context;
        struct pt_regs * regs;
 
        regs = (struct pt_regs *) &__unused;
+       if (verify_area(VERIFY_READ, (void *) regs->esp, sizeof(context)))
+               goto badframe;
        memcpy_fromfs(&context,(void *) regs->esp, sizeof(context));
        current->blocked = context.oldmask & _BLOCKABLE;
-       CHECK_SEG(context.ss);
-       CHECK_SEG(context.cs);
-       CHECK_SEG(context.ds);
-       CHECK_SEG(context.es);
-       CHECK_SEG(context.fs);
-       CHECK_SEG(context.gs);
+       COPY_SEG(ds);
+       COPY_SEG(es);
+       COPY_SEG(fs);
+       COPY_SEG(gs);
+       COPY_SEG_STRICT(ss);
+       COPY_SEG_STRICT(cs);
        COPY(eip); COPY(eflags);
        COPY(ecx); COPY(edx);
        COPY(ebx);
        COPY(esp); COPY(ebp);
        COPY(edi); COPY(esi);
-       COPY(cs); COPY(ss);
-       COPY(ds); COPY(es);
-       COPY(fs); COPY(gs);
        regs->orig_eax = -1;            /* disable syscall checks */
        return context.eax;
+badframe:
+       do_exit(SIGSEGV);
 }
 
 /*
index 78ca139c20ed79b4579e81f52ffe5b6de3622071..e0145cc806c7ca388dd9d1fe7975573172a24d0b 100644 (file)
@@ -89,7 +89,7 @@ asmlinkage void alignment_check(void);
        printk("EIP:    %04x:%08lx\nEFLAGS: %08lx\n", 0xffff & regs->cs,regs->eip,regs->eflags);
        printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
                regs->eax, regs->ebx, regs->ecx, regs->edx);
-       printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08x\n",
+       printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
                regs->esi, regs->edi, regs->ebp, regs->esp);
        printk("ds: %04x   es: %04x   fs: %04x   gs: %04x\n",
                regs->ds, regs->es, regs->fs, regs->gs);
@@ -98,9 +98,11 @@ asmlinkage void alignment_check(void);
        for(i=0;i<20;i++)
                printk("%02x ",0xff & get_seg_byte(regs->cs,(i+(char *)regs->eip)));
        printk("\n");
+#if 0
        for(i=0;i<5;i++)
-               printk("%08x ", get_seg_long(regs->ss,(i+(unsigned long *)regs->esp)));
+               printk("%08lx ", get_seg_long(regs->ss,(i+(unsigned long *)regs->esp)));
        printk("\n");
+#endif
        do_exit(SIGSEGV);
 }
 
index 71384af13e423e810197b3aa00cddb03bef397cc..7b1540f02873c7c4b460536d1672f69f89d0a74b 100644 (file)
@@ -39,6 +39,7 @@
  *             Dominik Kubla   :       Better checking
  *             Tegge           :       Assorted corrections on cross port stuff
  *             Alan Cox        :       ATF_PERM was backwards! - might be useful now (sigh)
+ *             Alan Cox        :       Arp timer added.
  *
  * To Fix:
  *                             :       arp response allocates an skbuff to send. However there is a perfectly
@@ -60,6 +61,7 @@
 #include <linux/config.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
 #include <linux/in.h>
@@ -250,6 +252,28 @@ arp_send_q(void)
 }
 
 
+static struct timer_list arp_timer;
+
+static void arp_queue_ticker(unsigned long data);
+
+static void arp_queue_kick(void)
+{
+       arp_timer.expires = 500;        /* 5 seconds */
+       arp_timer.data = 0;
+       arp_timer.function = arp_queue_ticker;
+       del_timer(&arp_timer);
+       add_timer(&arp_timer);
+}
+
+static void arp_queue_ticker(unsigned long data/*UNUSED*/)
+{
+       arp_send_q();
+       if (skb_peek(&arp_q))
+               arp_queue_kick();
+}
+
+
+
 /* Create and send our response to an ARP request. */
 static int
 arp_response(struct arphdr *arp1, struct device *dev,  int addrtype)
@@ -753,6 +777,8 @@ arp_queue(struct sk_buff *skb)
        printk("ARP: arp_queue skb already on queue magic=%X.\n", skb->magic);
        return;
   }
+  if(arp_q==NULL)
+       arp_queue_kick();
   skb_queue_tail(&arp_q,skb);
   skb->magic = ARP_QUEUE_MAGIC;
   sti();
index 7d0687eedc6d4d6e199e5ad881566dc9ee9571f5..0101fd8431bb27428a020f15f01f26c40ba95c09 100644 (file)
@@ -186,7 +186,7 @@ int datagram_select(struct sock *sk, int sel_type, select_table *wait)
                        return(0);
 
                case SEL_OUT:
-                       if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
+                       if (sk->prot && sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
                        {
                                return(1);
                        }
index 9624d5aa90a9e1ea084bd23e8670a6bfb14c1202..5a67bd76c7c1de63b2c9eb6bd46a78a9f66d7df6 100644 (file)
@@ -253,17 +253,33 @@ static inline int bad_mask(unsigned long mask, unsigned long addr)
 
 static int rt_new(struct rtentry *r)
 {
-       struct device *dev;
+       int err;
+       char * devname;
+       struct device * dev = NULL;
        unsigned long flags, daddr, mask, gw;
 
+       if ((devname = r->rt_dev) != NULL) {
+               err = getname(devname, &devname);
+               if (err)
+                       return err;
+               dev = dev_get(devname);
+               putname(devname);
+               if (!dev)
+                       return -EINVAL;
+       }
+
        if (r->rt_dst.sa_family != AF_INET)
                return -EAFNOSUPPORT;
 
        flags = r->rt_flags;
        daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
-       mask = r->rt_genmask;
+       mask = ((struct sockaddr_in *) &r->rt_genmask)->sin_addr.s_addr;
        gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;
-       dev = (struct device *) r->rt_dev;
+
+       if (flags & RTF_HOST)
+               mask = 0xffffffff;
+       else if (r->rt_genmask.sa_family != AF_INET)
+               return -EAFNOSUPPORT;
 
        if (flags & RTF_GATEWAY) {
                if (r->rt_gateway.sa_family != AF_INET)
@@ -343,19 +359,41 @@ no_route:
        return NULL;
 }
 
+static int get_old_rtent(struct old_rtentry * src, struct rtentry * rt)
+{
+       int err;
+       struct old_rtentry tmp;
+
+       err=verify_area(VERIFY_READ, src, sizeof(*src));
+       if (err)
+               return err;
+       memcpy_fromfs(&tmp, src, sizeof(*src));
+       memset(rt, 0, sizeof(*rt));
+       rt->rt_dst = tmp.rt_dst;
+       rt->rt_gateway = tmp.rt_gateway;
+       rt->rt_genmask.sa_family = AF_INET;
+       ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = tmp.rt_genmask;
+       rt->rt_flags = tmp.rt_flags;
+       rt->rt_dev = tmp.rt_dev;
+       return 0;
+}
 
 int rt_ioctl(unsigned int cmd, void *arg)
 {
-       struct device *dev;
-       struct rtentry rt;
-       char *devname;
-       int ret;
        int err;
+       struct rtentry rt;
 
        switch(cmd) {
        case DDIOCSDBG:
-               ret = dbg_ioctl(arg, DBG_RT);
-               break;
+               return dbg_ioctl(arg, DBG_RT);
+       case SIOCADDRTOLD:
+       case SIOCDELRTOLD:
+               if (!suser())
+                       return -EPERM;
+               err = get_old_rtent((struct old_rtentry *) arg, &rt);
+               if (err)
+                       return err;
+               return (cmd == SIOCDELRTOLD) ? rt_kill(&rt) : rt_new(&rt);
        case SIOCADDRT:
        case SIOCDELRT:
                if (!suser())
@@ -364,21 +402,8 @@ int rt_ioctl(unsigned int cmd, void *arg)
                if (err)
                        return err;
                memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
-               if ((devname = (char *) rt.rt_dev) != NULL) {
-                       err = getname(devname, &devname);
-                       if (err)
-                               return err;
-                       dev = dev_get(devname);
-                       putname(devname);
-                       if (!dev)
-                               return -EINVAL;
-                       rt.rt_dev = dev;
-               }
-               ret = (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
-               break;
-       default:
-               ret = -EINVAL;
+               return (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
        }
 
-       return ret;
+       return -EINVAL;
 }
index 3de12e38f29064166a2c4c1efc9a440b393a7f58..c9370719c8192c4365c834b16323a5a2405819b2 100644 (file)
@@ -1531,8 +1531,8 @@ inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        case DDIOCSDBG:
                return(dbg_ioctl((void *) arg, DBG_INET));
 
-       case SIOCADDRT:
-       case SIOCDELRT:
+       case SIOCADDRT: case SIOCADDRTOLD:
+       case SIOCDELRT: case SIOCDELRTOLD:
                return(rt_ioctl(cmd,(void *) arg));
 
        case SIOCDARP:
@@ -1595,7 +1595,7 @@ sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
 {
   if (sk) {
        if (sk->rmem_alloc + size < sk->rcvbuf || force) {
-               void *c = alloc_skb(size, priority);
+               struct sk_buff *c = alloc_skb(size, priority);
                cli();
                if (c) sk->rmem_alloc += size;
                sti();