LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Benjamin Herrenschmidt @ 2008-07-06  0:31 UTC (permalink / raw)
  To: Grant Erickson; +Cc: linuxppc-dev, sr
In-Reply-To: <1215303343-26410-1-git-send-email-gerickson@nuovations.com>

On Sat, 2008-07-05 at 17:15 -0700, Grant Erickson wrote:
> +       union {
> +               /* Registers unique to EMAC4 implementations */
> +               struct {
> +                       u32 iaht1;      /* Reset, R     */
> +                       u32 iaht2;      /* Reset, R     */
> +                       u32 iaht3;      /* Reset, R     */
> +                       u32 iaht4;      /* Reset, R     */
> +                       u32 gaht1;      /* Reset, R     */
> +                       u32 gaht2;      /* Reset, R     */
> +                       u32 gaht3;      /* Reset, R     */
> +                       u32 gaht4;      /* Reset, R     */
> +                       u32 lsah;
> +                       u32 lsal;
> +                       u32 ipgvr;      /* Reset,    T  */
> +                       u32 stacr;      /* Special      */
> +                       u32 trtr;       /* Special      */
> +                       u32 rwmr;       /* Reset        */
> +                       u32 octx;
> +                       u32 ocrx;
> +                       u32 ipcr;
> +               };
> +               /* Registers unique to EMAC4SYNC implementations */
> +               struct {
> +                       u32 mahr;       /* Reset, R, T  */
> +                       u32 malr;       /* Reset, R, T  */
> +                       u32 mmahr;      /* Reset, R, T  */
> +                       u32 mmalr;      /* Reset, R, T  */
> +                       u32 rsvd0[4];
> +                       u32 lsah;
> +                       u32 lsal;
> +                       u32 ipgvr;      /* Reset, T     */
> +                       u32 stacr;
> +                       u32 trtr;
> +                       u32 rwmr;       /* Reset        */
> +                       u32 octx;
> +                       u32 ocrx;
> +                       u32 rsvd1;
> +                       u32 revid;
> +                       u32 rsvd2[2];
> +                       u32 iaht[8];    /* Reset, R     */
> +                       u32 gaht[8];    /* Reset, R     */
> +                       u32 tpc;        /* Reset, T     */
> +               };
> +       };

Getting there :-) I note that all your sub-structs are unnamed. How does
the compiler knows which one to use to get to, for example, "lsah" ?

Thanks for working on that btw !

Cheers,
Ben.

^ permalink raw reply

* Re: the printk problem
From: Ingo Molnar @ 2008-07-06  5:27 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, linuxppc-dev, Peter Anvin, Andrew Morton,
	Arjan van de Ven, David S. Miller, parisc-linux
In-Reply-To: <alpine.LFD.1.10.0807051523180.2847@woody.linux-foundation.org>


* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> > Still all happily untested, of course. And still with no actual 
> > users converted.
> 
> Ok, it's tested, and here's an example usage conversion.
> 
> The diffstat pretty much says it all. It _does_ change the format of 
> the stack trace entry a bit, but I don't think it's for the worse 
> (unless it breaks things like the oops tracker - Arjan?)
> 
> It changes the symbol-in-module format from
> 
> 	:ext3:add_dirent_to_buf+0x6c/0x26c
> 
> to
> 
> 	add_dirent_to_buf+0x6c/0x26c [ext3]
> 
> but quite frankly, the latter was the standard format anyway (it's 
> what "sprint_symbol()" gives you), and traps_64.c was the odd man out.
> 
> In fact, traps_32.c already uses the standard print_symbol() format, 
> so it really was an issue of the 64-bit code being odd (and I assume 
> that this also means that it cannot break the oops tracker, since it 
> already had to be able to handle both formats).
> 
> I also removed the KALLSYMS dependency, so if KALLSYMS isn't enabled 
> it will now give the same hex format twice, but I doubt we really care 
> (such stack traces are unreadable whether it shows up once or twice, 
> and the simplicity is worth it).
> 
> If people do just a few more conversions like this, then the 52 added 
> lines in lib/vsnprintf.c are more than made up for by removed lines 
> elsewhere (and more readable source code).

applied (with the commit message below) to tip/x86/debug for v2.6.27 
merging, thanks Linus. Can i add your SOB too?

	Ingo

-------------------->
commit 4afd2534d6d4a77f4b7497c92f1ff7528d8f4eaa
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat Jul 5 15:32:41 2008 -0700

    x86, 64-bit: standardize printk_address()
    
    Changes the symbol-in-module format from
    
    	:ext3:add_dirent_to_buf+0x6c/0x26c
    
    to
    
    	add_dirent_to_buf+0x6c/0x26c [ext3]
    
    the latter was the standard format anyway (it's what "sprint_symbol()"
    gives you), and traps_64.c was the odd man out.
    
    In fact, traps_32.c already uses the standard print_symbol() format, so
    it really was an issue of the 64-bit code being odd (and I assume that
    this also means that it cannot break the oops tracker, since it already
    had to be able to handle both formats).
    
    I also removed the KALLSYMS dependency, so if KALLSYMS isn't enabled it
    will now give the same hex format twice, but I doubt we really care
    (such stack traces are unreadable whether it shows up once or twice, and
    the simplicity is worth it).
    
    If people do just a few more conversions like this, then the 52 added
    lines in lib/vsnprintf.c are more than made up for by removed lines
    elsewhere (and more readable source code).
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index adff76e..f1a95d1 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -104,30 +104,7 @@ int kstack_depth_to_print = 12;
 
 void printk_address(unsigned long address, int reliable)
 {
-#ifdef CONFIG_KALLSYMS
-	unsigned long offset = 0, symsize;
-	const char *symname;
-	char *modname;
-	char *delim = ":";
-	char namebuf[KSYM_NAME_LEN];
-	char reliab[4] = "";
-
-	symname = kallsyms_lookup(address, &symsize, &offset,
-					&modname, namebuf);
-	if (!symname) {
-		printk(" [<%016lx>]\n", address);
-		return;
-	}
-	if (!reliable)
-		strcpy(reliab, "? ");
-
-	if (!modname)
-		modname = delim = "";
-	printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
-		address, reliab, delim, modname, delim, symname, offset, symsize);
-#else
-	printk(" [<%016lx>]\n", address);
-#endif
+	printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address);
 }
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,

^ permalink raw reply related

* Re: the printk problem
From: Linus Torvalds @ 2008-07-06  5:37 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-ia64, Linux Kernel Mailing List, linuxppc-dev, Peter Anvin,
	Andrew Morton, Arjan van de Ven, David S. Miller, parisc-linux
In-Reply-To: <20080706052741.GA18928@elte.hu>



On Sun, 6 Jul 2008, Ingo Molnar wrote:
> 
> applied (with the commit message below) to tip/x86/debug for v2.6.27 
> merging, thanks Linus. Can i add your SOB too?

Sure, add my S-O-B. But I hope/assuem that you also added my earlier patch 
that added the support for '%pS' too? I'm not entirely sure that should go 
in an x86-specific branch, since it has nothing x86-specific in it.

Also, I've cleaned up the lib/vsnprintf.c patch to fix up some minor 
details. For example, it should not default to a field width of 
"2*sizeof(unsigned long)" - it should do that only if it ends up printing 
the pointer as a hex number.

So this is my current version.. (the "precision" thing was moved into the 
'pointer()' function, and to after the special case handling).

		Linus
---
 lib/vsprintf.c |  118 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 85 insertions(+), 33 deletions(-)

diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 6021757..f60c7c0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -22,6 +22,8 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
 #include <asm/div64.h>
@@ -482,6 +484,82 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
 	return buf;
 }
 
+static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
+{
+	int len, i;
+
+	if ((unsigned long)s < PAGE_SIZE)
+		s = "<NULL>";
+
+	len = strnlen(s, precision);
+
+	if (!(flags & LEFT)) {
+		while (len < field_width--) {
+			if (buf < end)
+				*buf = ' ';
+			++buf;
+		}
+	}
+	for (i = 0; i < len; ++i) {
+		if (buf < end)
+			*buf = *s;
+		++buf; ++s;
+	}
+	while (len < field_width--) {
+		if (buf < end)
+			*buf = ' ';
+		++buf;
+	}
+	return buf;
+}
+
+static inline void *dereference_function_descriptor(void *ptr)
+{
+#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
+	void *p;
+	if (!probe_kernel_address(ptr, p))
+		ptr = p;
+#endif
+	return ptr;
+}
+
+
+/*
+ * Show a '%p' thing.  A kernel extension is that the '%p' is followed
+ * by an extra set of alphanumeric characters that are extended format
+ * specifiers.  Right now we just handle 'F' (for symbolic Function
+ * pointers) and 'S' (for Symbolic data pointers), but this can easily
+ * be extended in the future (network address types etc).
+ *
+ * The difference between 'S' and 'F' is that on ia64 and ppc64 function
+ * pointers are really function descriptors, which contain a pointer the
+ * real address. 
+ */
+static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int base, int size, int precision, int type)
+{
+	switch (*fmt) {
+	case 'F':
+		ptr = dereference_function_descriptor(ptr);
+		/* Fallthrough */
+	case 'S': {	/* Other (direct) pointer */
+#if CONFIG_KALLSYMS
+		char sym[KSYM_SYMBOL_LEN];
+		sprint_symbol(sym, (unsigned long) ptr);
+		return string(buf, end, sym, size, precision, type);
+#else
+		type |= SPECIAL;
+		break;
+#endif
+	}
+	}
+	type |= SMALL;
+	if (precision == -1) {
+		precision = 2*sizeof(void *);
+		type |= ZEROPAD;
+	}
+	return number(buf, end, (unsigned long long) ptr, base, size, precision, type);
+}
+
 /**
  * vsnprintf - Format a string and place it in a buffer
  * @buf: The buffer to place the result into
@@ -502,11 +580,9 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
  */
 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
-	int len;
 	unsigned long long num;
-	int i, base;
+	int base;
 	char *str, *end, c;
-	const char *s;
 
 	int flags;		/* flags to number() */
 
@@ -622,40 +698,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 				continue;
 
 			case 's':
-				s = va_arg(args, char *);
-				if ((unsigned long)s < PAGE_SIZE)
-					s = "<NULL>";
-
-				len = strnlen(s, precision);
-
-				if (!(flags & LEFT)) {
-					while (len < field_width--) {
-						if (str < end)
-							*str = ' ';
-						++str;
-					}
-				}
-				for (i = 0; i < len; ++i) {
-					if (str < end)
-						*str = *s;
-					++str; ++s;
-				}
-				while (len < field_width--) {
-					if (str < end)
-						*str = ' ';
-					++str;
-				}
+				str = string(str, end, va_arg(args, char *), field_width, precision, flags);
 				continue;
 
 			case 'p':
-				flags |= SMALL;
-				if (field_width == -1) {
-					field_width = 2*sizeof(void *);
-					flags |= ZEROPAD;
-				}
-				str = number(str, end,
-						(unsigned long) va_arg(args, void *),
+				str = pointer(fmt+1, str, end,
+						va_arg(args, void *),
 						16, field_width, precision, flags);
+				/* Skip all alphanumeric pointer suffixes */
+				while (isalnum(fmt[1]))
+					fmt++;
 				continue;
 
 

^ permalink raw reply related

* Re: the printk problem
From: Ingo Molnar @ 2008-07-06  5:53 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, Linux Kernel Mailing List, linuxppc-dev, Peter Anvin,
	Andrew Morton, Arjan van de Ven, David S. Miller, parisc-linux
In-Reply-To: <alpine.LFD.1.10.0807052232530.3016@woody.linux-foundation.org>


* Linus Torvalds <torvalds@linux-foundation.org> wrote:

> On Sun, 6 Jul 2008, Ingo Molnar wrote:
> > 
> > applied (with the commit message below) to tip/x86/debug for v2.6.27 
> > merging, thanks Linus. Can i add your SOB too?
> 
> Sure, add my S-O-B. But I hope/assuem that you also added my earlier 
> patch that added the support for '%pS' too? I'm not entirely sure that 
> should go in an x86-specific branch, since it has nothing x86-specific 
> in it.

yeah, agreed, combined it's not an x86 topic anymore.

[ There's some lkml trouble so i've missed the earlier patch. I'm not 
  sure the email problem is on my side, see how incomplete the 
  discussion is on lkml.org as well:

     http://lkml.org/lkml/2008/6/25/170   ]

Anyway, i have have added this second patch of yours to tip/core/printk 
and moved your first patch over to that topic (which relies on it).

That topic has a few other (smaller) printk enhancements queued for 
v2.6.27 already:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git core/printk

[find other stats below]

so it fits in naturally.

	Ingo

------------------>
Ingo Molnar (1):
      printk: export console_drivers

Jan Kiszka (1):
      printk: don't prefer unsuited consoles on registration

Jiri Slaby (1):
      x86, generic: mark early_printk as asmlinkage

Linus Torvalds (2):
      printk: add support for '%pS'
      x86, 64-bit: standardize printk_address()

Nick Andrew (2):
      printk: refactor processing of line severity tokens
      printk: remember the message level for multi-line output

Tejun Heo (1):
      printk: clean up recursion check related static variables

Thomas Gleixner (2):
      namespacecheck: fix kernel printk.c
      namespacecheck: more kernel/printk.c fixes

 arch/x86/kernel/early_printk.c |    2 +-
 arch/x86/kernel/traps_64.c     |   25 +--------
 include/linux/kernel.h         |    8 +---
 kernel/printk.c                |  107 +++++++++++++++---------------------
 lib/vsprintf.c                 |  118 +++++++++++++++++++++++++++++-----------
 5 files changed, 133 insertions(+), 127 deletions(-)

diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 643fd86..ff9e735 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -196,7 +196,7 @@ static struct console simnow_console = {
 static struct console *early_console = &early_vga_console;
 static int early_console_initialized;
 
-void early_printk(const char *fmt, ...)
+asmlinkage void early_printk(const char *fmt, ...)
 {
 	char buf[512];
 	int n;
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index adff76e..f1a95d1 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -104,30 +104,7 @@ int kstack_depth_to_print = 12;
 
 void printk_address(unsigned long address, int reliable)
 {
-#ifdef CONFIG_KALLSYMS
-	unsigned long offset = 0, symsize;
-	const char *symname;
-	char *modname;
-	char *delim = ":";
-	char namebuf[KSYM_NAME_LEN];
-	char reliab[4] = "";
-
-	symname = kallsyms_lookup(address, &symsize, &offset,
-					&modname, namebuf);
-	if (!symname) {
-		printk(" [<%016lx>]\n", address);
-		return;
-	}
-	if (!reliable)
-		strcpy(reliab, "? ");
-
-	if (!modname)
-		modname = delim = "";
-	printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
-		address, reliab, delim, modname, delim, symname, offset, symsize);
-#else
-	printk(" [<%016lx>]\n", address);
-#endif
+	printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address);
 }
 
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 792bf0a..4cb8d3d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -184,9 +184,6 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	__attribute__ ((format (printf, 1, 0)));
 asmlinkage int printk(const char * fmt, ...)
 	__attribute__ ((format (printf, 1, 2))) __cold;
-extern int log_buf_get_len(void);
-extern int log_buf_read(int idx);
-extern int log_buf_copy(char *dest, int idx, int len);
 
 extern int printk_ratelimit_jiffies;
 extern int printk_ratelimit_burst;
@@ -202,9 +199,6 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
 static inline int printk(const char *s, ...)
 	__attribute__ ((format (printf, 1, 2)));
 static inline int __cold printk(const char *s, ...) { return 0; }
-static inline int log_buf_get_len(void) { return 0; }
-static inline int log_buf_read(int idx) { return 0; }
-static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
 static inline int printk_ratelimit(void) { return 0; }
 static inline int __printk_ratelimit(int ratelimit_jiffies, \
 				     int ratelimit_burst) { return 0; }
@@ -213,7 +207,7 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
 		{ return false; }
 #endif
 
-extern void __attribute__((format(printf, 1, 2)))
+extern void asmlinkage __attribute__((format(printf, 1, 2)))
 	early_printk(const char *fmt, ...);
 
 unsigned long int_sqrt(unsigned long);
diff --git a/kernel/printk.c b/kernel/printk.c
index 8fb01c3..de1a4f4 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -38,7 +38,7 @@
 /*
  * Architectures can override it:
  */
-void __attribute__((weak)) early_printk(const char *fmt, ...)
+void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
 {
 }
 
@@ -75,6 +75,8 @@ EXPORT_SYMBOL(oops_in_progress);
 static DECLARE_MUTEX(console_sem);
 static DECLARE_MUTEX(secondary_console_sem);
 struct console *console_drivers;
+EXPORT_SYMBOL_GPL(console_drivers);
+
 /*
  * This is used for debugging the mess that is the VT code by
  * keeping track if we have the console semaphore held. It's
@@ -231,7 +233,7 @@ static inline void boot_delay_msec(void)
 /*
  * Return the number of unread characters in the log buffer.
  */
-int log_buf_get_len(void)
+static int log_buf_get_len(void)
 {
 	return logged_chars;
 }
@@ -268,19 +270,6 @@ int log_buf_copy(char *dest, int idx, int len)
 }
 
 /*
- * Extract a single character from the log buffer.
- */
-int log_buf_read(int idx)
-{
-	char ret;
-
-	if (log_buf_copy(&ret, idx, 1) == 1)
-		return ret;
-	else
-		return -1;
-}
-
-/*
  * Commands to do_syslog:
  *
  * 	0 -- Close the log.  Currently a NOP.
@@ -665,18 +654,17 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu)
 	spin_unlock(&logbuf_lock);
 	return retval;
 }
-
-const char printk_recursion_bug_msg [] =
-			KERN_CRIT "BUG: recent printk recursion!\n";
-static int printk_recursion_bug;
+static const char recursion_bug_msg [] =
+		KERN_CRIT "BUG: recent printk recursion!\n";
+static int recursion_bug;
+	static int new_text_line = 1;
+static char printk_buf[1024];
 
 asmlinkage int vprintk(const char *fmt, va_list args)
 {
-	static int log_level_unknown = 1;
-	static char printk_buf[1024];
-
-	unsigned long flags;
 	int printed_len = 0;
+	int current_log_level = default_message_loglevel;
+	unsigned long flags;
 	int this_cpu;
 	char *p;
 
@@ -699,7 +687,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 		 * it can be printed at the next appropriate moment:
 		 */
 		if (!oops_in_progress) {
-			printk_recursion_bug = 1;
+			recursion_bug = 1;
 			goto out_restore_irqs;
 		}
 		zap_locks();
@@ -709,70 +697,62 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 	spin_lock(&logbuf_lock);
 	printk_cpu = this_cpu;
 
-	if (printk_recursion_bug) {
-		printk_recursion_bug = 0;
-		strcpy(printk_buf, printk_recursion_bug_msg);
-		printed_len = sizeof(printk_recursion_bug_msg);
+	if (recursion_bug) {
+		recursion_bug = 0;
+		strcpy(printk_buf, recursion_bug_msg);
+		printed_len = sizeof(recursion_bug_msg);
 	}
 	/* Emit the output into the temporary buffer */
 	printed_len += vscnprintf(printk_buf + printed_len,
 				  sizeof(printk_buf) - printed_len, fmt, args);
 
+
 	/*
 	 * Copy the output into log_buf.  If the caller didn't provide
 	 * appropriate log level tags, we insert them here
 	 */
 	for (p = printk_buf; *p; p++) {
-		if (log_level_unknown) {
-                        /* log_level_unknown signals the start of a new line */
+		if (new_text_line) {
+			/* If a token, set current_log_level and skip over */
+			if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
+			    p[2] == '>') {
+				current_log_level = p[1] - '0';
+				p += 3;
+				printed_len -= 3;
+			}
+
+			/* Always output the token */
+			emit_log_char('<');
+			emit_log_char(current_log_level + '0');
+			emit_log_char('>');
+			printed_len += 3;
+			new_text_line = 0;
+
 			if (printk_time) {
-				int loglev_char;
+				/* Follow the token with the time */
 				char tbuf[50], *tp;
 				unsigned tlen;
 				unsigned long long t;
 				unsigned long nanosec_rem;
 
-				/*
-				 * force the log level token to be
-				 * before the time output.
-				 */
-				if (p[0] == '<' && p[1] >='0' &&
-				   p[1] <= '7' && p[2] == '>') {
-					loglev_char = p[1];
-					p += 3;
-					printed_len -= 3;
-				} else {
-					loglev_char = default_message_loglevel
-						+ '0';
-				}
 				t = cpu_clock(printk_cpu);
 				nanosec_rem = do_div(t, 1000000000);
-				tlen = sprintf(tbuf,
-						"<%c>[%5lu.%06lu] ",
-						loglev_char,
-						(unsigned long)t,
-						nanosec_rem/1000);
+				tlen = sprintf(tbuf, "[%5lu.%06lu] ",
+						(unsigned long) t,
+						nanosec_rem / 1000);
 
 				for (tp = tbuf; tp < tbuf + tlen; tp++)
 					emit_log_char(*tp);
 				printed_len += tlen;
-			} else {
-				if (p[0] != '<' || p[1] < '0' ||
-				   p[1] > '7' || p[2] != '>') {
-					emit_log_char('<');
-					emit_log_char(default_message_loglevel
-						+ '0');
-					emit_log_char('>');
-					printed_len += 3;
-				}
 			}
-			log_level_unknown = 0;
+
 			if (!*p)
 				break;
 		}
+
 		emit_log_char(*p);
 		if (*p == '\n')
-			log_level_unknown = 1;
+			new_text_line = 1;
 	}
 
 	/*
@@ -1172,8 +1152,11 @@ void register_console(struct console *console)
 			console->index = 0;
 		if (console->setup == NULL ||
 		    console->setup(console, NULL) == 0) {
-			console->flags |= CON_ENABLED | CON_CONSDEV;
-			preferred_console = 0;
+			console->flags |= CON_ENABLED;
+			if (console->device) {
+				console->flags |= CON_CONSDEV;
+				preferred_console = 0;
+			}
 		}
 	}
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 6021757..f60c7c0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -22,6 +22,8 @@
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/kernel.h>
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
 #include <asm/div64.h>
@@ -482,6 +484,82 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
 	return buf;
 }
 
+static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
+{
+	int len, i;
+
+	if ((unsigned long)s < PAGE_SIZE)
+		s = "<NULL>";
+
+	len = strnlen(s, precision);
+
+	if (!(flags & LEFT)) {
+		while (len < field_width--) {
+			if (buf < end)
+				*buf = ' ';
+			++buf;
+		}
+	}
+	for (i = 0; i < len; ++i) {
+		if (buf < end)
+			*buf = *s;
+		++buf; ++s;
+	}
+	while (len < field_width--) {
+		if (buf < end)
+			*buf = ' ';
+		++buf;
+	}
+	return buf;
+}
+
+static inline void *dereference_function_descriptor(void *ptr)
+{
+#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
+	void *p;
+	if (!probe_kernel_address(ptr, p))
+		ptr = p;
+#endif
+	return ptr;
+}
+
+
+/*
+ * Show a '%p' thing.  A kernel extension is that the '%p' is followed
+ * by an extra set of alphanumeric characters that are extended format
+ * specifiers.  Right now we just handle 'F' (for symbolic Function
+ * pointers) and 'S' (for Symbolic data pointers), but this can easily
+ * be extended in the future (network address types etc).
+ *
+ * The difference between 'S' and 'F' is that on ia64 and ppc64 function
+ * pointers are really function descriptors, which contain a pointer the
+ * real address. 
+ */
+static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int base, int size, int precision, int type)
+{
+	switch (*fmt) {
+	case 'F':
+		ptr = dereference_function_descriptor(ptr);
+		/* Fallthrough */
+	case 'S': {	/* Other (direct) pointer */
+#if CONFIG_KALLSYMS
+		char sym[KSYM_SYMBOL_LEN];
+		sprint_symbol(sym, (unsigned long) ptr);
+		return string(buf, end, sym, size, precision, type);
+#else
+		type |= SPECIAL;
+		break;
+#endif
+	}
+	}
+	type |= SMALL;
+	if (precision == -1) {
+		precision = 2*sizeof(void *);
+		type |= ZEROPAD;
+	}
+	return number(buf, end, (unsigned long long) ptr, base, size, precision, type);
+}
+
 /**
  * vsnprintf - Format a string and place it in a buffer
  * @buf: The buffer to place the result into
@@ -502,11 +580,9 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
  */
 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
-	int len;
 	unsigned long long num;
-	int i, base;
+	int base;
 	char *str, *end, c;
-	const char *s;
 
 	int flags;		/* flags to number() */
 
@@ -622,40 +698,16 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 				continue;
 
 			case 's':
-				s = va_arg(args, char *);
-				if ((unsigned long)s < PAGE_SIZE)
-					s = "<NULL>";
-
-				len = strnlen(s, precision);
-
-				if (!(flags & LEFT)) {
-					while (len < field_width--) {
-						if (str < end)
-							*str = ' ';
-						++str;
-					}
-				}
-				for (i = 0; i < len; ++i) {
-					if (str < end)
-						*str = *s;
-					++str; ++s;
-				}
-				while (len < field_width--) {
-					if (str < end)
-						*str = ' ';
-					++str;
-				}
+				str = string(str, end, va_arg(args, char *), field_width, precision, flags);
 				continue;
 
 			case 'p':
-				flags |= SMALL;
-				if (field_width == -1) {
-					field_width = 2*sizeof(void *);
-					flags |= ZEROPAD;
-				}
-				str = number(str, end,
-						(unsigned long) va_arg(args, void *),
+				str = pointer(fmt+1, str, end,
+						va_arg(args, void *),
 						16, field_width, precision, flags);
+				/* Skip all alphanumeric pointer suffixes */
+				while (isalnum(fmt[1]))
+					fmt++;
 				continue;
 
 

^ permalink raw reply related

* Re: the printk problem
From: Ingo Molnar @ 2008-07-06  6:13 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, Linux Kernel Mailing List, linuxppc-dev, Peter Anvin,
	Andrew Morton, Arjan van de Ven, David S. Miller, parisc-linux
In-Reply-To: <20080706055317.GA4212@elte.hu>


* Ingo Molnar <mingo@elte.hu> wrote:

> yeah, agreed, combined it's not an x86 topic anymore.
> 
> [ There's some lkml trouble so i've missed the earlier patch. I'm not 
>   sure the email problem is on my side, see how incomplete the 
>   discussion is on lkml.org as well:
> 
>      http://lkml.org/lkml/2008/6/25/170   ]
> 
> Anyway, i have have added this second patch of yours to 
> tip/core/printk and moved your first patch over to that topic (which 
> relies on it).

ah, i found the reason - it started out on linux-ia64 originally then 
moved over to lkml - so only half of the discussion was visible there. 
And linux-ia64 is one of the few vger lists i'm not subscribed to 
apparently. (there's no vger-please-give-me-all-emails list - making the 
following of Linux development even harder)

	Ingo

^ permalink raw reply

* Re: the printk problem
From: Randy Dunlap @ 2008-07-06  5:17 UTC (permalink / raw)
  To: Pekka Enberg
  Cc: linux-ia64, Matthew Wilcox, Vegard Nossum, linux-kernel,
	Jan Engelhardt, linuxppc-dev, Peter Anvin, Andrew Morton,
	Linus Torvalds, David S. Miller
In-Reply-To: <84144f020807051702q1fc6275cv358c5e33dc2677fc@mail.gmail.com>

On Sun, 6 Jul 2008 03:02:59 +0300 Pekka Enberg wrote:

> On Sat, Jul 05, 2008 at 08:41:39PM +0200, Vegard Nossum wrote:
> >> Single letters are bad because it hurts readability and limits the
> >> usefulness of the extension.</MHO>
> 
> On Sat, Jul 5, 2008 at 9:52 PM, Matthew Wilcox <matthew@wil.cx> wrote:
> > I think you need a little warning noise that goes off in your head that
> > means "I might be overdesigning this".  Linus' code is elegant and
> > solves a problem nicely.
> 
> Am I the only one who missed Linus' patch? Did it make it to the list?

No, you are not the only one.  It was on linuxppc-dev for some reason.
http://ozlabs.org/pipermail/linuxppc-dev/2008-July/059257.html

---
~Randy
Linux Plumbers Conference, 17-19 September 2008, Portland, Oregon USA
http://linuxplumbersconf.org/

^ permalink raw reply

* powerpc: fix swapcontext backwards compatibility due to VSX ucontext changes
From: Michael Neuling @ 2008-07-06  8:37 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18542.1169.106972.172938@cargo.ozlabs.ibm.com>

When the ucontext changed to add the VSX context, this broke backwards
compatibly on swapcontext.  swapcontext only compares the ucontext
size passed in from the user to the new kernel ucontext size.

This adds a check against the old ucontext size (with VMX but without
VSX).  It also adds some sanity check for ucontexts without VSX, but
where VSX is used according the MSR.  Fixes for both 32 and 64bit
processes on 64bit kernels

Kudos to Paulus for noticing.

Signed-off-by: Michael Neuling <mikey@neuling.org>
---
> > +	    /*
> > +	     * If userspace doesn't provide enough room for VSX data,
> > +	     * but current thread has used VSX, we don't have anywhere
> > +	     * to store the full context back into.
> > +	     */
> > +		((ctx_size < sizeof(struct ucontext)) &&
> > +		 (regs->msr & MSR_VSX) && old_ctx) ||
> 
> I think we need to check current->thread.used_vsr rather than
> regs->msr here (in both instances of this code).

Yep I agree.  Thanks

 arch/powerpc/kernel/signal_32.c |   36 +++++++++++++++++++++++++++++++++++-
 arch/powerpc/kernel/signal_64.c |   35 +++++++++++++++++++++++++++++++----
 2 files changed, 66 insertions(+), 5 deletions(-)

Index: linux-2.6-ozlabs/arch/powerpc/kernel/signal_32.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/signal_32.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/signal_32.c
@@ -68,6 +68,13 @@
 #define ucontext	ucontext32
 
 /*
+ * Userspace code may pass a ucontext which doesn't include VSX added
+ * at the end.  We need to check for this case.
+ */
+#define UCONTEXTSIZEWITHOUTVSX \
+		(sizeof(struct ucontext) - sizeof(elf_vsrreghalf_t32))
+
+/*
  * Returning 0 means we return to userspace via
  * ret_from_except and thus restore all user
  * registers from *regs.  This is what we need
@@ -930,12 +937,39 @@ long sys_swapcontext(struct ucontext __u
 {
 	unsigned char tmp;
 
+#ifdef CONFIG_PPC64
+	unsigned long new_msr = 0;
+
+	if (new_ctx &&
+	    __get_user(new_msr, &new_ctx->uc_mcontext.mc_gregs[PT_MSR]))
+		return -EFAULT;
+	if (/*
+	     * Check that the context is not smaller than the original
+	     * size (with VMX but without VSX)
+	     */
+		(ctx_size < UCONTEXTSIZEWITHOUTVSX) ||
+	    /*
+	     * If userspace doesn't provide enough room for VSX data,
+	     * but current thread has used VSX, we don't have anywhere
+	     * to store the full context back into.
+	     */
+		((ctx_size < sizeof(struct ucontext)) &&
+		 current->thread.used_vsr && old_ctx) ||
+	    /*
+	     * If the new context state sets the MSR VSX bits but
+	     * it doesn't provide VSX state.
+	     */
+		((ctx_size < sizeof(struct ucontext)) &&
+		 (new_msr & MSR_VSX)))
+		/* ... computer says "noooo" */
+		return -EINVAL;
+#else
 	/* Context size is for future use. Right now, we only make sure
 	 * we are passed something we understand
 	 */
 	if (ctx_size < sizeof(struct ucontext))
 		return -EINVAL;
-
+#endif
 	if (old_ctx != NULL) {
 		struct mcontext __user *mctx;
 
Index: linux-2.6-ozlabs/arch/powerpc/kernel/signal_64.c
===================================================================
--- linux-2.6-ozlabs.orig/arch/powerpc/kernel/signal_64.c
+++ linux-2.6-ozlabs/arch/powerpc/kernel/signal_64.c
@@ -268,6 +268,13 @@ static long setup_trampoline(unsigned in
 }
 
 /*
+ * Userspace code may pass a ucontext which doesn't include VSX added
+ * at the end.  We need to check for this case.
+ */
+#define UCONTEXTSIZEWITHOUTVSX \
+		(sizeof(struct ucontext) - 32*sizeof(long))
+
+/*
  * Handle {get,set,swap}_context operations
  */
 int sys_swapcontext(struct ucontext __user *old_ctx,
@@ -277,10 +284,30 @@ int sys_swapcontext(struct ucontext __us
 	unsigned char tmp;
 	sigset_t set;
 
-	/* Context size is for future use. Right now, we only make sure
-	 * we are passed something we understand
-	 */
-	if (ctx_size < sizeof(struct ucontext))
+	unsigned long new_msr = 0;
+
+	if (new_ctx &&
+	    __get_user(new_msr, &new_ctx->uc_mcontext.gp_regs[PT_MSR]))
+		return -EFAULT;
+	if (/*
+	     * Check that the context is not smaller than the original
+	     * size (with VMX but without VSX)
+	     */
+		(ctx_size < UCONTEXTSIZEWITHOUTVSX) ||
+	    /*
+	     * If userspace doesn't provide enough room for VSX data,
+	     * but current thread has used VSX, we don't have anywhere
+	     * to store the full context back into.
+	     */
+		((ctx_size < sizeof(struct ucontext)) &&
+		 current->thread.used_vsr && old_ctx) ||
+	    /*
+	     * If the new context state sets the MSR VSX bits but
+	     * it doesn't provide VSX state.
+	     */
+		((ctx_size < sizeof(struct ucontext)) &&
+		 (new_msr & MSR_VSX)))
+		/* ... computer says "No" */
 		return -EINVAL;
 
 	if (old_ctx != NULL) {

^ permalink raw reply

* Re: [PATCH v4] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Stefan Roese @ 2008-07-06  9:43 UTC (permalink / raw)
  To: Grant Erickson; +Cc: linuxppc-dev
In-Reply-To: <1215303343-26410-1-git-send-email-gerickson@nuovations.com>

On Sunday 06 July 2008, Grant Erickson wrote:
> Various instances of the EMAC core have varying: 1) number of address
> match slots, 2) width of the registers for handling address match slots,
> 3) number of registers for handling address match slots and 4) base
> offset for those registers.

Thanks Grant. Apart from Ben's comments I only have a few nitpicking comment. 
Please see below.

<snip>

> diff --git a/drivers/net/ibm_newemac/core.c
> b/drivers/net/ibm_newemac/core.c index 5d2108c..931a061 100644
> --- a/drivers/net/ibm_newemac/core.c
> +++ b/drivers/net/ibm_newemac/core.c
> @@ -363,25 +363,32 @@ static int emac_reset(struct emac_instance *dev)
>
>  static void emac_hash_mc(struct emac_instance *dev)
>  {
> -	struct emac_regs __iomem *p = dev->emacp;
> -	u16 gaht[4] = { 0 };
> +	const int regs = EMAC_XAHT_REGS(dev);
> +	u32 *gaht_base = emac_gaht_base(dev);
> +	u32 gaht_temp[regs];
>  	struct dev_mc_list *dmi;
> +	int i;
>
>  	DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
>
> +	memset(gaht_temp, 0, sizeof (gaht_temp));
> +
>  	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
> -		int bit;
> +		int slot, reg, mask;
>  		DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
>  		     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
>  		     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
>
> -		bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
> -		gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
> +		slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
> +		reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
> +		mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot);
> +
> +		gaht_temp[reg] |= mask;
> +	}
> +
> +	for (i = 0; i < regs; i++) {
> +		out_be32(gaht_base + i, gaht_temp[i]);
>  	}

No parentheses on single line statements.

> -	out_be32(&p->gaht1, gaht[0]);
> -	out_be32(&p->gaht2, gaht[1]);
> -	out_be32(&p->gaht3, gaht[2]);
> -	out_be32(&p->gaht4, gaht[3]);
>  }
>
>  static inline u32 emac_iff2rmr(struct net_device *ndev)
> @@ -398,7 +405,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
>
>  	if (ndev->flags & IFF_PROMISC)
>  		r |= EMAC_RMR_PME;
> -	else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
> +	else if (ndev->flags & IFF_ALLMULTI ||
> +			 (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
>  		r |= EMAC_RMR_PMME;
>  	else if (ndev->mc_count > 0)
>  		r |= EMAC_RMR_MAE;
> @@ -2015,10 +2023,10 @@ static int emac_get_regs_len(struct emac_instance
> *dev) {
>  	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
>  		return sizeof(struct emac_ethtool_regs_subhdr) +
> -			EMAC4_ETHTOOL_REGS_SIZE;
> +			EMAC4_ETHTOOL_REGS_SIZE(dev);
>  	else
>  		return sizeof(struct emac_ethtool_regs_subhdr) +
> -			EMAC_ETHTOOL_REGS_SIZE;
> +			EMAC_ETHTOOL_REGS_SIZE(dev);
>  }
>
>  static int emac_ethtool_get_regs_len(struct net_device *ndev)
> @@ -2045,12 +2053,12 @@ static void *emac_dump_regs(struct emac_instance
> *dev, void *buf) hdr->index = dev->cell_index;
>  	if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
>  		hdr->version = EMAC4_ETHTOOL_REGS_VER;
> -		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE);
> -		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE);
> +		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
> +		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
>  	} else {
>  		hdr->version = EMAC_ETHTOOL_REGS_VER;
> -		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
> -		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
> +		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
> +		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
>  	}
>  }
>
> @@ -2540,7 +2548,9 @@ static int __devinit emac_init_config(struct
> emac_instance *dev) }
>
>  	/* Check EMAC version */
> -	if (of_device_is_compatible(np, "ibm,emac4")) {
> +	if (of_device_is_compatible(np, "ibm,emac4sync")) {
> +		dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
> +	} else if (of_device_is_compatible(np, "ibm,emac4")) {
>  		dev->features |= EMAC_FTR_EMAC4;
>  		if (of_device_is_compatible(np, "ibm,emac-440gx"))
>  			dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
> @@ -2601,6 +2611,15 @@ static int __devinit emac_init_config(struct
> emac_instance *dev) }
>  	memcpy(dev->ndev->dev_addr, p, 6);
>
> +	/* IAHT and GAHT filter parameterization */
> +	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
> +		dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT;
> +		dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT;
> +	} else {
> +		dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT;
> +		dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT;
> +	}
> +
>  	DBG(dev, "features     : 0x%08x / 0x%08x\n", dev->features,
> EMAC_FTRS_POSSIBLE); DBG(dev, "tx_fifo_size : %d (%d gige)\n",
> dev->tx_fifo_size, dev->tx_fifo_size_gige); DBG(dev, "rx_fifo_size : %d (%d
> gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige); @@ -2672,7 +2691,8 @@
> static int __devinit emac_probe(struct of_device *ofdev, goto
> err_irq_unmap;
>  	}
>  	// TODO : request_mem_region
> -	dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs));
> +	dev->emacp = ioremap(dev->rsrc_regs.start,
> +						 dev->rsrc_regs.end - dev->rsrc_regs.start + 1);


Indentation above seems incorrect.

>  	if (dev->emacp == NULL) {
>  		printk(KERN_ERR "%s: Can't map device registers!\n",
>  		       np->full_name);
> @@ -2884,6 +2904,10 @@ static struct of_device_id emac_match[] =
>  		.type		= "network",
>  		.compatible	= "ibm,emac4",
>  	},
> +	{
> +		.type		= "network",
> +		.compatible	= "ibm,emac4sync",
> +	},
>  	{},
>  };
>
> diff --git a/drivers/net/ibm_newemac/core.h
> b/drivers/net/ibm_newemac/core.h index 1683db9..312bfa5 100644
> --- a/drivers/net/ibm_newemac/core.h
> +++ b/drivers/net/ibm_newemac/core.h
> @@ -235,6 +235,10 @@ struct emac_instance {
>  	u32				fifo_entry_size;
>  	u32				mal_burst_size; /* move to MAL ? */
>
> +	/* IAHT and GAHT filter parameterization */
> +	u32				xaht_slots_shift;
> +	u32				xaht_width_shift;
> +
>  	/* Descriptor management
>  	 */
>  	struct mal_descriptor		*tx_desc;
> @@ -309,6 +313,10 @@ struct emac_instance {
>   * Set if we need phy clock workaround for 440ep or 440gr
>   */
>  #define EMAC_FTR_440EP_PHY_CLK_FIX	0x00000100
> +/*
> + * The 405EX and 460EX contain the EMAC4SYNC core
> + */
> +#define EMAC_FTR_EMAC4SYNC		0x00000200
>
>
>  /* Right now, we don't quite handle the always/possible masks on the
> @@ -320,7 +328,8 @@ enum {
>
>  	EMAC_FTRS_POSSIBLE	=
>  #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
> -	    EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
> +	    EMAC_FTR_EMAC4	| EMAC_FTR_EMAC4SYNC	|
> +	    EMAC_FTR_HAS_NEW_STACR	|
>  	    EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
>  #endif
>  #ifdef CONFIG_IBM_NEW_EMAC_TAH
> @@ -342,6 +351,71 @@ static inline int emac_has_feature(struct
> emac_instance *dev, (EMAC_FTRS_POSSIBLE & dev->features & feature);
>  }
>
> +/*
> + * Various instances of the EMAC core have varying 1) number of
> + * address match slots, 2) width of the registers for handling address
> + * match slots, 3) number of registers for handling address match
> + * slots and 4) base offset for those registers.
> + *
> + * These macros and inlines handle these differences based on
> + * parameters supplied by the device tree.
> + */
> +
> +#define	EMAC4_XAHT_SLOTS_SHIFT		6
> +#define	EMAC4_XAHT_WIDTH_SHIFT		4
> +#define	EMAC4_XAHT_BASE_OFFSET		0x30
> +
> +#define	EMAC4SYNC_XAHT_SLOTS_SHIFT	8
> +#define	EMAC4SYNC_XAHT_WIDTH_SHIFT	5
> +#define	EMAC4SYNC_XAHT_BASE_OFFSET	0x80
> +
> +
> +#define	EMAC_XAHT_SLOTS(dev)         	(1 << (dev)->xaht_slots_shift)
> +#define	EMAC_XAHT_WIDTH(dev)         	(1 << (dev)->xaht_width_shift)
> +#define	EMAC_XAHT_REGS(dev)          	(1 << ((dev)->xaht_slots_shift - \
> +					       (dev)->xaht_width_shift))
> +
> +#define	EMAC_XAHT_CRC_TO_SLOT(dev, crc)			\
> +	((EMAC_XAHT_SLOTS(dev) - 1) -			\
> +	 ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) -	\
> +		    (dev)->xaht_slots_shift)))
> +
> +#define	EMAC_XAHT_SLOT_TO_REG(dev, slot)		\
> +	((slot) >> (dev)->xaht_width_shift)
> +
> +#define	EMAC_XAHT_SLOT_TO_MASK(dev, slot)		\
> +	((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >>	\
> +	 ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1)))
> +
> +static inline u32 *emac_xaht_base(struct emac_instance *dev)
> +{
> +	struct emac_regs __iomem *p = dev->emacp;
> +	int offset;
> +
> +	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC))
> +	    offset = EMAC4SYNC_XAHT_BASE_OFFSET;
> +	else
> +	    offset = EMAC4_XAHT_BASE_OFFSET;

Indentation with 4 spaces instead of one tab above "offset =" (twice).

Thanks.

BTW: You should send those ibm_newemac related patches to the netdev list too.

Best regards,
Stefan

^ permalink raw reply

* Re: patches for 2.6.27...
From: Vitaly Bordug @ 2008-07-06 14:54 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linuxppc-dev
In-Reply-To: <200807021036.46603.laurentp@cse-semaphore.com>

В Wed, 2 Jul 2008 10:36:43 +0200
Laurent Pinchart <laurentp@cse-semaphore.com> пишет:

> Hi Kumar,
> 
> On Wednesday 02 July 2008, Kumar Gala wrote:
> > Please point out any patches that have been posted but havent made
> > it into a git tree related to Freescale chips.
> > 
> > I know there are probably a slew of CPM patches that need to get
> > into the tree.
> 
> Here are 5 patches that I'd like to see in 2.6.27. They haven't made
> into any git tree as far as I know.
> 
> [PATCHv2] fs_enet: restore promiscuous and multicast settings in
> restart()
> http://patchwork.ozlabs.org/linuxppc/patch?person=968&id=19228 [PATCH
> 2/2] fs_enet: MDIO on GPIO support

This has been merged per email from Jeff.

> http://patchwork.ozlabs.org/linuxppc/patch?person=968&id=18693
> [PATCHv3 1/2] [POWERPC] CPM2: Implement GPIO LIB API on CPM2
> Freescale SoC.

> http://patchwork.ozlabs.org/linuxppc/patch?person=968&id=19045
> [PATCH] powerpc: Modem control lines support for the cpm_uart driver
> http://patchwork.ozlabs.org/linuxppc/patch?person=968&id=17928

Seems to be missing and I'd second adding this and will add my ACK if
it will help getting those upstream.

> [PATCH] cpm_uart: Support uart_wait_until_sent()
> http://patchwork.ozlabs.org/linuxppc/patch?person=968&id=19233
> 
This seems to be applied to Kumar's tree per email from him.

^ permalink raw reply

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
From: Arnd Bergmann @ 2008-07-06 15:15 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev
In-Reply-To: <1215296448.8970.14.camel@pasglop>

On Sunday 06 July 2008, Benjamin Herrenschmidt wrote:
> I need to look closely at what the various bridge settings are. Drivers
> do expect DMA requests from one device to stay in order, at least up to
> what's defined in the PCI spec, which is pretty much fully ordered
> unless those devices set the PCIe (or X) relaxed ordering attribute.
> However, AFAIK, Axon doesn't convey that sort of ordering attributes
> from incoming transactions between the PCIe segment and the PLB5.

Yes, it would be very helpful if you can look into this a bit more.
The Axon specification is particularly confusing in this regard and
even though everyone I have asked so far told us that it's totally
fine, an extra person with more insight in the complete picture looking
into this would be good.

	Arnd <><

^ permalink raw reply

* Re: [alsa-devel] [PATCH 2/3] ALSA SoC: Add mpc5200-psc I2S driver
From: Jon Smirl @ 2008-07-06 17:56 UTC (permalink / raw)
  To: Grant Likely; +Cc: liam.girdwood, alsa-devel, broonie, timur, linuxppc-dev
In-Reply-To: <20080701235335.16923.43253.stgit@trillian.secretlab.ca>

On 7/1/08, Grant Likely <grant.likely@secretlab.ca> wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
>  This is an I2S bus driver for the MPC5200 PSC device.  It is probably
>  will not be merged as-is because it uses v1 of the ASoC API, but I want
>  to get it out there for comments.
>  ---

The driver is assuming a capture stream exists. My codec is output only.

I'm using external clocking, but the driver should support using the
mpc5200 for clocking. That's a little complicated since you have to
compute the divisors. For example the Phytec pcm030 board has a
33.3333Mhz xtal and runs at 400Mhz.

In order to reduce options, can the psc-i2s driver always try to use
mpc5200 clocking, then let the codec or fabric driver override it?

-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* [PATCH v5] ibm_newemac: Parameterize EMAC Multicast Match Handling
From: Grant Erickson @ 2008-07-06 23:30 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: sr
In-Reply-To: <1215303343-26410-1-git-send-email-gerickson@nuovations.com>

Various instances of the EMAC core have varying: 1) number of address 
match slots, 2) width of the registers for handling address match slots, 
3) number of registers for handling address match slots and 4) base 
offset for those registers.

As the driver stands today, it assumes that all EMACs have 4 IAHT and 
GAHT 32-bit registers, starting at offset 0x30 from the register base, 
with only 16-bits of each used for a total of 64 match slots.

The 405EX(r) and 460EX now use the EMAC4SYNC core rather than the EMAC4 
core. This core has 8 IAHT and GAHT registers, starting at offset 0x80 
from the register base, with ALL 32-bits of each used for a total of 
256 match slots.

This adds a new compatible device tree entry "emac4sync" and a new,
related feature flag "EMAC_FTR_EMAC4SYNC" along with a series of macros
and inlines which supply the appropriate parameterized value based on
the presence or absence of the EMAC4SYNC feature.

The code has further been reworked where appropriate to use those macros
and inlines.

In addition, the register size passed to ioremap is now taken from the 
device tree:

	c4 for EMAC4SYNC cores
	74 for EMAC4 cores
	70 for EMAC cores

rather than sizeof (emac_regs).

Finally, the device trees have been updated with the appropriate compatible
entries and resource sizes.

This has been tested on an AMCC Haleakala board such that: 1) inbound 
ICMP requests to 'haleakala.local' via MDNS from both Mac OS X 10.4.11 
and Ubuntu 8.04 systems as well as 2) outbound ICMP requests from 
'haleakala.local' to those same systems in the '.local' domain via MDNS 
now work.

Signed-off-by: Grant Erickson <gerickson@nuovations.com>
---
 arch/powerpc/boot/dts/canyonlands.dts |    8 +-
 arch/powerpc/boot/dts/glacier.dts     |    8 +-
 arch/powerpc/boot/dts/haleakala.dts   |    4 +-
 arch/powerpc/boot/dts/katmai.dts      |    2 +-
 arch/powerpc/boot/dts/kilauea.dts     |    8 +-
 arch/powerpc/boot/dts/makalu.dts      |    8 +-
 arch/powerpc/boot/dts/rainier.dts     |    4 +-
 arch/powerpc/boot/dts/sequoia.dts     |    4 +-
 arch/powerpc/boot/dts/taishan.dts     |    8 +-
 drivers/net/ibm_newemac/core.c        |   61 ++++++++++++++------
 drivers/net/ibm_newemac/core.h        |   83 ++++++++++++++++++++++++++-
 drivers/net/ibm_newemac/debug.c       |   52 +++++++++++++----
 drivers/net/ibm_newemac/emac.h        |  101 ++++++++++++++++++++++----------
 13 files changed, 259 insertions(+), 92 deletions(-)

diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 3963412..8b82d47 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -264,7 +264,7 @@
 
 			EMAC0: ethernet@ef600e00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -272,7 +272,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -293,7 +293,7 @@
 
 			EMAC1: ethernet@ef600f00 {
 				device_type = "network";
-				compatible = "ibm,emac-460ex", "ibm,emac4";
+				compatible = "ibm,emac-460ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -301,7 +301,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/glacier.dts b/arch/powerpc/boot/dts/glacier.dts
index 0f2fc07..8ffde9b 100644
--- a/arch/powerpc/boot/dts/glacier.dts
+++ b/arch/powerpc/boot/dts/glacier.dts
@@ -281,7 +281,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 10 4
 						 /*Wake*/   1 &UIC2 14 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -310,7 +310,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 11 4
 						 /*Wake*/   1 &UIC2 15 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -340,7 +340,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 12 4
 						 /*Wake*/   1 &UIC2 16 4>;
-				reg = <ef601100 70>;
+				reg = <ef601100 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -368,7 +368,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC2 13 4
 						 /*Wake*/   1 &UIC2 17 4>;
-				reg = <ef601200 70>;
+				reg = <ef601200 74>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts
index b5d95ac..d131c00 100644
--- a/arch/powerpc/boot/dts/haleakala.dts
+++ b/arch/powerpc/boot/dts/haleakala.dts
@@ -204,7 +204,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405exr", "ibm,emac4";
+				compatible = "ibm,emac-405exr", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -212,7 +212,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/katmai.dts b/arch/powerpc/boot/dts/katmai.dts
index cc2873a..c91bb66 100644
--- a/arch/powerpc/boot/dts/katmai.dts
+++ b/arch/powerpc/boot/dts/katmai.dts
@@ -206,7 +206,7 @@
 				compatible = "ibm,emac-440spe", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <10000800 70>;
+				reg = <10000800 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 48c9a6e..799592d 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/makalu.dts b/arch/powerpc/boot/dts/makalu.dts
index 84cc5e7..4295772 100644
--- a/arch/powerpc/boot/dts/makalu.dts
+++ b/arch/powerpc/boot/dts/makalu.dts
@@ -205,7 +205,7 @@
 			EMAC0: ethernet@ef600900 {
 				linux,network-index = <0>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC0>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -213,7 +213,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600900 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -233,7 +233,7 @@
 			EMAC1: ethernet@ef600a00 {
 				linux,network-index = <1>;
 				device_type = "network";
-				compatible = "ibm,emac-405ex", "ibm,emac4";
+				compatible = "ibm,emac-405ex", "ibm,emac4sync";
 				interrupt-parent = <&EMAC1>;
 				interrupts = <0 1>;
 				#interrupt-cells = <1>;
@@ -241,7 +241,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600a00 70>;
+				reg = <ef600900 c4>;
 				local-mac-address = [000000000000]; /* Filled in by U-Boot */
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/rainier.dts b/arch/powerpc/boot/dts/rainier.dts
index 6a8fa70..026c22c 100644
--- a/arch/powerpc/boot/dts/rainier.dts
+++ b/arch/powerpc/boot/dts/rainier.dts
@@ -263,7 +263,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -292,7 +292,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/sequoia.dts b/arch/powerpc/boot/dts/sequoia.dts
index 72d6756..8d66c99 100644
--- a/arch/powerpc/boot/dts/sequoia.dts
+++ b/arch/powerpc/boot/dts/sequoia.dts
@@ -278,7 +278,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 18 4
 						/*Wake*/  1 &UIC1 1d 4>;
-				reg = <ef600e00 70>;
+				reg = <ef600e00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -307,7 +307,7 @@
 				#size-cells = <0>;
 				interrupt-map = </*Status*/ 0 &UIC0 19 4
 						/*Wake*/  1 &UIC1 1f 4>;
-				reg = <ef600f00 70>;
+				reg = <ef600f00 74>;
 				local-mac-address = [000000000000];
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
diff --git a/arch/powerpc/boot/dts/taishan.dts b/arch/powerpc/boot/dts/taishan.dts
index e808e1c..f736d87 100644
--- a/arch/powerpc/boot/dts/taishan.dts
+++ b/arch/powerpc/boot/dts/taishan.dts
@@ -258,7 +258,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1c 4 1d 4>;
-				reg = <40000800 70>;
+				reg = <40000800 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <0>;
@@ -278,7 +278,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC1>;
 				interrupts = <1e 4 1f 4>;
-				reg = <40000900 70>;
+				reg = <40000900 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <1>;
@@ -298,7 +298,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <0 4 1 4>;
-				reg = <40000c00 70>;
+				reg = <40000c00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <2>;
@@ -322,7 +322,7 @@
 				compatible = "ibm,emac-440gx", "ibm,emac4";
 				interrupt-parent = <&UIC2>;
 				interrupts = <2 4 3 4>;
-				reg = <40000e00 70>;
+				reg = <40000e00 74>;
 				local-mac-address = [000000000000]; // Filled in by zImage
 				mal-device = <&MAL0>;
 				mal-tx-channel = <3>;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 5d2108c..ed24a1d 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -363,25 +363,31 @@ static int emac_reset(struct emac_instance *dev)
 
 static void emac_hash_mc(struct emac_instance *dev)
 {
-	struct emac_regs __iomem *p = dev->emacp;
-	u16 gaht[4] = { 0 };
+	const int regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 gaht_temp[regs];
 	struct dev_mc_list *dmi;
+	int i;
 
 	DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
 
+	memset(gaht_temp, 0, sizeof (gaht_temp));
+
 	for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
-		int bit;
+		int slot, reg, mask;
 		DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
 		     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
 		     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
 
-		bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
-		gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+		slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
+		reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
+		mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot);
+
+		gaht_temp[reg] |= mask;
 	}
-	out_be32(&p->gaht1, gaht[0]);
-	out_be32(&p->gaht2, gaht[1]);
-	out_be32(&p->gaht3, gaht[2]);
-	out_be32(&p->gaht4, gaht[3]);
+
+	for (i = 0; i < regs; i++)
+		out_be32(gaht_base + i, gaht_temp[i]);
 }
 
 static inline u32 emac_iff2rmr(struct net_device *ndev)
@@ -398,7 +404,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
 
 	if (ndev->flags & IFF_PROMISC)
 		r |= EMAC_RMR_PME;
-	else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+	else if (ndev->flags & IFF_ALLMULTI ||
+			 (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
 		r |= EMAC_RMR_PMME;
 	else if (ndev->mc_count > 0)
 		r |= EMAC_RMR_MAE;
@@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev)
 			/* Put some arbitrary OUI, Manuf & Rev IDs so we can
 			 * identify this GPCS PHY later.
 			 */
-			out_be32(&p->ipcr, 0xdeadbeef);
+			out_be32(&p->u1.emac4.ipcr, 0xdeadbeef);
 		} else
 			mr1 |= EMAC_MR1_MF_1000;
 
@@ -2015,10 +2022,10 @@ static int emac_get_regs_len(struct emac_instance *dev)
 {
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC4_ETHTOOL_REGS_SIZE;
+			EMAC4_ETHTOOL_REGS_SIZE(dev);
 	else
 		return sizeof(struct emac_ethtool_regs_subhdr) +
-			EMAC_ETHTOOL_REGS_SIZE;
+			EMAC_ETHTOOL_REGS_SIZE(dev);
 }
 
 static int emac_ethtool_get_regs_len(struct net_device *ndev)
@@ -2045,12 +2052,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
 	hdr->index = dev->cell_index;
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
 		hdr->version = EMAC4_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
 	} else {
 		hdr->version = EMAC_ETHTOOL_REGS_VER;
-		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
-		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+		memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
+		return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
 	}
 }
 
@@ -2540,7 +2547,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 
 	/* Check EMAC version */
-	if (of_device_is_compatible(np, "ibm,emac4")) {
+	if (of_device_is_compatible(np, "ibm,emac4sync")) {
+		dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
+	} else if (of_device_is_compatible(np, "ibm,emac4")) {
 		dev->features |= EMAC_FTR_EMAC4;
 		if (of_device_is_compatible(np, "ibm,emac-440gx"))
 			dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
@@ -2601,6 +2610,15 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 	memcpy(dev->ndev->dev_addr, p, 6);
 
+	/* IAHT and GAHT filter parameterization */
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
+		dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT;
+	} else {
+		dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT;
+		dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT;
+	}
+
 	DBG(dev, "features     : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE);
 	DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige);
 	DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige);
@@ -2672,7 +2690,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
 		goto err_irq_unmap;
 	}
 	// TODO : request_mem_region
-	dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs));
+	dev->emacp = ioremap(dev->rsrc_regs.start,
+			     dev->rsrc_regs.end - dev->rsrc_regs.start + 1);
 	if (dev->emacp == NULL) {
 		printk(KERN_ERR "%s: Can't map device registers!\n",
 		       np->full_name);
@@ -2884,6 +2903,10 @@ static struct of_device_id emac_match[] =
 		.type		= "network",
 		.compatible	= "ibm,emac4",
 	},
+	{
+		.type		= "network",
+		.compatible	= "ibm,emac4sync",
+	},
 	{},
 };
 
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 1683db9..70794cd 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -235,6 +235,10 @@ struct emac_instance {
 	u32				fifo_entry_size;
 	u32				mal_burst_size; /* move to MAL ? */
 
+	/* IAHT and GAHT filter parameterization */
+	u32				xaht_slots_shift;
+	u32				xaht_width_shift;
+
 	/* Descriptor management
 	 */
 	struct mal_descriptor		*tx_desc;
@@ -309,6 +313,10 @@ struct emac_instance {
  * Set if we need phy clock workaround for 440ep or 440gr
  */
 #define EMAC_FTR_440EP_PHY_CLK_FIX	0x00000100
+/*
+ * The 405EX and 460EX contain the EMAC4SYNC core
+ */
+#define EMAC_FTR_EMAC4SYNC		0x00000200
 
 
 /* Right now, we don't quite handle the always/possible masks on the
@@ -320,7 +328,8 @@ enum {
 
 	EMAC_FTRS_POSSIBLE	=
 #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
-	    EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
+	    EMAC_FTR_EMAC4	| EMAC_FTR_EMAC4SYNC	|
+	    EMAC_FTR_HAS_NEW_STACR	|
 	    EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_TAH
@@ -342,6 +351,71 @@ static inline int emac_has_feature(struct emac_instance *dev,
 	       (EMAC_FTRS_POSSIBLE & dev->features & feature);
 }
 
+/*
+ * Various instances of the EMAC core have varying 1) number of
+ * address match slots, 2) width of the registers for handling address
+ * match slots, 3) number of registers for handling address match
+ * slots and 4) base offset for those registers.
+ *
+ * These macros and inlines handle these differences based on
+ * parameters supplied by the device structure which are, in turn,
+ * initialized based on the "compatible" entry in the device tree.
+ */
+
+#define	EMAC4_XAHT_SLOTS_SHIFT		6
+#define	EMAC4_XAHT_WIDTH_SHIFT		4
+
+#define	EMAC4SYNC_XAHT_SLOTS_SHIFT	8
+#define	EMAC4SYNC_XAHT_WIDTH_SHIFT	5
+
+#define	EMAC_XAHT_SLOTS(dev)         	(1 << (dev)->xaht_slots_shift)
+#define	EMAC_XAHT_WIDTH(dev)         	(1 << (dev)->xaht_width_shift)
+#define	EMAC_XAHT_REGS(dev)          	(1 << ((dev)->xaht_slots_shift - \
+					       (dev)->xaht_width_shift))
+
+#define	EMAC_XAHT_CRC_TO_SLOT(dev, crc)			\
+	((EMAC_XAHT_SLOTS(dev) - 1) -			\
+	 ((crc) >> ((sizeof (u32) * BITS_PER_BYTE) -	\
+		    (dev)->xaht_slots_shift)))
+
+#define	EMAC_XAHT_SLOT_TO_REG(dev, slot)		\
+	((slot) >> (dev)->xaht_width_shift)
+
+#define	EMAC_XAHT_SLOT_TO_MASK(dev, slot)		\
+	((u32)(1 << (EMAC_XAHT_WIDTH(dev) - 1)) >>	\
+	 ((slot) & (u32)(EMAC_XAHT_WIDTH(dev) - 1)))
+
+static inline u32 *emac_xaht_base(struct emac_instance *dev)
+{
+	struct emac_regs __iomem *p = dev->emacp;
+	int offset;
+
+	/* The first IAHT entry always is the base of the block of
+	 * IAHT and GAHT registers.
+	 */
+	if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC))
+		offset = offsetof(struct emac_regs, u1.emac4sync.iaht1);
+	else
+		offset = offsetof(struct emac_regs, u0.emac4.iaht1);
+
+	return ((u32 *)((ptrdiff_t)p + offset));
+}
+
+static inline u32 *emac_gaht_base(struct emac_instance *dev)
+{
+	/* GAHT registers always come after an identical number of
+	 * IAHT registers.
+	 */
+	return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev));
+}
+
+static inline u32 *emac_iaht_base(struct emac_instance *dev)
+{
+	/* IAHT registers always come before an identical number of
+	 * GAHT registers.
+	 */
+	return (emac_xaht_base(dev));
+}
 
 /* Ethtool get_regs complex data.
  * We want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
@@ -366,4 +440,11 @@ struct emac_ethtool_regs_subhdr {
 	u32 index;
 };
 
+#define EMAC_ETHTOOL_REGS_VER		0
+#define EMAC_ETHTOOL_REGS_SIZE(dev) 	((dev)->rsrc_regs.end - \
+					 (dev)->rsrc_regs.start + 1)
+#define EMAC4_ETHTOOL_REGS_VER      	1
+#define EMAC4_ETHTOOL_REGS_SIZE(dev)	((dev)->rsrc_regs.end -	\
+					 (dev)->rsrc_regs.start + 1)
+
 #endif /* __IBM_NEWEMAC_CORE_H */
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c
index 86b756a..775c850 100644
--- a/drivers/net/ibm_newemac/debug.c
+++ b/drivers/net/ibm_newemac/debug.c
@@ -67,29 +67,55 @@ static void emac_desc_dump(struct emac_instance *p)
 static void emac_mac_dump(struct emac_instance *dev)
 {
 	struct emac_regs __iomem *p = dev->emacp;
+	const int xaht_regs = EMAC_XAHT_REGS(dev);
+	u32 *gaht_base = emac_gaht_base(dev);
+	u32 *iaht_base = emac_iaht_base(dev);
+	int emac4sync = emac_has_feature(dev, EMAC_FTR_EMAC4SYNC);
+	int n;
 
 	printk("** EMAC %s registers **\n"
 	       "MR0 = 0x%08x MR1 = 0x%08x TMR0 = 0x%08x TMR1 = 0x%08x\n"
 	       "RMR = 0x%08x ISR = 0x%08x ISER = 0x%08x\n"
-	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n"
-	       "IAHT: 0x%04x 0x%04x 0x%04x 0x%04x "
-	       "GAHT: 0x%04x 0x%04x 0x%04x 0x%04x\n"
-	       "LSA = %04x%08x IPGVR = 0x%04x\n"
-	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
-	       "OCTX = 0x%08x OCRX = 0x%08x IPCR = 0x%08x\n",
+	       "IAR = %04x%08x VTPID = 0x%04x VTCI = 0x%04x\n",
 	       dev->ofdev->node->full_name, in_be32(&p->mr0), in_be32(&p->mr1),
 	       in_be32(&p->tmr0), in_be32(&p->tmr1),
 	       in_be32(&p->rmr), in_be32(&p->isr), in_be32(&p->iser),
 	       in_be32(&p->iahr), in_be32(&p->ialr), in_be32(&p->vtpid),
-	       in_be32(&p->vtci),
-	       in_be32(&p->iaht1), in_be32(&p->iaht2), in_be32(&p->iaht3),
-	       in_be32(&p->iaht4),
-	       in_be32(&p->gaht1), in_be32(&p->gaht2), in_be32(&p->gaht3),
-	       in_be32(&p->gaht4),
+	       in_be32(&p->vtci)
+	       );
+
+	if (emac4sync)
+		printk("MAR = %04x%08x MMAR = %04x%08x\n",
+		       in_be32(&p->u0.emac4sync.mahr),
+		       in_be32(&p->u0.emac4sync.malr),
+		       in_be32(&p->u0.emac4sync.mmahr),
+		       in_be32(&p->u0.emac4sync.mmalr)
+		       );
+
+	for (n = 0; n < xaht_regs; n++)
+		printk("IAHT%02d = 0x%08x\n", n + 1, in_be32(iaht_base + n));
+
+	for (n = 0; n < xaht_regs; n++)
+		printk("GAHT%02d = 0x%08x\n", n + 1, in_be32(gaht_base + n));
+
+	printk("LSA = %04x%08x IPGVR = 0x%04x\n"
+	       "STACR = 0x%08x TRTR = 0x%08x RWMR = 0x%08x\n"
+	       "OCTX = 0x%08x OCRX = 0x%08x\n",
 	       in_be32(&p->lsah), in_be32(&p->lsal), in_be32(&p->ipgvr),
 	       in_be32(&p->stacr), in_be32(&p->trtr), in_be32(&p->rwmr),
-	       in_be32(&p->octx), in_be32(&p->ocrx), in_be32(&p->ipcr)
-	    );
+	       in_be32(&p->octx), in_be32(&p->ocrx)
+	       );
+
+	if (!emac4sync) {
+		printk("IPCR = 0x%08x\n",
+		       in_be32(&p->u1.emac4.ipcr)
+		       );
+	} else {
+		printk("REVID = 0x%08x TPC = 0x%08x\n",
+		       in_be32(&p->u1.emac4sync.revid),
+		       in_be32(&p->u1.emac4sync.tpc)
+		       );
+	}
 
 	emac_desc_dump(dev);
 }
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index 91cb096..0afc2cf 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -27,37 +27,80 @@
 
 #include <linux/types.h>
 
-/* EMAC registers 		Write Access rules */
+/* EMAC registers 			Write Access rules */
 struct emac_regs {
-	u32 mr0;		/* special 	*/
-	u32 mr1;		/* Reset 	*/
-	u32 tmr0;		/* special 	*/
-	u32 tmr1;		/* special 	*/
-	u32 rmr;		/* Reset 	*/
-	u32 isr;		/* Always 	*/
-	u32 iser;		/* Reset 	*/
-	u32 iahr;		/* Reset, R, T 	*/
-	u32 ialr;		/* Reset, R, T 	*/
-	u32 vtpid;		/* Reset, R, T 	*/
-	u32 vtci;		/* Reset, R, T 	*/
-	u32 ptr;		/* Reset,    T 	*/
-	u32 iaht1;		/* Reset, R	*/
-	u32 iaht2;		/* Reset, R	*/
-	u32 iaht3;		/* Reset, R	*/
-	u32 iaht4;		/* Reset, R	*/
-	u32 gaht1;		/* Reset, R	*/
-	u32 gaht2;		/* Reset, R	*/
-	u32 gaht3;		/* Reset, R	*/
-	u32 gaht4;		/* Reset, R	*/
+	/* Common registers across all EMAC implementations. */
+	u32 mr0;			/* Special 	*/
+	u32 mr1;			/* Reset 	*/
+	u32 tmr0;			/* Special 	*/
+	u32 tmr1;			/* Special 	*/
+	u32 rmr;			/* Reset 	*/
+	u32 isr;			/* Always 	*/
+	u32 iser;			/* Reset 	*/
+	u32 iahr;			/* Reset, R, T 	*/
+	u32 ialr;			/* Reset, R, T 	*/
+	u32 vtpid;			/* Reset, R, T 	*/
+	u32 vtci;			/* Reset, R, T 	*/
+	u32 ptr;			/* Reset,    T 	*/
+	union {
+		/* Registers unique to EMAC4 implementations */
+		struct {
+			u32 iaht1;	/* Reset, R	*/
+			u32 iaht2;	/* Reset, R	*/
+			u32 iaht3;	/* Reset, R	*/
+			u32 iaht4;	/* Reset, R	*/
+			u32 gaht1;	/* Reset, R	*/
+			u32 gaht2;	/* Reset, R	*/
+			u32 gaht3;	/* Reset, R	*/
+			u32 gaht4;	/* Reset, R	*/
+		} emac4;
+		/* Registers unique to EMAC4SYNC implementations */
+		struct {
+			u32 mahr;	/* Reset, R, T  */
+			u32 malr;	/* Reset, R, T  */
+			u32 mmahr;	/* Reset, R, T  */
+			u32 mmalr;	/* Reset, R, T  */
+			u32 rsvd0[4];
+		} emac4sync;
+	} u0;
+	/* Common registers across all EMAC implementations. */
 	u32 lsah;
 	u32 lsal;
-	u32 ipgvr;		/* Reset,    T 	*/
-	u32 stacr;		/* special 	*/
-	u32 trtr;		/* special 	*/
-	u32 rwmr;		/* Reset 	*/
+	u32 ipgvr;			/* Reset,    T 	*/
+	u32 stacr;			/* Special 	*/
+	u32 trtr;			/* Special 	*/
+	u32 rwmr;			/* Reset 	*/
 	u32 octx;
 	u32 ocrx;
-	u32 ipcr;
+	union {
+		/* Registers unique to EMAC4 implementations */
+		struct {
+			u32 ipcr;
+		} emac4;
+		/* Registers unique to EMAC4SYNC implementations */
+		struct {
+			u32 rsvd1;
+			u32 revid;
+ 			u32 rsvd2[2];
+			u32 iaht1;	/* Reset, R     */
+			u32 iaht2;	/* Reset, R     */
+			u32 iaht3;	/* Reset, R     */
+			u32 iaht4;	/* Reset, R     */
+			u32 iaht5;	/* Reset, R     */
+			u32 iaht6;	/* Reset, R     */
+			u32 iaht7;	/* Reset, R     */
+			u32 iaht8;	/* Reset, R     */
+			u32 gaht1;	/* Reset, R     */
+			u32 gaht2;	/* Reset, R     */
+			u32 gaht3;	/* Reset, R     */
+			u32 gaht4;	/* Reset, R     */
+			u32 gaht5;	/* Reset, R     */
+			u32 gaht6;	/* Reset, R     */
+			u32 gaht7;	/* Reset, R     */
+			u32 gaht8;	/* Reset, R     */
+			u32 tpc;	/* Reset, T     */
+		} emac4sync;
+	} u1;
 };
 
 /*
@@ -73,12 +116,6 @@ struct emac_regs {
 #define PHY_MODE_RTBI	7
 #define PHY_MODE_SGMII	8
 
-
-#define EMAC_ETHTOOL_REGS_VER		0
-#define EMAC_ETHTOOL_REGS_SIZE		(sizeof(struct emac_regs) - sizeof(u32))
-#define EMAC4_ETHTOOL_REGS_VER      	1
-#define EMAC4_ETHTOOL_REGS_SIZE		sizeof(struct emac_regs)
-
 /* EMACx_MR0 */
 #define EMAC_MR0_RXI			0x80000000
 #define EMAC_MR0_TXI			0x40000000

^ permalink raw reply related

* Re: [PATCH] Add MPC5200B base board mvBC-P
From: David Gibson @ 2008-07-06 23:50 UTC (permalink / raw)
  To: Andre Schwarz; +Cc: linux-ppc list
In-Reply-To: <486E515B.80508@matrix-vision.de>

On Fri, Jul 04, 2008 at 06:35:39PM +0200, Andre Schwarz wrote:
> The mvBlueCOUGAR-P is a MPC5200B based camera system with Intel Gigabit ethernet
> controller (using e1000). It's just another MPC5200_simple board.
> 
> Signed-off-by: Andre Schwarz <andre.schwarz@matrix-vision.de>
[snip]
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/mvbc-p.dts
> @@ -0,0 +1,206 @@

[snip]
> +		dma-controller@1200 {
> +			device_type = "dma-controller";

No device_type here.

> +			compatible = "fsl,mpc5200-bestcomm";
> +			reg = <0x1200 0x80>;
> +			interrupts = <3 0 0  3 1 0  3 2 0  3 3 0
> +				3 4 0  3 5 0  3 6 0  3 7 0
> +				3 8 0  3 9 0  3 10 0  3 11 0
> +				3 12 0  3 13 0  3 14 0  3 15 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +		};
> +
> +		xlb@1f00 {
> +			compatible = "fsl,mpc5200-xlb";
> +			reg = <0x1f00 0x100>;
> +		};
> +
> +		serial0: serial@2000 {		// PSC1
> +			device_type = "serial";
> +			compatible = "fsl,mpc5200-psc-uart";
> +			port-number = <0>;
> +			reg = <0x2000 0x100>;
> +			interrupts = <2 1 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +		};
> +
> +		i2c@3d00 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "fsl,mpc5200-i2c","fsl-i2c";
> +			reg = <0x3d00 0x40>;
> +			interrupts = <2 15 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +			fsl5200-clocking;
> +		};
> +
> +		i2c@3d40 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "fsl,mpc5200-i2c","fsl-i2c";
> +			reg = <0x3d40 0x40>;
> +			interrupts = <2 16 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +			fsl5200-clocking;
> +		};
> +		sram@8000 {
> +			compatible = "fsl,mpc5200-sram","sram";
> +			reg = <0x8000 0x4000>;
> +		};
> +	};

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] [POWERPC] 52xx: add missing MSCAN FDT nodes for TQM52xx
From: David Gibson @ 2008-07-06 23:53 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: Linuxppc-dev
In-Reply-To: <486B50D8.5000009@grandegger.com>

On Wed, Jul 02, 2008 at 11:56:40AM +0200, Wolfgang Grandegger wrote:
> This patch adds the still missing FDT nodes for the MSCAN devices for
> the TQM52xx modules.
>
> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
> ---
> arch/powerpc/boot/dts/tqm5200.dts |   16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> Index: linux-2.6-galak/arch/powerpc/boot/dts/tqm5200.dts
> ===================================================================
> --- linux-2.6-galak.orig/arch/powerpc/boot/dts/tqm5200.dts
> +++ linux-2.6-galak/arch/powerpc/boot/dts/tqm5200.dts
> @@ -70,6 +70,22 @@
> 			fsl,has-wdt;
> 		};
>
> +		can@900 {
> +			compatible = "fsl,mpc5200-mscan";
> +			cell-index = <0>;

What shared resource are these cell-index values used to index into?
Because cell-index is so freqeuntly misunderstood, I strongly
recommend putting a comment describing this.

> +			interrupts = <2 17 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +			reg = <0x900 0x80>;
> +		};
> +
> +		can@980 {
> +			compatible = "fsl,mpc5200-mscan";
> +			cell-index = <1>;
> +			interrupts = <2 18 0>;
> +			interrupt-parent = <&mpc5200_pic>;
> +			reg = <0x980 0x80>;
> +		};
> +
> 		gpio@b00 {
> 			compatible = "fsl,mpc5200-gpio";
> 			reg = <0xb00 0x40>;
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
From: Michael Ellerman @ 2008-07-07  0:00 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Paul Mackerras, cbe-oss-dev, linuxppc-dev
In-Reply-To: <200807052351.39945.arnd@arndb.de>

[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]

On Sat, 2008-07-05 at 23:51 +0200, Arnd Bergmann wrote:
> On Saturday 05 July 2008, Benjamin Herrenschmidt wrote:
> > On Sat, 2008-07-05 at 15:43 +1000, Michael Ellerman wrote:
> > > > The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> > > > (for both the dynamic and fixed mappings) which enforces strong ordering of
> > > > both reads and writes. This patch makes the default behaviour weak ordering
> > > > (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> > > > new DMA_ATTR_STRONG_ORDERING needs to be used.
> > > 
> > > We're sure that's safe?
> > 
> > I'd say it's not...
> 
> It turned out that the firmware sets up the south bridge to never set the 'S'
> bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
> existing cell hardware.

It seems strange to me that the southbridge is allowed to override the
setting in the IOMMU page table, but if that's what the doc says ..

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* dtc: Enable and fix -Wpointer-arith warnings
From: David Gibson @ 2008-07-07  0:10 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

This patch turns on the -Wpointer-arith option in the dtc Makefile,
and fixes the resulting warnings due to using (void *) in pointer
arithmetic.  While convenient, pointer arithmetic on void * is not
portable, so it's better that we avoid it, particularly in libfdt.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/Makefile
===================================================================
--- dtc.orig/Makefile	2008-07-04 11:48:05.000000000 +1000
+++ dtc/Makefile	2008-07-04 16:54:42.000000000 +1000
@@ -16,7 +16,7 @@
 CONFIG_LOCALVERSION =
 
 CPPFLAGS = -I libfdt
-CFLAGS = -Wall -g -Os
+CFLAGS = -Wall -g -Os -Wpointer-arith
 
 CPPFLAGS += -std=c99 -D_XOPEN_SOURCE -D_BSD_SOURCE
 CFLAGS += -Werror
Index: dtc/libfdt/fdt.c
===================================================================
--- dtc.orig/libfdt/fdt.c	2008-07-04 13:13:49.000000000 +1000
+++ dtc/libfdt/fdt.c	2008-07-04 14:04:05.000000000 +1000
@@ -76,7 +76,7 @@
 
 const void *fdt_offset_ptr(const void *fdt, int offset, int len)
 {
-	const void *p;
+	const char *p;
 
 	if (fdt_version(fdt) >= 0x11)
 		if (((offset + len) < offset)
Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c	2008-07-04 13:13:17.000000000 +1000
+++ dtc/libfdt/fdt_ro.c	2008-07-04 16:54:42.000000000 +1000
@@ -408,10 +408,10 @@
 					     &phandle, sizeof(phandle));
 }
 
-int _stringlist_contains(const void *strlist, int listlen, const char *str)
+int _stringlist_contains(const char *strlist, int listlen, const char *str)
 {
 	int len = strlen(str);
-	const void *p;
+	const char *p;
 
 	while (listlen >= len) {
 		if (memcmp(str, strlist, len+1) == 0)
Index: dtc/libfdt/libfdt_internal.h
===================================================================
--- dtc.orig/libfdt/libfdt_internal.h	2008-07-04 13:11:47.000000000 +1000
+++ dtc/libfdt/libfdt_internal.h	2008-07-04 16:54:42.000000000 +1000
@@ -72,7 +72,7 @@
 
 static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
 {
-	return fdt + fdt_off_dt_struct(fdt) + offset;
+	return (const char *)fdt + fdt_off_dt_struct(fdt) + offset;
 }
 
 static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
@@ -82,8 +82,8 @@
 
 static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
 {
-	const struct fdt_reserve_entry *rsv_table =
-		fdt + fdt_off_mem_rsvmap(fdt);
+	const struct fdt_reserve_entry *rsv_table = (struct fdt_reserve_entry *)
+		((const char *)fdt + fdt_off_mem_rsvmap(fdt));
 
 	return rsv_table + n;
 }
Index: dtc/libfdt/fdt_sw.c
===================================================================
--- dtc.orig/libfdt/fdt_sw.c	2008-07-04 13:15:50.000000000 +1000
+++ dtc/libfdt/fdt_sw.c	2008-07-04 14:04:33.000000000 +1000
@@ -121,7 +121,7 @@
 	if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
 		return -FDT_ERR_NOSPACE;
 
-	re = (struct fdt_reserve_entry *)(fdt + offset);
+	re = (struct fdt_reserve_entry *)((char *)fdt + offset);
 	re->address = cpu_to_fdt64(addr);
 	re->size = cpu_to_fdt64(size);
 
Index: dtc/libfdt/fdt_wip.c
===================================================================
--- dtc.orig/libfdt/fdt_wip.c	2008-07-04 13:15:06.000000000 +1000
+++ dtc/libfdt/fdt_wip.c	2008-07-04 14:05:42.000000000 +1000
@@ -76,7 +76,7 @@
 {
 	uint32_t *p;
 
-	for (p = start; (void *)p < (start + len); p++)
+	for (p = start; (char *)p < ((char *)start + len); p++)
 		*p = cpu_to_fdt32(FDT_NOP);
 }
 
Index: dtc/libfdt/fdt_rw.c
===================================================================
--- dtc.orig/libfdt/fdt_rw.c	2008-07-04 13:25:22.000000000 +1000
+++ dtc/libfdt/fdt_rw.c	2008-07-04 16:54:42.000000000 +1000
@@ -94,13 +94,14 @@
 	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 }
 
-static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
+static int _blob_splice(void *fdt, void *splicepoint, int oldlen, int newlen)
 {
-	void *end = fdt + _blob_data_size(fdt);
+	char *p = splicepoint;
+	char *end = (char *)fdt + _blob_data_size(fdt);
 
 	if (((p + oldlen) < p) || ((p + oldlen) > end))
 		return -FDT_ERR_BADOFFSET;
-	if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
+	if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
 		return -FDT_ERR_NOSPACE;
 	memmove(p + newlen, p + oldlen, end - p - oldlen);
 	return 0;
@@ -135,7 +136,8 @@
 
 static int _blob_splice_string(void *fdt, int newlen)
 {
-	void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
+	void *p = (char *)fdt
+		+ fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
 	int err;
 
 	if ((err = _blob_splice(fdt, p, 0, newlen)))
@@ -338,7 +340,7 @@
 	nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
 	memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
 	memcpy(nh->name, name, namelen);
-	endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
+	endtag = (uint32_t *)((char *)nh + nodelen - FDT_TAGSIZE);
 	*endtag = cpu_to_fdt32(FDT_END_NODE);
 
 	return offset;
@@ -363,7 +365,7 @@
 				   endoffset - nodeoffset, 0);
 }
 
-static void _packblocks(const void *fdt, void *buf,
+static void _packblocks(const char *old, char *new,
 		       int mem_rsv_size, int struct_size)
 {
 	int mem_rsv_off, struct_off, strings_off;
@@ -372,17 +374,17 @@
 	struct_off = mem_rsv_off + mem_rsv_size;
 	strings_off = struct_off + struct_size;
 
-	memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
-	fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
+	memmove(new + mem_rsv_off, old + fdt_off_mem_rsvmap(old), mem_rsv_size);
+	fdt_set_off_mem_rsvmap(new, mem_rsv_off);
 
-	memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
-	fdt_set_off_dt_struct(buf, struct_off);
-	fdt_set_size_dt_struct(buf, struct_size);
-
-	memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
-		fdt_size_dt_strings(fdt));
-	fdt_set_off_dt_strings(buf, strings_off);
-	fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
+	memmove(new + struct_off, old + fdt_off_dt_struct(old), struct_size);
+	fdt_set_off_dt_struct(new, struct_off);
+	fdt_set_size_dt_struct(new, struct_size);
+
+	memmove(new + strings_off, old + fdt_off_dt_strings(old),
+		fdt_size_dt_strings(old));
+	fdt_set_off_dt_strings(new, strings_off);
+	fdt_set_size_dt_strings(new, fdt_size_dt_strings(old));
 }
 
 int fdt_open_into(const void *fdt, void *buf, int bufsize)
@@ -390,7 +392,9 @@
 	int err;
 	int mem_rsv_size, struct_size;
 	int newsize;
-	void *tmp;
+	const char *fdtstart = fdt;
+	const char *fdtend = fdtstart + fdt_totalsize(fdt);
+	char *tmp;
 
 	CHECK_HEADER(fdt);
 
@@ -423,12 +427,13 @@
 	if (bufsize < newsize)
 		return -FDT_ERR_NOSPACE;
 
-	if (((buf + newsize) <= fdt)
-	    || (buf >= (fdt + fdt_totalsize(fdt)))) {
-		tmp = buf;
-	} else {
-		tmp = (void *)fdt + fdt_totalsize(fdt);
-		if ((tmp + newsize) > (buf + bufsize))
+	/* First attempt to build converted tree at beginning of buffer */
+	tmp = buf;
+	/* But if that overlaps with the old tree... */
+	if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
+		/* Try right after the old tree instead */
+		tmp = (char *)fdtend;
+		if ((tmp + newsize) > ((char *)buf + bufsize))
 			return -FDT_ERR_NOSPACE;
 	}
 
Index: dtc/ftdump.c
===================================================================
--- dtc.orig/ftdump.c	2008-07-04 13:42:44.000000000 +1000
+++ dtc/ftdump.c	2008-07-04 16:54:42.000000000 +1000
@@ -70,9 +70,9 @@
 	uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
 	uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
 	struct fdt_reserve_entry *p_rsvmap =
-		(struct fdt_reserve_entry *)(blob + off_mem_rsvmap);
-	char *p_struct = blob + off_dt;
-	char *p_strings = blob + off_str;
+		(struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
+	char *p_struct = (char *)blob + off_dt;
+	char *p_strings = (char *)blob + off_str;
 	uint32_t version = fdt32_to_cpu(bph->version);
 	uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
 	uint32_t tag;
Index: dtc/tests/incbin.c
===================================================================
--- dtc.orig/tests/incbin.c	2008-07-04 13:47:25.000000000 +1000
+++ dtc/tests/incbin.c	2008-07-04 13:48:00.000000000 +1000
@@ -31,10 +31,10 @@
 
 #define CHUNKSIZE	1024
 
-void *load_file(const char *name, int *len)
+char *load_file(const char *name, int *len)
 {
 	FILE *f;
-	void *buf = NULL;
+	char *buf = NULL;
 	int bufsize = 0, n;
 
 	*len = 0;
@@ -60,7 +60,8 @@
 
 int main(int argc, char *argv[])
 {
-	void *fdt, *incbin;
+	void *fdt;
+	char *incbin;
 	int len;
 
 	test_init(argc, argv);
Index: dtc/tests/mangle-layout.c
===================================================================
--- dtc.orig/tests/mangle-layout.c	2008-07-04 13:44:25.000000000 +1000
+++ dtc/tests/mangle-layout.c	2008-07-04 14:27:52.000000000 +1000
@@ -31,7 +31,7 @@
 #include "testdata.h"
 
 struct bufstate {
-	void *buf;
+	char *buf;
 	int size;
 };
 
@@ -73,7 +73,7 @@
 	case 'm':
 		/* Memory reserve map */
 		align = 8;
-		src = fdt + fdt_off_mem_rsvmap(fdt);
+		src = (const char *)fdt + fdt_off_mem_rsvmap(fdt);
 		size = (fdt_num_mem_rsv(fdt) + 1)
 			* sizeof(struct fdt_reserve_entry);
 		break;
@@ -81,14 +81,14 @@
 	case 't':
 		/* Structure block */
 		align = 4;
-		src = fdt + fdt_off_dt_struct(fdt);
+		src = (const char *)fdt + fdt_off_dt_struct(fdt);
 		size = fdt_size_dt_struct(fdt);
 		break;
 
 	case 's':
 		/* Strings block */
 		align = 1;
-		src = fdt + fdt_off_dt_strings(fdt);
+		src = (const char *)fdt + fdt_off_dt_strings(fdt);
 		size = fdt_size_dt_strings(fdt);
 		break;
 	default:
Index: dtc/tests/move_and_save.c
===================================================================
--- dtc.orig/tests/move_and_save.c	2008-07-04 13:44:04.000000000 +1000
+++ dtc/tests/move_and_save.c	2008-07-04 14:09:34.000000000 +1000
@@ -33,7 +33,7 @@
 int main(int argc, char *argv[])
 {
 	void *fdt, *fdt1, *fdt2, *fdt3;
-	void *buf;
+	char *buf;
 	int shuntsize;
 	int bufsize;
 	int err;
Index: dtc/tests/nopulate.c
===================================================================
--- dtc.orig/tests/nopulate.c	2008-07-04 13:45:22.000000000 +1000
+++ dtc/tests/nopulate.c	2008-07-04 14:09:52.000000000 +1000
@@ -30,7 +30,7 @@
 #include "tests.h"
 #include "testdata.h"
 
-int nopulate_struct(char *buf, const void *fdt)
+int nopulate_struct(char *buf, const char *fdt)
 {
 	int offset, nextoffset = 0;
 	uint32_t tag;
@@ -42,7 +42,7 @@
 		offset = nextoffset;
 		tag = fdt_next_tag(fdt, offset, &nextoffset);
 
-		memcpy(p, fdt + fdt_off_dt_struct(fdt) + offset,
+		memcpy(p, (const char *)fdt + fdt_off_dt_struct(fdt) + offset,
 		       nextoffset - offset);
 		p += nextoffset - offset;
 
@@ -56,8 +56,7 @@
 
 int main(int argc, char *argv[])
 {
-	void *fdt, *fdt2;
-	void *buf;
+	char *fdt, *fdt2, *buf;
 	int newsize, struct_start, struct_end_old, struct_end_new, delta;
 	const char *inname;
 	char outname[PATH_MAX];
Index: dtc/tests/testutils.c
===================================================================
--- dtc.orig/tests/testutils.c	2008-07-04 13:43:43.000000000 +1000
+++ dtc/tests/testutils.c	2008-07-04 14:10:05.000000000 +1000
@@ -200,7 +200,7 @@
 	int fd;
 	int totalsize;
 	int offset;
-	void *p;
+	char *p;
 	int ret;
 
 	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* dtc: Enable and fix -Wcast-qual warnings
From: David Gibson @ 2008-07-07  0:14 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

Enabling -Wcast-qual warnings in dtc shows up a number of places where
we are incorrectly discarding a const qualification.  There are also
some places where we are intentionally discarding the 'const', and we
need an ugly cast through uintptr_t to suppress the warning.  However,
most of these are pretty well isolated with the *_w() functions.  So
in the interests of maximum safety with const qualifications, this
patch enables the warnings and fixes the existing complaints.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/Makefile
===================================================================
--- dtc.orig/Makefile	2008-07-04 16:54:38.000000000 +1000
+++ dtc/Makefile	2008-07-04 16:54:38.000000000 +1000
@@ -16,7 +16,7 @@
 CONFIG_LOCALVERSION =
 
 CPPFLAGS = -I libfdt
-CFLAGS = -Wall -g -Os -Wpointer-arith
+CFLAGS = -Wall -g -Os -Wpointer-arith -Wcast-qual
 
 CPPFLAGS += -std=c99 -D_XOPEN_SOURCE -D_BSD_SOURCE
 CFLAGS += -Werror
Index: dtc/ftdump.c
===================================================================
--- dtc.orig/ftdump.c	2008-07-04 16:54:38.000000000 +1000
+++ dtc/ftdump.c	2008-07-04 16:54:38.000000000 +1000
@@ -48,11 +48,11 @@
 		return;
 
 	if (is_printable_string(data, len)) {
-		printf(" = \"%s\"", (char *)data);
+		printf(" = \"%s\"", (const char *)data);
 	} else if ((len % 4) == 0) {
 		printf(" = <");
 		for (i = 0; i < len; i += 4)
-			printf("%08x%s", *((uint32_t *)data + i),
+			printf("%08x%s", *((const uint32_t *)data + i),
 			       i < (len - 4) ? " " : "");
 		printf(">");
 	} else {
Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c	2008-07-04 16:54:38.000000000 +1000
+++ dtc/treesource.c	2008-07-04 16:54:38.000000000 +1000
@@ -176,7 +176,7 @@
 		}
 
 		fprintf(f, "%02hhx", *bp++);
-		if ((void *)bp >= propend)
+		if ((const void *)bp >= propend)
 			break;
 		fprintf(f, " ");
 	}
Index: dtc/libfdt/fdt_ro.c
===================================================================
--- dtc.orig/libfdt/fdt_ro.c	2008-07-04 16:54:38.000000000 +1000
+++ dtc/libfdt/fdt_ro.c	2008-07-04 16:54:38.000000000 +1000
@@ -77,7 +77,7 @@
 
 const char *fdt_string(const void *fdt, int stroffset)
 {
-	return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
+	return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
Index: dtc/libfdt/libfdt.h
===================================================================
--- dtc.orig/libfdt/libfdt.h	2008-07-04 16:54:38.000000000 +1000
+++ dtc/libfdt/libfdt.h	2008-07-04 16:54:38.000000000 +1000
@@ -125,7 +125,7 @@
 const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
 static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
 {
-	return (void *)fdt_offset_ptr(fdt, offset, checklen);
+	return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen);
 }
 
 uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
@@ -375,8 +375,8 @@
 						      const char *name,
 						      int *lenp)
 {
-	return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
-						       name, lenp);
+	return (struct fdt_property *)(uintptr_t)
+		fdt_get_property(fdt, nodeoffset, name, lenp);
 }
 
 /**
@@ -411,7 +411,7 @@
 static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
 				  const char *name, int *lenp)
 {
-	return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
+	return (void *)(uintptr_t)fdt_getprop(fdt, nodeoffset, name, lenp);
 }
 
 /**
Index: dtc/libfdt/libfdt_internal.h
===================================================================
--- dtc.orig/libfdt/libfdt_internal.h	2008-07-04 16:54:38.000000000 +1000
+++ dtc/libfdt/libfdt_internal.h	2008-07-04 16:54:38.000000000 +1000
@@ -77,19 +77,20 @@
 
 static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
 {
-	return (void *)_fdt_offset_ptr(fdt, offset);
+	return (void *)(uintptr_t)_fdt_offset_ptr(fdt, offset);
 }
 
 static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
 {
-	const struct fdt_reserve_entry *rsv_table = (struct fdt_reserve_entry *)
+	const struct fdt_reserve_entry *rsv_table =
+		(const struct fdt_reserve_entry *)
 		((const char *)fdt + fdt_off_mem_rsvmap(fdt));
 
 	return rsv_table + n;
 }
 static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
 {
-	return (void *)_fdt_mem_rsv(fdt, n);
+	return (void *)(uintptr_t)_fdt_mem_rsv(fdt, n);
 }
 
 #define SW_MAGIC		(~FDT_MAGIC)
Index: dtc/libfdt/fdt_rw.c
===================================================================
--- dtc.orig/libfdt/fdt_rw.c	2008-07-04 16:54:38.000000000 +1000
+++ dtc/libfdt/fdt_rw.c	2008-07-04 16:54:38.000000000 +1000
@@ -257,7 +257,7 @@
 
 	RW_CHECK_HEADER(fdt);
 
-	namep = (char *)fdt_get_name(fdt, nodeoffset, &oldlen);
+	namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen);
 	if (!namep)
 		return oldlen;
 
@@ -432,7 +432,7 @@
 	/* But if that overlaps with the old tree... */
 	if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
 		/* Try right after the old tree instead */
-		tmp = (char *)fdtend;
+		tmp = (char *)(uintptr_t)fdtend;
 		if ((tmp + newsize) > ((char *)buf + bufsize))
 			return -FDT_ERR_NOSPACE;
 	}

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] [POWERPC] 52xx: add missing MSCAN FDT nodes for TQM52xx
From: Grant Likely @ 2008-07-07  0:26 UTC (permalink / raw)
  To: Wolfgang Grandegger, Linuxppc-dev
In-Reply-To: <20080706235328.GB6267@yookeroo.seuss>

On Sun, Jul 6, 2008 at 5:53 PM, David Gibson
<david@gibson.dropbear.id.au> wrote:
> On Wed, Jul 02, 2008 at 11:56:40AM +0200, Wolfgang Grandegger wrote:
>> This patch adds the still missing FDT nodes for the MSCAN devices for
>> the TQM52xx modules.
>>
>> Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
>> ---
>> arch/powerpc/boot/dts/tqm5200.dts |   16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>>
>> Index: linux-2.6-galak/arch/powerpc/boot/dts/tqm5200.dts
>> ===================================================================
>> --- linux-2.6-galak.orig/arch/powerpc/boot/dts/tqm5200.dts
>> +++ linux-2.6-galak/arch/powerpc/boot/dts/tqm5200.dts
>> @@ -70,6 +70,22 @@
>>                       fsl,has-wdt;
>>               };
>>
>> +             can@900 {
>> +                     compatible = "fsl,mpc5200-mscan";
>> +                     cell-index = <0>;
>
> What shared resource are these cell-index values used to index into?
> Because cell-index is so freqeuntly misunderstood, I strongly
> recommend putting a comment describing this.

This is still my fault.  The lite5200.dts which everyone uses as the
example to go by for 5200 board ports still has it, so everyone just
copies it.  I'll look at fixing all of them up.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: the printk problem
From: Benjamin Herrenschmidt @ 2008-07-07  1:14 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-ia64, linuxppc-dev, Peter Anvin, Andrew Morton,
	David S. Miller, parisc-linux
In-Reply-To: <alpine.LFD.1.10.0807041622270.2815@woody.linux-foundation.org>

On Fri, 2008-07-04 at 16:25 -0700, Linus Torvalds wrote:
> 
> On Sat, 5 Jul 2008, Benjamin Herrenschmidt wrote:
> > 
> > I'll give it a try using probe_kernel_address() instead on monday.
> 
> Here's the updated patch which uses probe_kernel_address() instead (and 
> moves the whole #ifdef mess out of the code that wants it and into a 
> helper function - and maybe we should then put that helper into 
> kallsyms.h, but that's a different issue).
> 
> Still all happily untested, of course. And still with no actual users 
> converted.

Did a few tests and it seems to work. I'll stick a patch converting
powerpc to use %pS for oops display in -next.

Thanks !

Cheers,
Ben.

^ permalink raw reply

* dtc: Run relevant checks on dtb input as well as dts
From: David Gibson @ 2008-07-07  1:19 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev

This patch adjusts the testsuite to run most of the tests for the tree
checking code on input in dtb form as well as dts form.  Some checks
which only make sense for dts input (like reference handling) are
excluded, as are those which currently take dtb input because they
rely on things which cannot be lexically constructed in a dts file.

This shows up two small bugs in dtc, which are also corrected.

First, the name_properties test which was is supposed to remove
correctly formed 'name' properties (because they can be reconstructed
from tne node name) was instead removing 'name' properties even if
they weren't correct.

Secondly, when using dtb or fs input, the runtime tree in dtc did not
have the parent pointer initialized propertly because.built
internally.  The appropriate initialization is added to the
add_child() function.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh	2008-07-07 11:09:43.000000000 +1000
+++ dtc/tests/run_tests.sh	2008-07-07 11:09:44.000000000 +1000
@@ -115,6 +115,14 @@
     run_test del_node $TREE
 }
 
+check_tests () {
+    tree="$1"
+    shift
+    run_sh_test dtc-checkfails.sh "$@" -- -I dts -O dtb $tree
+    run_dtc_test -I dts -O dtb -o $tree.test.dtb -f $tree
+    run_sh_test dtc-checkfails.sh "$@" -- -I dtb -O dtb $tree.test.dtb
+}
+
 ALL_LAYOUTS="mts mst tms tsm smt stm"
 
 libfdt_tests () {
@@ -243,22 +251,22 @@
     done
 
     # Check some checks
-    run_sh_test dtc-checkfails.sh duplicate_node_names -- -I dts -O dtb dup-nodename.dts
-    run_sh_test dtc-checkfails.sh duplicate_property_names -- -I dts -O dtb dup-propname.dts
-    run_sh_test dtc-checkfails.sh explicit_phandles -- -I dts -O dtb dup-phandle.dts
-    run_sh_test dtc-checkfails.sh explicit_phandles -- -I dts -O dtb zero-phandle.dts
-    run_sh_test dtc-checkfails.sh explicit_phandles -- -I dts -O dtb minusone-phandle.dts
+    check_tests dup-nodename.dts duplicate_node_names
+    check_tests dup-propname.dts duplicate_property_names
+    check_tests dup-phandle.dts explicit_phandles
+    check_tests zero-phandle.dts explicit_phandles
+    check_tests minusone-phandle.dts explicit_phandles
     run_sh_test dtc-checkfails.sh phandle_references -- -I dts -O dtb nonexist-node-ref.dts
     run_sh_test dtc-checkfails.sh phandle_references -- -I dts -O dtb nonexist-label-ref.dts
-    run_sh_test dtc-checkfails.sh name_properties -- -I dts -O dtb bad-name-property.dts
+    check_tests bad-name-property.dts name_properties
 
-    run_sh_test dtc-checkfails.sh address_cells_is_cell size_cells_is_cell interrupt_cells_is_cell -- -I dts -O dtb bad-ncells.dts
-    run_sh_test dtc-checkfails.sh device_type_is_string model_is_string status_is_string -- -I dts -O dtb bad-string-props.dts
-    run_sh_test dtc-checkfails.sh reg_format ranges_format -- -I dts -O dtb bad-reg-ranges.dts
-    run_sh_test dtc-checkfails.sh ranges_format -- -I dts -O dtb bad-empty-ranges.dts
-    run_sh_test dtc-checkfails.sh reg_format ranges_format -- -I dts -O dtb reg-ranges-root.dts
-    run_sh_test dtc-checkfails.sh avoid_default_addr_size -- -I dts -O dtb default-addr-size.dts
-    run_sh_test dtc-checkfails.sh obsolete_chosen_interrupt_controller -- -I dts -O dtb obsolete-chosen-interrupt-controller.dts
+    check_tests bad-ncells.dts address_cells_is_cell size_cells_is_cell interrupt_cells_is_cell
+    check_tests bad-string-props.dts device_type_is_string model_is_string status_is_string
+    check_tests bad-reg-ranges.dts reg_format ranges_format
+    check_tests bad-empty-ranges.dts ranges_format
+    check_tests reg-ranges-root.dts reg_format ranges_format
+    check_tests default-addr-size.dts avoid_default_addr_size
+    check_tests obsolete-chosen-interrupt-controller.dts obsolete_chosen_interrupt_controller
     run_sh_test dtc-checkfails.sh node_name_chars -- -I dtb -O dtb bad_node_char.dtb
     run_sh_test dtc-checkfails.sh node_name_format -- -I dtb -O dtb bad_node_format.dtb
     run_sh_test dtc-checkfails.sh prop_name_chars -- -I dtb -O dtb bad_prop_char.dtb
Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c	2008-07-07 11:11:27.000000000 +1000
+++ dtc/checks.c	2008-07-07 11:11:46.000000000 +1000
@@ -328,15 +328,17 @@
 		return; /* No name property, that's fine */
 
 	if ((prop->val.len != node->basenamelen+1)
-	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
+	    || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
 		FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
 		     " of base node name)", node->fullpath, prop->val.val);
-
-	/* The name property is correct, and therefore redundant.  Delete it */
-	*pp = prop->next;
-	free(prop->name);
-	data_free(prop->val);
-	free(prop);
+	} else {
+		/* The name property is correct, and therefore redundant.
+		 * Delete it */
+		*pp = prop->next;
+		free(prop->name);
+		data_free(prop->val);
+		free(prop);
+	}
 }
 CHECK_IS_STRING(name_is_string, "name", ERROR);
 NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
Index: dtc/livetree.c
===================================================================
--- dtc.orig/livetree.c	2008-07-07 11:12:12.000000000 +1000
+++ dtc/livetree.c	2008-07-07 11:12:19.000000000 +1000
@@ -115,6 +115,7 @@
 	struct node **p;
 
 	child->next_sibling = NULL;
+	child->parent = parent;
 
 	p = &parent->children;
 	while (*p)

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: Merging seperate FDT-blobs?
From: David Gibson @ 2008-07-07  1:28 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linuxppc-dev
In-Reply-To: <20080627170547.GF3931@pengutronix.de>

[-- Attachment #1: Type: text/plain, Size: 7506 bytes --]

On Fri, Jun 27, 2008 at 07:05:47PM +0200, Wolfram Sang wrote:
> Hello David,
> 
> On Mon, Jun 23, 2008 at 03:06:24PM +1000, David Gibson wrote:
> 
> > Hrm.  I was assuming this would be handled by the code putting things
> > together, rather than being encoded into the fragments.  I envisaged
> > something like:
> > 
> > 	int fdt_graft(void *fdt, int parentoffset, const char *name,
> > 		      void *fragment);
> > 
> > This would attach the tree fragment in the blob at 'fragment' into the
> > tree 'fdt', with fragment's root gaining the name 'name' and being a
> > child of the existing node at 'parentoffset'.
> 
> This function is surely needed in every case I considered so far. I am
> just sceptical if the boot-loader can determine a correct parentoffset
> all alone (which one of the two I2C busses is the correct one?). This is

Hrm.  "all alone".  It's not clear to me what else there could be that
would have more information than the bootloader.

> why I added the property "external-name" as a helping hand. Meanwhile, I
> found your proposal about handling the aliases-node
> (http://ozlabs.org/pipermail/linuxppc-dev/2007-November/045778.html) 
> and think it will be a better alternative (as mentioned below).
> 
> > > 2) How to deal with phandles?
> > >    The fragment does not know anything about phandles from the main
> > >    tree, so it cannot use them, although it needs to for a number of
> > >    typical fdt-entries.
> > 
> > Ah.  This is harder.  And there are two sub-pieces to this problem.
> > First, how to ensure that any phandles for nodes in the fragment don't
> > collide with phandles from the parent tree or other included
> > fragments.  Second, how to fixup phandle references in between
> > initially separate fragments.
> 
> > As an asside, I think going through the grafted fragment and adjusting
> > phandles to avoid collisions is a no-goer.  Any new binding can
> > potentially introduce a new property in which phandles appear, so we
> > can't really know where to look for phandles and adjust.
> 
> True. I didn't take into account that phandles may show up anywhere,
> even in a field of cells. Sigh, I wish phandles had some marker tag
> (no, I don't expect this to happen).
> 
> > So, for the first part, for now, I think the sanest way to handle this
> > for now is simply to require that the fragments have non-overlapping
> > phandles.  For example by specifically allocating different ranges for
> > different fragments when assembling a collection of such things.
> > There are problems with this approach, and we may need something
> > better, but I think it's where we need to start.
> 
> > At the moment that will require manually assigning all phandles, but
> > we could extend dtc with a directive giving the range in which to
> > assign phandles.
> 
> So, if dtc has the possibility to specify a range for phandles, every
> fragment gets its own "namespace" for phandles. Handles which are
> clearly not leaving the namespace can still be referenced using the
> convenient <&phandle> syntax. Every phandle which needs to be accessed
> from different namespaces, has to be hardcoded, preferably in their own
> hardcoded namespace (e.g. linux,phandle = <0xfffffxyz>). Nice thing is,
> that it still can be assigned a dtc-label, so referencing inside the
> same source is also easy to maintain. Using macro features, one could
> even use #defines for the hardcoded values.

Exactly.  It's not perfect, but I think it's an ok compromise of
convenience of use and simplicity of implementation.  At least as a
first step.

> Still, I sense some practical issues. I guess I need to sketch some
> more possible constellations to get an even bigger picture. Problem is
> as often: if you get generic, you get complexity.
> 
> > Hrm.  I don't really follow the point of this scheme.  It seems like
> > you're encoding how to assemble the fragments into the master
> > fragment.
> 
> What I encoded using "external-name" is where possible fragments
> _could_ be added to. Something like a mount-point. The boot-loader
> decides if and what could be mounted there. As an "/aliases" node is
> already in use, I would favour to add such mount-points there.

Hrm.  I'm not convinced that the mount point model is actually a good
one.  I would have thought that one of the most common things to graft
would be extra optional devices onto a bus.  In this case there's no
specific "mountpoint"  the device could be attached at any valid
address on the bus in question.

> > But the whole point of assembling fragments is that the
> > master can encode several different trees depending what's included,
> > which means something else needs to decide whether they're merged or
> > not.  I think just provide fdt_graft() as above, and leave the
> > decisions about where and whether to the assembly code in the wrapper
> > or bootloader.
> 
> I assume the main tagret for this criticism is the "externals"-node I
> introduced at the very end. I agree that its functionality could be
> transferred to the boot-loader (e.g. give the boot-loader a list of
> addresses to check for potential eeproms). I wouldn't mind dropping the
> "externals" node; sounds in deed a bit cleaner.
> 
> > This doesn't work for properties which include phandles but are not
> > simply a single phandle; 'interrupt-map' for example.
> 
> Check mate :(
> 
> > We'll need property iteration for this, which we don't currently have.
> > But I've been intending to implement that for a while anyway.
> 
> I am quite sure it will come handy on the way nontheless.
> 
> > 
> > > 		propname = property without 'phandle-for-';
> > > 
> > > 		name = fdt_getprop(external_fdt, cur_node, property);
> > > 
> > > 		phandle_offset = fdt_node_offset_by_prop_value(main_fdt, "external-name", name)
> > > 		phandle = fdt_get_phandle(main_fdt, phandle_offset);
> > > 
> > > 		fdt_setprop(external_fdt, propname, phandle);
> > > 		copy_prop_to_main_fdt();
> > > 	}
> > 
> > Hrm.  This doesn't seem all that useful.  It only handles adjusting
> > phandle references that are in the external tree pointing into one of
> > the fragments.  Since the fragments more-or-less by definition aren't
> > always present, this is an unlikely use case.  What I *can* see
> > happening is things within the fragments wanting to refer to an
> > always-present piece of hardware outside - the main interrupt
> > controller, in particular.
> 
> Ehrm, most likely my example was not clear enough, I am sorry. The case
> of a fragment wanting to reach the main interrupt controller was exactly
> what I had in mind when writing this. For completeness, I will try to
> clear it up, although it won't work, as stated before: The
> 'phandle-for-*' property is in the fragment. It's value (let's say
> 'pic-0') is taken from the fragment. An apropriate mount-point (set by
> 'external-name = "pic-0"' in the main tree) is searched in the main
> tree.  The phandle of the mount point is taked from the main tree. This
> value will become the new phandle inside the fragment pointing to the
> main tree. In the end, the whole fragment will be grafted into the main
> tree, of course.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: New fsl device bindings file
From: David Gibson @ 2008-07-07  1:39 UTC (permalink / raw)
  To: Olof Johansson; +Cc: Scott Wood, linuxppc-dev list
In-Reply-To: <8C77F02F-E930-40EB-AE25-F959C40833B3@lixom.net>

On Sat, Jul 05, 2008 at 12:24:56AM -0500, Olof Johansson wrote:
>
> On Jul 3, 2008, at 1:34 PM, Grant Likely wrote:
>
>>> How about splitting up like this:
>>>
>>> Documentation/powerpc/device-tree/fsl/cpm.txt
>>> Documentation/powerpc/device-tree/fsl/cpm/uart.txt
>>> Documentation/powerpc/device-tree/fsl/tsec.txt
>>> Documentation/powerpc/device-tree/interrupts.txt
>>> Documentation/powerpc/device-tree/dtb.txt
>>
>> May I suggest moving it to Documentation/of-bindings/ instead?  Some
>> of these bindings (granted, not the fsl ones) will be used by
>> non-powerpc platforms (sparc, microblaze).
>
> Good idea, but:
>
> Don't call the bindings OF. They're not.
>
> They are a linux-specific binding that happens to use the same data  
> structures and representation that OF does.

Well... they may be Linux specific by default, but they're supposed to
be general enough that they (or at least, very small extensions)
*could* become official OF bindings, if there was still an OF group to
make them so.  It certainly should be possible to use these bindings
in a firmware which provides an OF client interface as well as in
flat-tree-only firmwares which don't.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: New fsl device bindings file
From: Olof Johansson @ 2008-07-07  1:45 UTC (permalink / raw)
  To: David Gibson; +Cc: Scott Wood, linuxppc-dev list
In-Reply-To: <20080707013902.GI6267@yookeroo.seuss>


On Jul 6, 2008, at 8:39 PM, David Gibson wrote:

> Well... they may be Linux specific by default, but they're supposed to
> be general enough that they (or at least, very small extensions)
> *could* become official OF bindings, if there was still an OF group to
> make them so.  It certainly should be possible to use these bindings
> in a firmware which provides an OF client interface as well as in
> flat-tree-only firmwares which don't.

Right, it's a classic case of embrace and extend. Calling it OF is  
just plain misleading, especially since the original document was  
called booting _WITHOUT_ OF.


-Olof

^ permalink raw reply

* Re: the printk problem
From: Stephen Rothwell @ 2008-07-07  3:26 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1215393276.8970.36.camel@pasglop>

[-- Attachment #1: Type: text/plain, Size: 1036 bytes --]

On Mon, 07 Jul 2008 11:14:36 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Fri, 2008-07-04 at 16:25 -0700, Linus Torvalds wrote:
> > 
> > On Sat, 5 Jul 2008, Benjamin Herrenschmidt wrote:
> > > 
> > > I'll give it a try using probe_kernel_address() instead on monday.
> > 
> > Here's the updated patch which uses probe_kernel_address() instead (and 
> > moves the whole #ifdef mess out of the code that wants it and into a 
> > helper function - and maybe we should then put that helper into 
> > kallsyms.h, but that's a different issue).
> > 
> > Still all happily untested, of course. And still with no actual users 
> > converted.
> 
> Did a few tests and it seems to work. I'll stick a patch converting
> powerpc to use %pS for oops display in -next.

After you post it to linuxppc-dev and get review comments, of course ...

And after the patch to make %pS work goes in ...
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: the printk problem
From: Michael Ellerman @ 2008-07-07  3:28 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc-dev
In-Reply-To: <20080707132615.f6b6247b.sfr@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 1379 bytes --]

On Mon, 2008-07-07 at 13:26 +1000, Stephen Rothwell wrote:
> On Mon, 07 Jul 2008 11:14:36 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> >
> > On Fri, 2008-07-04 at 16:25 -0700, Linus Torvalds wrote:
> > > 
> > > On Sat, 5 Jul 2008, Benjamin Herrenschmidt wrote:
> > > > 
> > > > I'll give it a try using probe_kernel_address() instead on monday.
> > > 
> > > Here's the updated patch which uses probe_kernel_address() instead (and 
> > > moves the whole #ifdef mess out of the code that wants it and into a 
> > > helper function - and maybe we should then put that helper into 
> > > kallsyms.h, but that's a different issue).
> > > 
> > > Still all happily untested, of course. And still with no actual users 
> > > converted.
> > 
> > Did a few tests and it seems to work. I'll stick a patch converting
> > powerpc to use %pS for oops display in -next.
> 
> After you post it to linuxppc-dev and get review comments, of course ...
> 
> And after the patch to make %pS work goes in ...

Wasn't that already merged via the trivial scheduler fixes tree or
something? ;)

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox