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__ */
|