diff options
author | Linus Torvalds <torvalds@cc.helsinki.fi> | 1994-02-07 14:58:39 +0000 |
---|---|---|
committer | Nicolas Pitre <nico@cam.org> | 2007-08-19 14:19:31 -0400 |
commit | d5a0671f4362f508274b5d32a5cdf222e8dae5ec (patch) | |
tree | 8151d96fcd458e2da336cfb18aac0f1512673f80 | |
parent | e2778b587aa9fb80b1ce6bf12ff05ab1f7520dde (diff) | |
download | archive-d5a0671f4362f508274b5d32a5cdf222e8dae5ec.tar.gz |
ALPHA-pl15a
[ Message-ID: <2jaihl$21l@klaava.Helsinki.FI> ]
- pl15a fixes the buffer cache growing problem, adds emulation for a
few unimportant floating point instructions (i287 instructions that
are No-Ops on the i387, so "emulating" them is easy :^) and fixes a
silly bug when mmap'ing stuff write-only. It also fixes a buggy lock
in the networking.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | drivers/FPU-emu/fpu_aux.c | 19 | ||||
-rw-r--r-- | drivers/char/console.c | 5 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 2 | ||||
-rw-r--r-- | fs/buffer.c | 29 | ||||
-rw-r--r-- | fs/ext2/inode.c | 5 | ||||
-rw-r--r-- | include/asm/io.h | 13 | ||||
-rw-r--r-- | init/main.c | 13 | ||||
-rw-r--r-- | mm/memory.c | 4 | ||||
-rw-r--r-- | mm/mmap.c | 4 | ||||
-rw-r--r-- | net/inet/dev.c | 102 | ||||
-rw-r--r-- | net/inet/ip.c | 1 | ||||
-rw-r--r-- | net/inet/ip.h | 1 | ||||
-rw-r--r-- | net/inet/raw.c | 2 | ||||
-rw-r--r-- | net/inet/tcp.h | 1 |
16 files changed, 117 insertions, 89 deletions
@@ -1,6 +1,6 @@ VERSION = 0.99 PATCHLEVEL = 15 -ALPHA = +ALPHA = a all: Version zImage diff --git a/drivers/FPU-emu/fpu_aux.c b/drivers/FPU-emu/fpu_aux.c index c1835d4..d9f3a22 100644 --- a/drivers/FPU-emu/fpu_aux.c +++ b/drivers/FPU-emu/fpu_aux.c @@ -17,6 +17,9 @@ #include "control_w.h" +static void fnop(void) +{ +} void fclex(void) { @@ -47,9 +50,16 @@ void finit() FPU_entry_eip = ip_offset = 0; } +/* + * These are nops on the i387.. + */ +#define feni fnop +#define fdisi fnop +#define fsetpm fnop + static FUNC const finit_table[] = { - Un_impl, Un_impl, fclex, finit, - Un_impl, FPU_illegal, FPU_illegal, FPU_illegal + feni, fdisi, fclex, finit, + fsetpm, FPU_illegal, FPU_illegal, FPU_illegal }; void finit_() @@ -75,11 +85,6 @@ void fstsw_() } - -static void fnop(void) -{ -} - static FUNC const fp_nop_table[] = { fnop, FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal diff --git a/drivers/char/console.c b/drivers/char/console.c index a228898..cfd1e0c 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -1800,12 +1800,11 @@ int paste_selection(struct tty_struct *tty) if (! *bp) return 0; unblank_screen(); - while (*bp) - { + while (*bp) { put_tty_queue(*bp, &tty->read_q); bp++; + TTY_READ_FLUSH(tty); } - TTY_READ_FLUSH(tty); return 0; } diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 1f4b50e..bb9474d 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -550,6 +550,9 @@ int tty_ioctl(struct inode * inode, struct file * file, return set_selection(arg); case 3: return paste_selection(tty); + case 4: + unblank_screen(); + return 0; #endif /* CONFIG_SELECTION */ default: return -EINVAL; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a2083b8..6025755 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -136,6 +136,8 @@ static struct blist blacklist[] = {"SEAGATE", "ST296","921"}, /* Responds to all lun */ {"SONY","CD-ROM CDU-541","4.3d"}, {"TANDBERG","TDC 3600","U07"}, /* Locks up if polled for lun != 0 */ + {"TEAC","CD-ROM","1.06"}, /* causes failed REQUEST SENSE on lun 1 for seagate + * controller, which causes SCSI code to reset bus.*/ {"TEXEL","CD-ROM","1.06"}, /* causes failed REQUEST SENSE on lun 1 for seagate * controller, which causes SCSI code to reset bus.*/ {NULL, NULL, NULL}}; diff --git a/fs/buffer.c b/fs/buffer.c index 1d00868..31c203d 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -956,7 +956,11 @@ int shrink_buffers(unsigned int priority) bh = free_list; i = nr_buffers >> priority; for ( ; i-- > 0 ; bh = bh->b_next_free) { - if (bh->b_count || !bh->b_this_page) + if (bh->b_count) { + put_last_free(bh); + continue; + } + if (!bh->b_this_page) continue; if (bh->b_lock) if (priority) @@ -975,6 +979,29 @@ int shrink_buffers(unsigned int priority) return 0; } +void show_buffers(void) +{ + struct buffer_head * bh; + int found = 0, locked = 0, dirty = 0, used = 0, lastused = 0; + + printk("Buffer memory: %6dkB\n",buffermem>>10); + printk("Buffer heads: %6d\n",nr_buffer_heads); + printk("Buffer blocks: %6d\n",nr_buffers); + bh = free_list; + do { + found++; + if (bh->b_lock) + locked++; + if (bh->b_dirt) + dirty++; + if (bh->b_count) + used++, lastused = found; + bh = bh->b_next_free; + } while (bh != free_list); + printk("Buffer mem: %d buffers, %d used (last=%d), %d locked, %d dirty\n", + found, used, lastused, locked, dirty); +} + /* * This initializes the initial buffer free list. nr_buffers is set * to one less the actual number of buffers, as a sop to backwards diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 3f0230e..050b0f2 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -69,10 +69,11 @@ void ext2_discard_prealloc (struct inode * inode) { #ifdef EXT2_PREALLOCATE if (inode->u.ext2_i.i_prealloc_count) { + int i = inode->u.ext2_i.i_prealloc_count; + inode->u.ext2_i.i_prealloc_count = 0; ext2_free_blocks (inode->i_sb, inode->u.ext2_i.i_prealloc_block, - inode->u.ext2_i.i_prealloc_count); - inode->u.ext2_i.i_prealloc_count = 0; + i); } #endif } diff --git a/include/asm/io.h b/include/asm/io.h index a2527c1..09c494c 100644 --- a/include/asm/io.h +++ b/include/asm/io.h @@ -2,6 +2,19 @@ #define _ASM_IO_H /* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* * Thanks to James van Artsdalen for a better timing-fix than * the two short jumps: using outb's to a nonexistent port seems * to guarantee better timings even on fast machines. diff --git a/init/main.c b/init/main.c index 41309a4..f86cf12 100644 --- a/init/main.c +++ b/init/main.c @@ -326,6 +326,17 @@ static void parse_options(char *line) envp_init[envs+1] = NULL; } +static void copy_options(char * to, char * from) +{ + char c = ' '; + + do { + if (c == ' ' && !memcmp("mem=", from, 4)) + memory_end = simple_strtoul(from+4, &from, 0); + c = *(to++) = *(from++); + } while (c); +} + static void copro_timeout(void) { fpu_error = 1; @@ -351,7 +362,7 @@ asmlinkage void start_kernel(void) memory_end = (1<<20) + (EXT_MEM_K<<10); memory_end &= PAGE_MASK; ramdisk_size = RAMDISK_SIZE; - strcpy(command_line,COMMAND_LINE); + copy_options(command_line,COMMAND_LINE); #ifdef CONFIG_MAX_16M if (memory_end > 16*1024*1024) memory_end = 16*1024*1024; diff --git a/mm/memory.c b/mm/memory.c index 57cee25..0168a8d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -981,9 +981,6 @@ void show_mem(void) printk("Free pages: %6dkB\n",nr_free_pages<<(PAGE_SHIFT-10)); printk("Secondary pages: %6dkB\n",nr_secondary_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - printk("Buffer memory: %6dkB\n",buffermem>>10); - printk("Buffer heads: %6d\n",nr_buffer_heads); - printk("Buffer blocks: %6d\n",nr_buffers); i = high_memory >> PAGE_SHIFT; while (i-- > 0) { total++; @@ -998,6 +995,7 @@ void show_mem(void) printk("%d free pages\n",free); printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); + show_buffers(); } /* @@ -113,9 +113,9 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len, mask |= PAGE_READONLY; if (prot & PROT_WRITE) if ((flags & MAP_TYPE) == MAP_PRIVATE) - mask |= PAGE_COW; + mask |= PAGE_COPY; else - mask |= PAGE_RW; + mask |= PAGE_SHARED; if (!mask) return -EINVAL; diff --git a/net/inet/dev.c b/net/inet/dev.c index 22002f0..e5bc513 100644 --- a/net/inet/dev.c +++ b/net/inet/dev.c @@ -193,81 +193,49 @@ ip_addr_match(unsigned long me, unsigned long him) /* Check the address for our address, broadcasts, etc. */ -int -chk_addr(unsigned long addr) +int chk_addr(unsigned long addr) { - struct device *dev; - unsigned long dst; - - DPRINTF((DBG_DEV, "chk_addr(%s) --> ", in_ntoa(addr))); - dst = ntohl(addr); - - /* Accept both `all ones' and `all zeros' as BROADCAST. */ - if (dst == INADDR_ANY || dst == INADDR_BROADCAST) { - DPRINTF((DBG_DEV, "BROADCAST\n")); - return(IS_BROADCAST); - } + struct device *dev; + unsigned long mask; - /* Accept all of the `loopback' class A net. */ - if ((dst & IN_CLASSA_NET) == 0x7F000000L) { - DPRINTF((DBG_DEV, "LOOPBACK\n")); + /* Accept both `all ones' and `all zeros' as BROADCAST. */ + if (addr == INADDR_ANY || addr == INADDR_BROADCAST) + return IS_BROADCAST; - /* - * We force `loopback' to be equal to MY_ADDR. - */ - return(IS_MYADDR); - /* return(IS_LOOPBACK); */ - } + mask = get_mask(addr); - /* OK, now check the interface addresses. */ - for (dev = dev_base; dev != NULL; dev = dev->next) { - if (!(dev->flags&IFF_UP)) - continue; - if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/) - return(IS_MYADDR); - /* Is it the exact IP address? */ - if (addr == dev->pa_addr) { - DPRINTF((DBG_DEV, "MYADDR\n")); - return(IS_MYADDR); - } + /* Accept all of the `loopback' class A net. */ + if ((addr & mask) == htonl(0x7F000000L)) + return IS_MYADDR; - /* Nope. Check for a subnetwork broadcast. */ - if ((addr & dev->pa_mask) == (dev->pa_addr & dev->pa_mask)) { - if ((addr & ~dev->pa_mask) == 0) { - DPRINTF((DBG_DEV, "SUBBROADCAST-0\n")); - return(IS_BROADCAST); + /* OK, now check the interface addresses. */ + for (dev = dev_base; dev != NULL; dev = dev->next) { + if (!(dev->flags & IFF_UP)) + continue; + if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/) + return IS_MYADDR; + /* Is it the exact IP address? */ + if (addr == dev->pa_addr) + return IS_MYADDR; + /* Is it our broadcast address? */ + if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr) + return IS_BROADCAST; + /* Nope. Check for a subnetwork broadcast. */ + if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) { + if ((addr & ~dev->pa_mask) == 0) + return IS_BROADCAST; + if ((addr & ~dev->pa_mask) == ~dev->pa_mask) + return IS_BROADCAST; } - if (((addr & ~dev->pa_mask) | dev->pa_mask) - == INADDR_BROADCAST) { - DPRINTF((DBG_DEV, "SUBBROADCAST-1\n")); - return(IS_BROADCAST); + /* Nope. Check for Network broadcast. */ + if (((addr ^ dev->pa_addr) & mask) == 0) { + if ((addr & ~mask) == 0) + return IS_BROADCAST; + if ((addr & ~mask) == ~mask) + return IS_BROADCAST; } } - - /* Nope. Check for Network broadcast. */ - if(IN_CLASSA(dst)) { - if( addr == (dev->pa_addr | 0xffffff00)) { - DPRINTF((DBG_DEV, "CLASS A BROADCAST-1\n")); - return(IS_BROADCAST); - } - } - else if(IN_CLASSB(dst)) { - if( addr == (dev->pa_addr | 0xffff0000)) { - DPRINTF((DBG_DEV, "CLASS B BROADCAST-1\n")); - return(IS_BROADCAST); - } - } - else { /* IN_CLASSC */ - if( addr == (dev->pa_addr | 0xff000000)) { - DPRINTF((DBG_DEV, "CLASS C BROADCAST-1\n")); - return(IS_BROADCAST); - } - } - } - - DPRINTF((DBG_DEV, "NONE\n")); - - return(0); /* no match at all */ + return 0; /* no match at all */ } diff --git a/net/inet/ip.c b/net/inet/ip.c index fdef4c6..d95e4cd 100644 --- a/net/inet/ip.c +++ b/net/inet/ip.c @@ -764,7 +764,6 @@ static struct sk_buff *ip_glue(struct ipq *qp) skb->len = (len - qp->maclen); skb->h.raw = skb->data; skb->free = 1; - skb->lock = 1; /* Copy the original MAC and IP headers into the new buffer. */ ptr = (unsigned char *) skb->h.raw; diff --git a/net/inet/ip.h b/net/inet/ip.h index 7f2ecc0..31035bb 100644 --- a/net/inet/ip.h +++ b/net/inet/ip.h @@ -78,6 +78,7 @@ extern void ip_queue_xmit(struct sock *sk, struct device *dev, struct sk_buff *skb, int free); extern void ip_retransmit(struct sock *sk, int all); +extern void ip_do_retransmit(struct sock *sk, int all); extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen); diff --git a/net/inet/raw.c b/net/inet/raw.c index 91563d7..24f1da0 100644 --- a/net/inet/raw.c +++ b/net/inet/raw.c @@ -115,7 +115,7 @@ raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, /* Now we need to copy this into memory. */ skb->sk = sk; skb->len = len + skb->ip_hdr->ihl*sizeof(long); - skb->h.raw = skb->ip_hdr; + skb->h.raw = (unsigned char *) skb->ip_hdr; skb->dev = dev; skb->saddr = daddr; skb->daddr = saddr; diff --git a/net/inet/tcp.h b/net/inet/tcp.h index 007f3ee..e154d5e 100644 --- a/net/inet/tcp.h +++ b/net/inet/tcp.h @@ -124,6 +124,7 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev, extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); +extern void tcp_send_probe0(struct sock *sk); extern void tcp_enqueue_partial(struct sk_buff *, struct sock *); extern struct sk_buff * tcp_dequeue_partial(struct sock *); |