aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1994-02-13 17:08:57 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:32 -0400
commitd9cc76127bcc137e3214b9166c439e02d2060cda (patch)
tree8825a01f3f8cdd036e4bb9737236e898ca5eef2e
parent252058a6e7d838d1cab9512f6240f9e6b5b8b751 (diff)
downloadarchive-d9cc76127bcc137e3214b9166c439e02d2060cda.tar.gz
ALPHA-pl15c
-rw-r--r--Makefile2
-rw-r--r--drivers/block/floppy.c18
-rw-r--r--drivers/block/xd.c29
-rw-r--r--drivers/char/keyboard.c6
-rw-r--r--drivers/char/tty_ioctl.c3
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/net/3c509.c2
-rw-r--r--drivers/scsi/scsi.c7
-rw-r--r--drivers/sound/os.h2
-rw-r--r--fs/ext2/balloc.c6
-rw-r--r--fs/ext2/namei.c18
-rw-r--r--fs/hpfs/hpfs_fs.c4
-rw-r--r--fs/inode.c1
-rw-r--r--fs/namei.c77
-rw-r--r--fs/proc/array.c2
-rw-r--r--include/asm/bitops.h2
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/if_ether.h2
-rw-r--r--include/linux/route.h35
-rw-r--r--include/linux/sched.h15
-rw-r--r--include/linux/sockios.h10
-rw-r--r--include/linux/timer.h1
-rw-r--r--include/linux/wait.h7
-rw-r--r--include/linux/xd.h2
-rw-r--r--kernel/module.c3
-rw-r--r--kernel/sched.c13
-rw-r--r--kernel/signal.c24
-rw-r--r--kernel/traps.c6
-rw-r--r--net/inet/arp.c26
-rw-r--r--net/inet/datagram.c2
-rw-r--r--net/inet/route.c73
-rw-r--r--net/inet/sock.c6
32 files changed, 282 insertions, 125 deletions
diff --git a/Makefile b/Makefile
index 47407f6..5c71b86 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
diff --git a/fs/inode.c b/fs/inode.c
index 0db43c9..b95e9c9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -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");
diff --git a/fs/namei.c b/fs/namei.c
index 9273627..03ff84b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -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();