- pre6:2.4.0-test8pre6
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:38:38 +0000 (23 15:38 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:38:38 +0000 (23 15:38 -0500)
    - truncate - the never-ending story.  Makes me feel like a long
      Kurosawa movie.  But in this one the hero _will_ survive, or my
      name isn't Maxwell.
    - SCSI tape driver potential memory leak.
    - XMM FP handler bug fix: we really must not change the FP error
      mask on exceptions.  People care.

arch/i386/kernel/setup.c
arch/i386/kernel/traps.c
drivers/ide/via82cxxx.c
drivers/net/epic100.c
drivers/pcmcia/yenta.c
drivers/scsi/st.c
fs/buffer.c
fs/ext2/inode.c
include/asm-i386/bugs.h
include/linux/fs.h
kernel/ksyms.c

index e79572f..00e5c7b 100644 (file)
@@ -1650,6+1650,7 @@ int get_cpuinfo(char * buffer)
        int i, n;
 
        for (n = 0; n < NR_CPUS; n++, c++) {
+               int fpu_exception;
 #ifdef CONFIG_SMP
                if (!(cpu_online_map & (1<<n)))
                        continue;
@@ -1722,7+1723,9 @@ int get_cpuinfo(char * buffer)
                          (c->x86_capability & X86_FEATURE_SEP) &&
                          c->x86_model < 3 &&
                          c->x86_mask < 3;
-       
+
+               /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
+               fpu_exception = c->hard_math && (ignore_irq13 | (c->x86_capability & X86_FEATURE_FPU));
                p += sprintf(p, "fdiv_bug\t: %s\n"
                                "hlt_bug\t\t: %s\n"
                                "sep_bug\t\t: %s\n"
@@ -1739,7+1742,7 @@ int get_cpuinfo(char * buffer)
                             c->f00f_bug ? "yes" : "no",
                             c->coma_bug ? "yes" : "no",
                             c->hard_math ? "yes" : "no",
-                            (c->hard_math && ignore_irq13) ? "yes" : "no",
+                            fpu_exception ? "yes" : "no",
                             c->cpuid_level,
                             c->wp_works_ok ? "yes" : "no");
 
index 7bd8a04..2fae8b5 100644 (file)
@@ -641,7+641,6 @@ void simd_math_error(void *eip)
         */
        task = current;
        save_init_fpu(task);
-       load_mxcsr(0x1f80);
        task->thread.trap_no = 19;
        task->thread.error_code = 0;
        info.si_signo = SIGFPE;
index ef21c2c..3780750 100644 (file)
@@ -278,7+278,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
 
 #endif
 
-#define FIT(v,min,max) (((v)>(max)?(max):(v))<(min)?(min):(v))
+#define FIT(v,min,max) ((v)>(max)?(max):((v)<(min)?(min):(v)))
 #define ENOUGH(v,un) (((v)-1)/(un)+1)
 
 #ifdef DEBUG
index afa7538..bdf5a48 100644 (file)
@@ -199,7+199,8 @@ static struct epic_chip_info epic_chip_info[] __devinitdata = {
 static struct pci_device_id epic_pci_tbl[] __devinitdata = {
        { 0x10B8, 0x0005, 0x1092, 0x0AB4, 0, 0, SMSC_83C170_0 },
        { 0x10B8, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMSC_83C170 },
-       { 0x10B8, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMSC_83C175 },
+       { 0x10B8, 0x0006, PCI_ANY_ID, PCI_ANY_ID,
+         PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, SMSC_83C175 },
        { 0,}
 };
 MODULE_DEVICE_TABLE (pci, epic_pci_tbl);
@@ -401,6+402,12 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
 
        dev->base_addr = ioaddr;
        dev->irq = pdev->irq;
+
+       ep = dev->priv;
+       ep->pci_dev = pdev;
+       ep->chip_flags = ci->drv_flags;
+       spin_lock_init (&ep->lock);
+
        printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
                   dev->name, ci->name, ioaddr, dev->irq);
 
@@ -430,10+437,6 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
                                   i % 16 == 15 ? "\n" : "");
        }
 
-       ep = dev->priv;
-       ep->pci_dev = pdev;
-       ep->chip_flags = ci->drv_flags;
-
        /* Find the connected MII xcvrs.
           Doing this in open() would allow detecting external xcvrs later, but
           takes much time and no cards have external MII. */
@@ -486,11+489,13 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
 
        return 0;
 
+err_out_iounmap:
 #ifndef USE_IO_OPS
+       iounmap ((void*) ioaddr);
 err_out_free_mmio:
+#endif
        release_mem_region (pci_resource_start (pdev, 1),
                            pci_resource_len (pdev, 1));
-#endif
 err_out_free_pio:
        release_region (pci_resource_start (pdev, 0),
                        pci_resource_len (pdev, 0));
@@ -936,8+941,7 @@ static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        long ioaddr = dev->base_addr;
        int status, boguscnt = max_interrupt_work;
 
-       if (!spin_trylock(&ep->lock))
-               return;
+       spin_lock(&ep->lock);
 
        do {
                status = inl(ioaddr + INTSTAT);
index 4d3aa94..367bfc2 100644 (file)
@@ -438,7+438,7 @@ static unsigned int yenta_events(pci_socket_t *socket)
        u8 csc;
        u32 cb_event;
        unsigned int events;
-       
+
        /* Clear interrupt status for the event */
        cb_event = cb_readl(socket, CB_SOCKET_EVENT);
        cb_writel(socket, CB_SOCKET_EVENT, cb_event);
@@ -552,6+552,12 @@ static int yenta_socket_thread(void * data)
        daemonize();
        strcpy(current->comm, "CardBus Watcher");
 
+       if (request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->name, socket)) {
+               printk ("Yenta: unable to register irq %d\n", socket->cb_irq);
+               MOD_DEC_USE_COUNT;
+               return (1);
+       }
+
        /* Figure out what the dang thing can do for the PCMCIA layer... */
        yenta_get_socket_capabilities(socket, isa_interrupts);
        printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
@@ -808,8+814,7 @@ static int yenta_open(pci_socket_t *socket)
        /* Set up the bridge regions.. */
        yenta_allocate_resources(socket);
 
-       if (dev->irq && !request_irq(dev->irq, yenta_interrupt, SA_SHIRQ, dev->name, socket))
-               socket->cb_irq = dev->irq;
+       socket->cb_irq = dev->irq;
 
        /* Do we have special options for the device? */
        for (i = 0; i < NR_OVERRIDES; i++) {
index dd5d178..333f4a5 100644 (file)
@@ -3486,6+3486,8 @@ static int st_attach(Scsi_Device * SDp)
                if (tmp_da == NULL || tmp_ba == NULL) {
                        if (tmp_da != NULL)
                                kfree(tmp_da);
+                       if (tmp_ba != NULL)
+                               kfree(tmp_ba);
                        SDp->attached--;
                        write_unlock_irqrestore(&st_dev_arr_lock, flags);
                        printk(KERN_ERR "st: Can't extend device array.\n");
index 58083e2..b437678 100644 (file)
@@ -1518,9+1518,6 @@ static int __block_commit_write(struct inode *inode, struct page *page,
                        if (!buffer_uptodate(bh))
                                partial = 1;
                } else {
-                       /* This can happen for the truncate case */
-                       if (!buffer_mapped(bh))
-                               continue;
                        set_bit(BH_Uptodate, &bh->b_state);
                        if (!atomic_set_buffer_dirty(bh)) {
                                __mark_dirty(bh);
@@ -1724,31+1721,63 @@ int generic_commit_write(struct file *file, struct page *page,
        return 0;
 }
 
-int block_zero_page(struct address_space *mapping, loff_t from, unsigned length)
+int block_truncate_page(struct address_space *mapping, loff_t from, get_block_t *get_block)
 {
        unsigned long index = from >> PAGE_CACHE_SHIFT;
        unsigned offset = from & (PAGE_CACHE_SIZE-1);
+       unsigned blocksize, iblock, length, pos;
        struct inode *inode = (struct inode *)mapping->host;
        struct page *page;
+       struct buffer_head *bh;
        int err;
 
+       blocksize = inode->i_sb->s_blocksize;
+       length = offset & (blocksize - 1);
+
+       /* Block boundary? Nothing to do */
        if (!length)
                return 0;
 
-       page = read_cache_page(mapping, index,
-                               (filler_t *)mapping->a_ops->readpage, NULL);
+       length = blocksize - length;
+       iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+       
+       page = grab_cache_page(mapping, index);
        err = PTR_ERR(page);
        if (IS_ERR(page))
                goto out;
-       lock_page(page);
-       err = -EIO;
-       if (!Page_Uptodate(page))
-               goto unlock;
+
+       if (!page->buffers)
+               create_empty_buffers(page, inode, blocksize);
+
+       /* Find the buffer that contains "offset" */
+       bh = page->buffers;
+       pos = blocksize;
+       while (offset >= pos) {
+               bh = bh->b_this_page;
+               iblock++;
+               pos += blocksize;
+       }
+
+       if (!buffer_uptodate(bh)) {
+               err = 0;
+               if (!buffer_mapped(bh)) {
+                       get_block(inode, iblock, bh, 0);
+                       if (!buffer_mapped(bh))
+                               goto unlock;
+               }
+               err = -EIO;
+               bh->b_end_io = end_buffer_io_sync;
+               ll_rw_block(READ, 1, &bh);
+               wait_on_buffer(bh);
+               if (!buffer_uptodate(bh))
+                       goto unlock;
+       }
 
        memset((char *) kmap(page) + offset, 0, length);
        flush_dcache_page(page);
-       __block_commit_write(inode, page, offset, offset+length);
        kunmap(page);
+
+       mark_buffer_dirty(bh);
        err = 0;
 
 unlock:
index 720597b..0f3fec6 100644 (file)
@@ -874,7+874,7 @@ void ext2_truncate (struct inode * inode)
        int nr = 0;
        int n;
        long iblock;
-       unsigned blocksize, tail;
+       unsigned blocksize;
 
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
            S_ISLNK(inode->i_mode)))
@@ -887,9+887,8 @@ void ext2_truncate (struct inode * inode)
        blocksize = inode->i_sb->s_blocksize;
        iblock = (inode->i_size + blocksize-1)
                                        >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
-       tail = (iblock << EXT2_BLOCK_SIZE_BITS(inode->i_sb)) - inode->i_size;
 
-       block_zero_page(inode->i_mapping, inode->i_size, tail);
+       block_truncate_page(inode->i_mapping, inode->i_size, ext2_get_block);
 
        n = ext2_block_to_path(inode, iblock, offsets);
        if (n == 0)
index 0ec21d9..008a3d4 100644 (file)
@@ -50,32+50,22 @@ static int __init no_387(char *s)
 
 __setup("no387", no_387);
 
-static char __initdata fpu_error = 0;
-
-static struct timer_list copro_timer __initdata = {{0, 0}, 0};
-
-static void __init copro_timeout(unsigned long dummy)
-{
-       fpu_error = 1;
-       mod_timer(&copro_timer, jiffies+HZ);
-       printk(KERN_ERR "387 failed: trying to reset\n");
-       send_sig(SIGFPE, current, 1);
-       outb_p(0,0xf1);
-       outb_p(0,0xf0);
-}
-
 static double __initdata x = 4195835.0;
 static double __initdata y = 3145727.0;
 
-#ifdef CONFIG_X86_XMM
-static float __initdata zero[4] = { 0.0, 0.0, 0.0, 0.0 };
-static float __initdata one[4] = { 1.0, 1.0, 1.0, 1.0 };
-#endif
-
+/*
+ * This used to check for exceptions.. 
+ * However, it turns out that to support that,
+ * the XMM trap handlers basically had to
+ * be buggy. So let's have a correct XMM trap
+ * handler, and forget about printing out
+ * some status at boot.
+ *
+ * We should really only care about bugs here
+ * anyway. Not features.
+ */
 static void __init check_fpu(void)
 {
-       unsigned short control_word;
-
        if (!boot_cpu_data.hard_math) {
 #ifndef CONFIG_MATH_EMULATION
                printk(KERN_EMERG "No coprocessor found and no math emulation present.\n");
@@ -84,72+74,8 @@ static void __init check_fpu(void)
 #endif
                return;
        }
-       if (mca_pentium_flag) {
-               /* The IBM Model 95 machines with pentiums lock up on
-                * fpu test, so we avoid it. All pentiums have inbuilt
-                * FPU and thus should use exception 16. We still do
-                * the FDIV test, although I doubt there where ever any
-                * MCA boxes built with non-FDIV-bug cpus.
-                */
-               __asm__("fninit\n\t"
-                       "fldl %1\n\t"
-                       "fdivl %2\n\t"
-                       "fmull %2\n\t"
-                       "fldl %1\n\t"
-                       "fsubp %%st,%%st(1)\n\t"
-                       "fistpl %0\n\t"
-                       "fwait\n\t"
-                       "fninit"
-                       : "=m" (*&boot_cpu_data.fdiv_bug)
-                       : "m" (*&x), "m" (*&y));
-               printk("mca-pentium specified, avoiding FPU coupling test... ");
-               if (!boot_cpu_data.fdiv_bug)
-                       printk("??? No FDIV bug? Lucky you...\n");
-               else
-                       printk("detected FDIV bug though.\n");
-               return;
-       }
-       /*
-        * check if exception 16 works correctly.. This is truly evil
-        * code: it disables the high 8 interrupts to make sure that
-        * the irq13 doesn't happen. But as this will lead to a lockup
-        * if no exception16 arrives, it depends on the fact that the
-        * high 8 interrupts will be re-enabled by the next timer tick.
-        * So the irq13 will happen eventually, but the exception 16
-        * should get there first..
-        */
-       printk(KERN_INFO "Checking 386/387 coupling... ");
-       init_timer(&copro_timer);
-       copro_timer.function = copro_timeout;
-       mod_timer(&copro_timer, jiffies+HZ/2);
-       __asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
-       control_word &= 0xffc0;
-       __asm__("fldcw %0 ; fwait": :"m" (*&control_word));
-       outb_p(inb_p(0x21) | (1 << 2), 0x21);
-       __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
-       del_timer(&copro_timer);
-       if (fpu_error)
-               return;
-       if (!ignore_irq13) {
-               printk("OK, FPU using old IRQ 13 error reporting\n");
-               return;
-       }
-       __asm__("fninit\n\t"
-               "fldl %1\n\t"
-               "fdivl %2\n\t"
-               "fmull %2\n\t"
-               "fldl %1\n\t"
-               "fsubp %%st,%%st(1)\n\t"
-               "fistpl %0\n\t"
-               "fwait\n\t"
-               "fninit"
-               : "=m" (*&boot_cpu_data.fdiv_bug)
-               : "m" (*&x), "m" (*&y));
-       if (!boot_cpu_data.fdiv_bug)
-               printk("OK, FPU using exception 16 error reporting.\n");
-       else
-               printk("Hmm, FPU using exception 16 error reporting with FDIV bug.\n");
 
+/* Enable FXSR and company _before_ testing for FP problems. */
 #if defined(CONFIG_X86_FXSR) || defined(CONFIG_X86_RUNTIME_FXSR)
        /*
         * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
@@ -168,18+94,24 @@ static void __init check_fpu(void)
                printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
                set_in_cr4(X86_CR4_OSXMMEXCPT);
                printk("done.\n");
-
-               /* Check if exception 19 works okay. */
-               load_mxcsr(0x0000);
-               printk(KERN_INFO "Checking SIMD FPU exceptions... ");
-               __asm__("movups %0,%%xmm0\n\t"
-                       "movups %1,%%xmm1\n\t"
-                       "divps %%xmm0,%%xmm1\n\t"
-                       : : "m" (*&zero), "m" (*&one));
-               printk("OK, SIMD FPU using exception 19 error reporting.\n");
                load_mxcsr(0x1f80);
        }
 #endif
+
+       /* Test for the divl bug.. */
+       __asm__("fninit\n\t"
+               "fldl %1\n\t"
+               "fdivl %2\n\t"
+               "fmull %2\n\t"
+               "fldl %1\n\t"
+               "fsubp %%st,%%st(1)\n\t"
+               "fistpl %0\n\t"
+               "fwait\n\t"
+               "fninit"
+               : "=m" (*&boot_cpu_data.fdiv_bug)
+               : "m" (*&x), "m" (*&y));
+       if (boot_cpu_data.fdiv_bug)
+               printk("Hmm, FPU with FDIV bug.\n");
 }
 
 static void __init check_hlt(void)
index c0157ad..a759d8a 100644 (file)
@@ -1173,7+1173,7 @@ extern int block_sync_page(struct page *);
 
 int generic_block_bmap(struct address_space *, long, get_block_t *);
 int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
-int block_zero_page(struct address_space *, loff_t, unsigned);
+int block_truncate_page(struct address_space *, loff_t, get_block_t *);
 
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
index 7d7290c..78527a7 100644 (file)
@@ -203,7+203,7 @@ EXPORT_SYMBOL(block_prepare_write);
 EXPORT_SYMBOL(block_sync_page);
 EXPORT_SYMBOL(cont_prepare_write);
 EXPORT_SYMBOL(generic_commit_write);
-EXPORT_SYMBOL(block_zero_page);
+EXPORT_SYMBOL(block_truncate_page);
 EXPORT_SYMBOL(generic_block_bmap);
 EXPORT_SYMBOL(generic_file_read);
 EXPORT_SYMBOL(do_generic_file_read);
close