diff options
author | Linus Torvalds <torvalds@cc.helsinki.fi> | 1994-02-13 17:08:57 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:32 -0400 |
commit | d9cc76127bcc137e3214b9166c439e02d2060cda (patch) | |
tree | 8825a01f3f8cdd036e4bb9737236e898ca5eef2e | |
parent | 252058a6e7d838d1cab9512f6240f9e6b5b8b751 (diff) | |
download | archive-d9cc76127bcc137e3214b9166c439e02d2060cda.tar.gz |
ALPHA-pl15c
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | drivers/block/floppy.c | 18 | ||||
-rw-r--r-- | drivers/block/xd.c | 29 | ||||
-rw-r--r-- | drivers/char/keyboard.c | 6 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 3 | ||||
-rw-r--r-- | drivers/char/vt.c | 2 | ||||
-rw-r--r-- | drivers/net/3c509.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 7 | ||||
-rw-r--r-- | drivers/sound/os.h | 2 | ||||
-rw-r--r-- | fs/ext2/balloc.c | 6 | ||||
-rw-r--r-- | fs/ext2/namei.c | 18 | ||||
-rw-r--r-- | fs/hpfs/hpfs_fs.c | 4 | ||||
-rw-r--r-- | fs/inode.c | 1 | ||||
-rw-r--r-- | fs/namei.c | 77 | ||||
-rw-r--r-- | fs/proc/array.c | 2 | ||||
-rw-r--r-- | include/asm/bitops.h | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 1 | ||||
-rw-r--r-- | include/linux/if_ether.h | 2 | ||||
-rw-r--r-- | include/linux/route.h | 35 | ||||
-rw-r--r-- | include/linux/sched.h | 15 | ||||
-rw-r--r-- | include/linux/sockios.h | 10 | ||||
-rw-r--r-- | include/linux/timer.h | 1 | ||||
-rw-r--r-- | include/linux/wait.h | 7 | ||||
-rw-r--r-- | include/linux/xd.h | 2 | ||||
-rw-r--r-- | kernel/module.c | 3 | ||||
-rw-r--r-- | kernel/sched.c | 13 | ||||
-rw-r--r-- | kernel/signal.c | 24 | ||||
-rw-r--r-- | kernel/traps.c | 6 | ||||
-rw-r--r-- | net/inet/arp.c | 26 | ||||
-rw-r--r-- | net/inet/datagram.c | 2 | ||||
-rw-r--r-- | net/inet/route.c | 73 | ||||
-rw-r--r-- | net/inet/sock.c | 6 |
32 files changed, 282 insertions, 125 deletions
@@ -1,6 +1,6 @@ VERSION = 0.99 PATCHLEVEL = 15 -ALPHA = b +ALPHA = c all: Version zImage diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index ff9b04a..84cf7e4 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -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) diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 07a4a42..ef8fa07 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -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) diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 9bad94d..4ef9f62 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -34,7 +34,11 @@ #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 diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index bb9474d..3895262 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -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; diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 2fb3731..07385b0 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -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); diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 7e18ce7..148d91b 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -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 diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 6025755..4eecd8b 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -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 && diff --git a/drivers/sound/os.h b/drivers/sound/os.h index bff4a43..fbad9ea 100644 --- a/drivers/sound/os.h +++ b/drivers/sound/os.h @@ -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. diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index b34778b..e6c3dbe 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -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)); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index d5a47b2..960fae9 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -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; diff --git a/fs/hpfs/hpfs_fs.c b/fs/hpfs/hpfs_fs.c index 0bd09f2..9498f5a 100644 --- a/fs/hpfs/hpfs_fs.c +++ b/fs/hpfs/hpfs_fs.c @@ -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; @@ -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"); @@ -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) diff --git a/fs/proc/array.c b/fs/proc/array.c index 2605d7f..1a4f2c2 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -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) { diff --git a/include/asm/bitops.h b/include/asm/bitops.h index 41b4f29..4a18616 100644 --- a/include/asm/bitops.h +++ b/include/asm/bitops.h @@ -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; diff --git a/include/linux/fs.h b/include/linux/fs.h index eaf22af..be397d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -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; diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 6eeee46..68d5330 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -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 */ diff --git a/include/linux/route.h b/include/linux/route.h index 6326a10..eb0ca2e 100644 --- a/include/linux/route.h +++ b/include/linux/route.h @@ -21,21 +21,32 @@ #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) */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 6ee77bf..932d26c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -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; diff --git a/include/linux/sockios.h b/include/linux/sockios.h index 2090c33..ed5aeed 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -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 */ diff --git a/include/linux/timer.h b/include/linux/timer.h index ad23e32..448bc2a 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -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); diff --git a/include/linux/wait.h b/include/linux/wait.h index 92fb67d..3af5609 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -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; diff --git a/include/linux/xd.h b/include/linux/xd.h index 567584b..c4146a4 100644 --- a/include/linux/xd.h +++ b/include/linux/xd.h @@ -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); diff --git a/kernel/module.c b/kernel/module.c index 2e38de5..789ca4a 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -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; diff --git a/kernel/sched.c b/kernel/sched.c index 43c6489..a9f52ce 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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; diff --git a/kernel/signal.c b/kernel/signal.c index a284eea..db3df6d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -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); } /* diff --git a/kernel/traps.c b/kernel/traps.c index 78ca139..e0145cc 100644 --- a/kernel/traps.c +++ b/kernel/traps.c @@ -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); } diff --git a/net/inet/arp.c b/net/inet/arp.c index 71384af..7b1540f 100644 --- a/net/inet/arp.c +++ b/net/inet/arp.c @@ -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(); diff --git a/net/inet/datagram.c b/net/inet/datagram.c index 7d0687e..0101fd8 100644 --- a/net/inet/datagram.c +++ b/net/inet/datagram.c @@ -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); } diff --git a/net/inet/route.c b/net/inet/route.c index 9624d5a..5a67bd7 100644 --- a/net/inet/route.c +++ b/net/inet/route.c @@ -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; } diff --git a/net/inet/sock.c b/net/inet/sock.c index 3de12e3..c937071 100644 --- a/net/inet/sock.c +++ b/net/inet/sock.c @@ -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(); |