All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Horton <pdh@colonel-panic.org>
To: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: pdh@colonel-panic.org, phorton@bitbox.co.uk, linux-mips@linux-mips.org
Subject: Re: missing flush_dcache_page call in 2.4 kernel
Date: Sun, 28 Mar 2004 14:04:00 +0100	[thread overview]
Message-ID: <20040328130400.GA28177@skeleton-jack> (raw)
In-Reply-To: <20040327.224952.74755860.anemo@mba.ocn.ne.jp>

On Sat, Mar 27, 2004 at 10:49:52PM +0900, Atsushi Nemoto wrote:
> 
> pdh> True. A proper fix would flush the relevant page after PIO
> pdh> transfers into the page cache / swap pages. Unfortunately this
> pdh> would require a hook in the generic kernel.
> 
> I found somewhat long discussions in linux-kernel ML.
> 
> Subject: [patch] cache flush bug in mm/filemap.c (all kernels >= 2.5.30(at least))
> http://www.ussg.iu.edu/hypermail/linux/kernel/0305.2/1205.html
> http://www.ussg.iu.edu/hypermail/linux/kernel/0305.3/0151.html
> 
> Still I do not understand whole story on the thread, David S. Miller
> said that architecture defined IDE insw/outsw macro should do the
> flushing in this case, if I understand correctly.  Definitely sparc64
> __ide_insw do it.  Hmm ...
> 

I've ditched the original Cobalt hack in c-r4k.c, and am using the patch
below instead. Seems to work okay ...

P.

--- linux.cvs/include/asm-mips/io.h	Tue Feb 25 22:03:12 2003
+++ linux.pdh/include/asm-mips/io.h	Sun Mar 28 13:53:54 2004
@@ -400,35 +400,35 @@
 	}
 }
 
-static inline void __insb(unsigned long port, void *addr, unsigned int count)
+static inline void __outsw(unsigned long port, void *addr, unsigned int count)
 {
 	while (count--) {
-		*(u8 *)addr = inb(port);
-		addr++;
+		outw(*(u16 *)addr, port);
+		addr += 2;
 	}
 }
 
-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
+static inline void __outsl(unsigned long port, void *addr, unsigned int count)
 {
 	while (count--) {
-		outw(*(u16 *)addr, port);
-		addr += 2;
+		outl(*(u32 *)addr, port);
+		addr += 4;
 	}
 }
 
-static inline void __insw(unsigned long port, void *addr, unsigned int count)
+static inline void __insb(unsigned long port, void *addr, unsigned int count)
 {
 	while (count--) {
-		*(u16 *)addr = inw(port);
-		addr += 2;
+		*(u8 *)addr = inb(port);
+		addr++;
 	}
 }
 
-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
+static inline void __insw(unsigned long port, void *addr, unsigned int count)
 {
 	while (count--) {
-		outl(*(u32 *)addr, port);
-		addr += 4;
+		*(u16 *)addr = inw(port);
+		addr += 2;
 	}
 }
 
@@ -440,12 +440,69 @@
 	}
 }
 
+/*
+ * String "in" operations which additionally write back & invalidate the
+ * data that's read into the D-cache to prevent unexpected aliases.
+ *
+ * We have no flush_data_cache_range(from, to) so we blast a whole page
+ * at a time.
+ */
+
+static inline void __insb_f(unsigned long port, void *addr, unsigned int count)
+{
+	u8 *ptr, *end;
+
+	ptr = addr;
+	end = ptr + count;
+
+	while (ptr < end)
+		*ptr++ = inb(port);
+
+	for (; addr < (void *) end; addr += PAGE_SIZE)
+		flush_data_cache_page((unsigned long) addr);
+}
+
+static inline void __insw_f(unsigned long port, void *addr, unsigned int count)
+{
+	u16 *ptr, *end;
+
+	ptr = addr;
+	end = ptr + count;
+
+	while (ptr < end)
+		*ptr++ = inw(port);
+
+	for (; addr < (void *) end; addr += PAGE_SIZE)
+		flush_data_cache_page((unsigned long) addr);
+}
+
+static inline void __insl_f(unsigned long port, void *addr, unsigned int count)
+{
+	u32 *ptr, *end;
+
+	ptr = addr;
+	end = ptr + count;
+
+	while (ptr < end)
+		*ptr++ = inl(port);
+
+	for (; addr < (void *) end; addr += PAGE_SIZE)
+		flush_data_cache_page((unsigned long) addr);
+}
+
 #define outsb(port, addr, count) __outsb(port, addr, count)
-#define insb(port, addr, count) __insb(port, addr, count)
 #define outsw(port, addr, count) __outsw(port, addr, count)
-#define insw(port, addr, count) __insw(port, addr, count)
 #define outsl(port, addr, count) __outsl(port, addr, count)
-#define insl(port, addr, count) __insl(port, addr, count)
+
+#ifdef CONFIG_MIPS_COBALT
+# define insb(port, addr, count) __insb_f(port, addr, count)
+# define insw(port, addr, count) __insw_f(port, addr, count)
+# define insl(port, addr, count) __insl_f(port, addr, count)
+#else
+# define insb(port, addr, count) __insb(port, addr, count)
+# define insw(port, addr, count) __insw(port, addr, count)
+# define insl(port, addr, count) __insl(port, addr, count)
+#endif
 
 /*
  * The caches on some architectures aren't dma-coherent and have need to

  reply	other threads:[~2004-03-28 14:04 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-25 13:42 missing flush_dcache_page call in 2.4 kernel Atsushi Nemoto
2004-03-25 14:33 ` Ralf Baechle
2004-03-25 14:50   ` Peter Horton
2004-03-26  3:22     ` Atsushi Nemoto
2004-03-26 18:43       ` Peter Horton
2004-03-26 19:27         ` Maciej W. Rozycki
2004-03-27 13:49         ` Atsushi Nemoto
2004-03-28 13:04           ` Peter Horton [this message]
2004-03-30  6:38             ` Atsushi Nemoto
2004-03-30  9:48               ` Peter Horton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040328130400.GA28177@skeleton-jack \
    --to=pdh@colonel-panic.org \
    --cc=anemo@mba.ocn.ne.jp \
    --cc=linux-mips@linux-mips.org \
    --cc=phorton@bitbox.co.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.