linux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: linux

To: linux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: linux
From: ralf@linux-mips.org
Date: Tue, 19 Apr 2005 13:26:58 +0100
Reply-to: linux-mips@linux-mips.org
Sender: linux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    linux
Changes by:     ralf@ftp.linux-mips.org 05/04/19 13:26:53

Modified files:
        include/asm-mips: Tag: linux_2_4 ide.h 
        include/asm-mips64: Tag: linux_2_4 ide.h 

Log message:
        Fix D-cache aliasing problem in the PIO IDE driver potencially resulting
        in the kernel or userspace seeing stale data.

diff -urN linux/include/asm-mips/ide.h linux/include/asm-mips/ide.h
--- linux/include/asm-mips/ide.h        2003/07/15 15:08:33     1.11.2.7
+++ linux/include/asm-mips/ide.h        2005/04/19 12:26:53     1.11.2.8
@@ -32,12 +32,12 @@
 
 extern struct ide_ops *ide_ops;
 
-static __inline__ int ide_default_irq(ide_ioreg_t base)
+static inline int ide_default_irq(ide_ioreg_t base)
 {
        return ide_ops->ide_default_irq(base);
 }
 
-static __inline__ ide_ioreg_t ide_default_io_base(int index)
+static inline ide_ioreg_t ide_default_io_base(int index)
 {
        return ide_ops->ide_default_io_base(index);
 }
@@ -48,7 +48,7 @@
        ide_ops->ide_init_hwif_ports(hw, data_port, ctrl_port, irq);
 }
 
-static __inline__ void ide_init_default_hwifs(void)
+static inline void ide_init_default_hwifs(void)
 {
 #ifndef CONFIG_BLK_DEV_IDEPCI
        hw_regs_t hw;
@@ -68,7 +68,89 @@
 #define ide_ack_intr(hwif)     ((hwif)->hw.ack_intr ? 
(hwif)->hw.ack_intr(hwif) : 1)
 #endif
 
-#include <asm-generic/ide_iops.h>
+/* MIPS port and memory-mapped I/O string operations.  */
+
+static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long 
size)
+{
+       if (cpu_has_dc_aliases) {
+               unsigned long end = addr + size;
+               for (; addr < end; addr += PAGE_SIZE)
+                       flush_dcache_page(virt_to_page(addr));
+       }
+}
+
+static inline void __ide_insw(unsigned long port, void *addr,
+       unsigned int count)
+{
+       insw(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, unsigned int 
count)
+{
+       insl(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_outsw(unsigned long port, const void *addr,
+       unsigned long count)
+{
+       outsw(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_outsl(unsigned long port, const void *addr,
+       unsigned long count)
+{
+       outsl(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_insw(unsigned long port, void *addr, u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               *(u16 *)addr = readw(port);
+               addr += 2;
+       }
+       __ide_flush_dcache_range(start, count * 2);
+}
+
+static inline void __ide_mm_insl(unsigned long port, void *addr, u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               *(u32 *)addr = readl(port);
+               addr += 4;
+       }
+       __ide_flush_dcache_range(start, count * 4);
+}
+
+static inline void __ide_mm_outsw(unsigned long port, const void *addr,
+       u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               writew(*(u16 *)addr, port);
+               addr += 2;
+       }
+       __ide_flush_dcache_range(start, count * 2);
+}
+
+static inline void __ide_mm_outsl(unsigned long port, const void *addr,
+       u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               writel(*(u32 *)addr, port);
+               addr += 4;
+       }
+       __ide_flush_dcache_range(start, count * 4);
+}
 
 #endif /* __KERNEL__ */
 
diff -urN linux/include/asm-mips64/ide.h linux/include/asm-mips64/ide.h
--- linux/include/asm-mips64/Attic/ide.h        2003/07/15 15:08:33     1.6.2.6
+++ linux/include/asm-mips64/Attic/ide.h        2005/04/19 12:26:53     1.6.2.7
@@ -32,12 +32,12 @@
 
 extern struct ide_ops *ide_ops;
 
-static __inline__ int ide_default_irq(ide_ioreg_t base)
+static inline int ide_default_irq(ide_ioreg_t base)
 {
        return ide_ops->ide_default_irq(base);
 }
 
-static __inline__ ide_ioreg_t ide_default_io_base(int index)
+static inline ide_ioreg_t ide_default_io_base(int index)
 {
        return ide_ops->ide_default_io_base(index);
 }
@@ -48,7 +48,7 @@
        ide_ops->ide_init_hwif_ports(hw, data_port, ctrl_port, irq);
 }
 
-static __inline__ void ide_init_default_hwifs(void)
+static inline void ide_init_default_hwifs(void)
 {
 #ifndef CONFIG_BLK_DEV_IDEPCI
        hw_regs_t hw;
@@ -68,7 +68,89 @@
 #define ide_ack_intr(hwif)    ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) 
: 1)
 #endif
 
-#include <asm-generic/ide_iops.h>
+/* MIPS port and memory-mapped I/O string operations.  */
+
+static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long 
size)
+{
+       if (cpu_has_dc_aliases) {
+               unsigned long end = addr + size;
+               for (; addr < end; addr += PAGE_SIZE)
+                       flush_dcache_page(virt_to_page(addr));
+       }
+}
+
+static inline void __ide_insw(unsigned long port, void *addr,
+       unsigned int count)
+{
+       insw(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_insl(unsigned long port, void *addr, unsigned int 
count)
+{
+       insl(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_outsw(unsigned long port, const void *addr,
+       unsigned long count)
+{
+       outsw(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 2);
+}
+
+static inline void __ide_outsl(unsigned long port, const void *addr,
+       unsigned long count)
+{
+       outsl(port, addr, count);
+       __ide_flush_dcache_range((unsigned long)addr, count * 4);
+}
+
+static inline void __ide_mm_insw(unsigned long port, void *addr, u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               *(u16 *)addr = readw(port);
+               addr += 2;
+       }
+       __ide_flush_dcache_range(start, count * 2);
+}
+
+static inline void __ide_mm_insl(unsigned long port, void *addr, u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               *(u32 *)addr = readl(port);
+               addr += 4;
+       }
+       __ide_flush_dcache_range(start, count * 4);
+}
+
+static inline void __ide_mm_outsw(unsigned long port, const void *addr,
+       u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               writew(*(u16 *)addr, port);
+               addr += 2;
+       }
+       __ide_flush_dcache_range(start, count * 2);
+}
+
+static inline void __ide_mm_outsl(unsigned long port, const void *addr,
+       u32 count)
+{
+       unsigned long start = (unsigned long) addr;
+
+       while (count--) {
+               writel(*(u32 *)addr, port);
+               addr += 4;
+       }
+       __ide_flush_dcache_range(start, count * 4);
+}
 
 #endif /* __KERNEL__ */
 

<Prev in Thread] Current Thread [Next in Thread>