From cd534a05124545055065589c15b2043d38300c18 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:25 -0500 Subject: [PATCH] Import 1.0.6 --- Makefile | 2 +- drivers/block/blk.h | 5 ++++- drivers/net/3c509.c | 11 +++++++---- drivers/scsi/wd7000.c | 24 ++++++++++++++++++++---- fs/ext2/file.c | 6 ++---- fs/ext2/truncate.c | 2 ++ fs/proc/array.c | 31 ++++++++++++++++++++++--------- include/linux/sched.h | 2 ++ include/linux/sockios.h | 2 +- kernel/exit.c | 4 ++++ kernel/sched.c | 4 ++++ mm/kmalloc.c | 1 - mm/swap.c | 1 - net/inet/skbuff.c | 1 - net/inet/sock.c | 1 + 15 files changed, 70 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 14791b6a6b92..b91716ee1cfe 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 0 -SUBLEVEL = 5 +SUBLEVEL = 6 all: Version zImage diff --git a/drivers/block/blk.h b/drivers/block/blk.h index faa5adfc527f..bf4531ada450 100644 --- a/drivers/block/blk.h +++ b/drivers/block/blk.h @@ -42,9 +42,12 @@ struct request { * This is used in the elevator algorithm: Note that * reads always go before writes. This is natural: reads * are much more time-critical than writes. + * + * Update: trying with writes being preferred due to test + * by Alessandro Rubini.. */ #define IN_ORDER(s1,s2) \ -((s1)->cmd < (s2)->cmd || ((s1)->cmd == (s2)->cmd && \ +((s1)->cmd > (s2)->cmd || ((s1)->cmd == (s2)->cmd && \ ((s1)->dev < (s2)->dev || (((s1)->dev == (s2)->dev && \ (s1)->sector < (s2)->sector))))) diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index e41276452a3e..1a907367c161 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -95,17 +95,20 @@ int el3_probe(struct device *dev) /* First check for a board on the EISA bus. */ if (EISA_bus) { for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { - if (inw(ioaddr) != 0x6d50) + /* Check the standard EISA ID register for an encoded '3Com'. */ + if (inw(ioaddr + 0xC80) != 0x6d50) continue; + /* Change the register set to the configuration window 0. */ + outw(0x0800, ioaddr + 0xC80 + EL3_CMD); + irq = inw(ioaddr + 8) >> 12; if_port = inw(ioaddr + 6)>>14; for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); - /* Restore the "Manufacturer ID" to the EEPROM read register. */ - /* The manual says to restore "Product ID" (reg. 3). !???! */ - read_eeprom(ioaddr, 7); + /* Restore the "Product ID" to the EEPROM read register. */ + read_eeprom(ioaddr, 3); /* Was the EISA code an add-on hack? Nahhhhh... */ goto found; diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index b64f56fed303..0bc67ae3bdf5 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -120,13 +120,27 @@ static inline void delay( unsigned how_long ) static inline int command_out(unchar *cmdp, int len) { + if(len == 1) { + while(1==1){ + WAIT(ASC_STAT, STATMASK, CMD_RDY, 0); + cli(); + if(!(inb(ASC_STAT) & CMD_RDY)) {sti(); continue;} + outb(*cmdp, COMMAND); + sti(); + return 1; + } + } else { + cli(); while (len--) { - WAIT(ASC_STAT, STATMASK, CMD_RDY, 0); - outb(*cmdp++, COMMAND); + WAIT(ASC_STAT, STATMASK, CMD_RDY, 0); + outb(*cmdp++, COMMAND); } + sti(); + } return 1; fail: + sti(); printk("wd7000_out WAIT failed(%d): ", len+1); return 0; } @@ -189,6 +203,7 @@ static int mail_out( Scb *scbptr ) */ { int i, ogmb; + unsigned char start_cmd; unsigned long flags; DEB(printk("wd7000_scb_out: %06x");) @@ -217,10 +232,11 @@ static int mail_out( Scb *scbptr ) return 0; } + start_cmd = START_OGMB | ogmb; + wd7000_enable_intr(); do { - WAIT(ASC_STAT,STATMASK,CMD_RDY,0); - outb(START_OGMB|ogmb, COMMAND); + command_out(&start_cmd, 1); WAIT(ASC_STAT,STATMASK,CMD_RDY,0); } while (inb(ASC_STAT) & CMD_REJ); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 4f7fa7b4b5da..7251a40e05c0 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -241,10 +241,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp, inode->i_mode); return -EINVAL; } -/* - * ok, append may not work when many processes are writing at the same time - * but so what. That way leads to madness anyway. - */ + down(&inode->i_sem); if (filp->f_flags & O_APPEND) pos = inode->i_size; else @@ -283,6 +280,7 @@ static int ext2_file_write (struct inode * inode, struct file * filp, bh->b_dirt = 1; brelse (bh); } + up(&inode->i_sem); inode->i_ctime = inode->i_mtime = CURRENT_TIME; filp->f_pos = pos; inode->i_dirt = 1; diff --git a/fs/ext2/truncate.c b/fs/ext2/truncate.c index b36598a58064..95db1ed4a8a8 100644 --- a/fs/ext2/truncate.c +++ b/fs/ext2/truncate.c @@ -335,6 +335,7 @@ void ext2_truncate (struct inode * inode) return; ext2_discard_prealloc(inode); while (1) { + down(&inode->i_sem); retry = trunc_direct(inode); retry |= trunc_indirect (inode, EXT2_IND_BLOCK, (unsigned long *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); @@ -342,6 +343,7 @@ void ext2_truncate (struct inode * inode) EXT2_ADDR_PER_BLOCK(inode->i_sb), (unsigned long *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); retry |= trunc_tindirect (inode); + up(&inode->i_sem); if (!retry) break; if (IS_SYNC(inode) && inode->i_dirt) diff --git a/fs/proc/array.c b/fs/proc/array.c index 028ec2296a69..fca6f07ebf97 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -4,7 +4,15 @@ * Copyright (C) 1992 by Linus Torvalds * based on ideas by Darren Senn * - * stat,statm extensions by Michael K. Johnson, johnsonm@stolaf.edu + * Fixes: + * Michael. K. Johnson: stat,statm extensions. + * + * + * Pauline Middelink : Made cmdline,envline only break at '\0's, to + * make sure SET_PROCTITLE works. Also removed + * bad '!' which forced addres recalculation for + * EVERY character on the current page. + * */ #include @@ -98,7 +106,7 @@ static int get_kstat(char * buffer) "disk %u %u %u %u\n" "page %u %u\n" "swap %u %u\n" - "%u", + "intr %u", kstat.cpu_user, kstat.cpu_nice, kstat.cpu_system, @@ -177,12 +185,12 @@ static unsigned long get_phys_addr(struct task_struct ** p, unsigned long ptr) if (!p || !*p || ptr >= TASK_SIZE) return 0; page = *PAGE_DIR_OFFSET((*p)->tss.cr3,ptr); - if (!(page & 1)) + if (!(page & PAGE_PRESENT)) return 0; page &= PAGE_MASK; page += PAGE_PTR(ptr); page = *(unsigned long *) page; - if (!(page & 1)) + if (!(page & PAGE_PRESENT)) return 0; page &= PAGE_MASK; page += ptr & ~PAGE_MASK; @@ -200,7 +208,7 @@ static int get_array(struct task_struct ** p, unsigned long start, unsigned long for (;;) { addr = get_phys_addr(p, start); if (!addr) - return result; + goto ready; do { c = *(char *) addr; if (!c) @@ -208,13 +216,18 @@ static int get_array(struct task_struct ** p, unsigned long start, unsigned long if (size < PAGE_SIZE) buffer[size++] = c; else - return result; + goto ready; addr++; start++; - if (start >= end) - return result; - } while (!(addr & ~PAGE_MASK)); + if (!c && start >= end) + goto ready; + } while (addr & ~PAGE_MASK); } +ready: + /* remove the trailing blanks, used to fillout argv,envp space */ + while (result>0 && buffer[result-1]==' ') + result--; + return result; } static int get_env(int pid, char * buffer) diff --git a/include/linux/sched.h b/include/linux/sched.h index 28343790de78..6828ada7f59d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -21,6 +21,8 @@ extern int x86; extern int ignore_irq13; extern int wp_works_ok; +extern unsigned long intr_count; + /* * Bus types (default is ISA, but people can check others with these..) * MCA_bus hardcoded to 0 for now. diff --git a/include/linux/sockios.h b/include/linux/sockios.h index ed5aeed3bee1..0e303a31dd98 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h @@ -28,7 +28,7 @@ struct ip_config { unsigned long paddr; unsigned long router; unsigned long net; - unsigned long up:1,destroy:1; + unsigned up:1,destroy:1; }; #endif /* FIXME: */ diff --git a/kernel/exit.c b/kernel/exit.c index d96504898761..08a098e0d1e7 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -355,6 +355,10 @@ NORET_TYPE void do_exit(long code) struct task_struct *p; int i; + if (intr_count) { + printk("Aiee, killing interrupt handler\n"); + intr_count = 0; + } fake_volatile: if (current->semun) sem_exit(); diff --git a/kernel/sched.c b/kernel/sched.c index 8eef62765a97..f383f894b6a5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -217,6 +217,10 @@ asmlinkage void schedule(void) /* check alarm, wake up any interruptible tasks that have got a signal */ + if (intr_count) { + printk("Aiee: scheduling in interrupt\n"); + intr_count = 0; + } cli(); ticks = itimer_ticks; itimer_ticks = 0; diff --git a/mm/kmalloc.c b/mm/kmalloc.c index b7a9b61c517b..dcfe17699bd0 100644 --- a/mm/kmalloc.c +++ b/mm/kmalloc.c @@ -151,7 +151,6 @@ void * kmalloc (size_t size, int priority) int order,tries,i,sz; struct block_header *p; struct page_descriptor *page; - extern unsigned long intr_count; /* Sanity check... */ if (intr_count && priority != GFP_ATOMIC) { diff --git a/mm/swap.c b/mm/swap.c index 1550cee911c1..a3c260f8adf9 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -585,7 +585,6 @@ last_free_pages[index = (index + 1) & (NR_LAST_FREE_PAGES - 1)] = result; \ */ unsigned long __get_free_page(int priority) { - extern unsigned long intr_count; unsigned long result, flag; static unsigned long index = 0; diff --git a/net/inet/skbuff.c b/net/inet/skbuff.c index 49b565b4a4ef..ba0795040de5 100644 --- a/net/inet/skbuff.c +++ b/net/inet/skbuff.c @@ -426,7 +426,6 @@ void kfree_skb(struct sk_buff *skb, int rw) struct sk_buff *alloc_skb(unsigned int size,int priority) { struct sk_buff *skb; - extern unsigned long intr_count; if (intr_count && priority != GFP_ATOMIC) { static int count = 0; diff --git a/net/inet/sock.c b/net/inet/sock.c index cc7e2f89d8a8..0b8ee3deee1d 100644 --- a/net/inet/sock.c +++ b/net/inet/sock.c @@ -1197,6 +1197,7 @@ inet_accept(struct socket *sock, struct socket *newsock, int flags) if (newsock->data) { struct sock * sk = (struct sock *) newsock->data; newsock->data = NULL; + sk->dead = 1; destroy_sock(sk); } -- 2.39.5