@@ -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");
@@ -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;
@@ -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
@@ -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);
@@ -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++) {
@@ -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");
@@ -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:
@@ -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)
@@ -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)
@@ -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 *);
@@ -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);