All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/6] m68k: simplify the singlestepping handling in signals
From: Al Viro @ 2010-10-07 17:09 UTC (permalink / raw)
  To: linux-m68k; +Cc: linux-kernel


Instead of checking the return value of do_signal() we can just do
the work (raise SIGTRAP and clear SR.T1) directly in handle_signal(),
when setting the sigframe up.  Simplifies the assembler glue and is
closer to the way we do it on other targets.

Note that do_delayed_trace does *not* disappear; it's still needed
to deal with single-stepping through syscall, since 68040 doesn't
raise the trace exception at all if the trap exception is pending.
We hit it after returning from sys_...() if TIF_DELAYED_TRACE is
set; all that has changed is that we don't reuse it for "single-step
into the handler" codepath.

As the result, do_signal() doesn't need to return anything anymore.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/m68k/kernel/entry.S  |    6 +-----
 arch/m68k/kernel/signal.c |   11 +++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 3a15a03..4e49f57 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -178,11 +178,7 @@ do_signal_return:
 	addql	#4,%sp
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
-	tstl	%d0
-	jeq	resume_userspace
-	| when single stepping into handler stop at the first insn
-	btst	#6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
-	jeq	resume_userspace
+	jbra	resume_userspace
 
 do_delayed_trace:
 	bclr	#7,%sp@(PT_OFF_SR)	| clear trace bit in SR
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index fa8200d..a18b251 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -978,6 +978,11 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	if (!(ka->sa.sa_flags & SA_NODEFER))
 		sigaddset(&current->blocked,sig);
 	recalc_sigpending();
+
+	if (test_thread_flag(TIF_DELAYED_TRACE)) {
+		regs->sr &= ~0x8000;
+		send_sig(SIGTRAP, current, 1);
+	}
 }
 
 /*
@@ -985,7 +990,7 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-asmlinkage int do_signal(struct pt_regs *regs)
+asmlinkage void do_signal(struct pt_regs *regs)
 {
 	siginfo_t info;
 	struct k_sigaction ka;
@@ -1004,7 +1009,7 @@ asmlinkage int do_signal(struct pt_regs *regs)
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
-		return 1;
+		return;
 	}
 
 	/* Did we come from a system call? */
@@ -1017,6 +1022,4 @@ asmlinkage int do_signal(struct pt_regs *regs)
 		clear_thread_flag(TIF_RESTORE_SIGMASK);
 		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 	}
-
-	return 0;
 }
-- 
1.5.6.5

^ permalink raw reply related

* [refpolicy] [ patch 24/44] shutdown: Fedora change.
From: Christopher J. PeBenito @ 2010-10-07 17:09 UTC (permalink / raw)
  To: refpolicy
In-Reply-To: <1286216636-28449-26-git-send-email-domg472@gmail.com>

On 10/04/10 14:23, Dominick Grift wrote:
>
> Signed-off-by: Dominick Grift<domg472@gmail.com>

Merged.

> :100644 100644 9174268... 97671a3... M	policy/modules/admin/shutdown.fc
>   policy/modules/admin/shutdown.fc |    4 +++-
>   1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/policy/modules/admin/shutdown.fc b/policy/modules/admin/shutdown.fc
> index 9174268..97671a3 100644
> --- a/policy/modules/admin/shutdown.fc
> +++ b/policy/modules/admin/shutdown.fc
> @@ -1,5 +1,7 @@
>   /etc/nologin		--	gen_context(system_u:object_r:shutdown_etc_t,s0)
>
> +/lib/upstart/shutdown	--	gen_context(system_u:object_r:shutdown_exec_t,s0)
> +
>   /sbin/shutdown		--	gen_context(system_u:object_r:shutdown_exec_t,s0)
>
> -/var/run/shutdown\.pid 	--	gen_context(system_u:object_r:shutdown_var_run_t,s0)
> +/var/run/shutdown\.pid	--	gen_context(system_u:object_r:shutdown_var_run_t,s0)


-- 
Chris PeBenito
Tresys Technology, LLC
www.tresys.com | oss.tresys.com

^ permalink raw reply

* [PATCH 4/6] m68k: don't lose state if sigframe setup fails
From: Al Viro @ 2010-10-07 17:09 UTC (permalink / raw)
  To: linux-m68k; +Cc: linux-kernel


If we'd failed in setup_frame(), we've no place to store
the original sigmask.  It's not an unrecoverable situation -
we raise SIGSEGV, but that SIGSEGV might be successfully
handled (e.g. on altstack).  In that case we really don't
want sa_mask of original signal permanently slapped on
the set of blocked signals.

Standard solution: have setup_frame()/setup_rt_frame()
report failure and don't mess with the signal-related
state if that has happened...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/m68k/kernel/signal.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index a18b251..a6dd614 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -743,7 +743,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 	return (void __user *)((usp - frame_size) & -8UL);
 }
 
-static void setup_frame (int sig, struct k_sigaction *ka,
+static int setup_frame (int sig, struct k_sigaction *ka,
 			 sigset_t *set, struct pt_regs *regs)
 {
 	struct sigframe __user *frame;
@@ -813,14 +813,14 @@ adjust_stack:
 		tregs->pc = regs->pc;
 		tregs->sr = regs->sr;
 	}
-	return;
+	return err;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
 	goto adjust_stack;
 }
 
-static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 			    sigset_t *set, struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
@@ -901,7 +901,7 @@ adjust_stack:
 		tregs->pc = regs->pc;
 		tregs->sr = regs->sr;
 	}
-	return;
+	return err;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
@@ -963,6 +963,7 @@ static void
 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
+	int err;
 	/* are we from a system call? */
 	if (regs->orig_d0 >= 0)
 		/* If so, check system call restarting.. */
@@ -970,9 +971,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 
 	/* set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		err = setup_rt_frame(sig, ka, info, oldset, regs);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		err = setup_frame(sig, ka, oldset, regs);
+
+	if (err)
+		return;
 
 	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 	if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -983,6 +987,8 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
 		regs->sr &= ~0x8000;
 		send_sig(SIGTRAP, current, 1);
 	}
+
+	clear_thread_flag(TIF_RESTORE_SIGMASK);
 }
 
 /*
@@ -1008,7 +1014,6 @@ asmlinkage void do_signal(struct pt_regs *regs)
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &ka, &info, oldset, regs);
-		clear_thread_flag(TIF_RESTORE_SIGMASK);
 		return;
 	}
 
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH 5/6] m68k: if we fail to set sigframe up, just leave regs alone...
From: Al Viro @ 2010-10-07 17:10 UTC (permalink / raw)
  To: linux-m68k; +Cc: linux-kernel


Same principle as with the previous patch - do not destroy the
state if sigframe setup fails.  Incidentally, it's actually
_less_ work - we don't need to go through adjust_stack dance
on failure if we don't touch regs->stkadj until we know we'd
written sigframe out.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/m68k/kernel/signal.c |   44 ++++++++++++++++++++++++++++++--------------
 1 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index a6dd614..16ea319 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -761,10 +761,8 @@ static int setup_frame (int sig, struct k_sigaction *ka,
 
 	frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
 
-	if (fsize) {
+	if (fsize)
 		err |= copy_to_user (frame + 1, regs + 1, fsize);
-		regs->stkadj = fsize;
-	}
 
 	err |= __put_user((current_thread_info()->exec_domain
 			   && current_thread_info()->exec_domain->signal_invmap
@@ -794,11 +792,21 @@ static int setup_frame (int sig, struct k_sigaction *ka,
 
 	push_cache ((unsigned long) &frame->retcode);
 
-	/* Set up registers for signal handler */
+	/*
+	 * Set up registers for signal handler.  All the state we are about
+	 * to destroy is successfully copied to sigframe.
+	 */
 	wrusp ((unsigned long) frame);
 	regs->pc = (unsigned long) ka->sa.sa_handler;
 
-adjust_stack:
+	/*
+	 * This is subtle; if we build more than one sigframe, all but the
+	 * first one will see frame format 0 and have fsize == 0, so we won't
+	 * screw stkadj.
+	 */
+	if (fsize)
+		regs->stkadj = fsize;
+
 	/* Prepare to skip over the extra stuff in the exception frame.  */
 	if (regs->stkadj) {
 		struct pt_regs *tregs =
@@ -813,11 +821,11 @@ adjust_stack:
 		tregs->pc = regs->pc;
 		tregs->sr = regs->sr;
 	}
-	return err;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
-	goto adjust_stack;
+	return err;
 }
 
 static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -837,10 +845,8 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 
 	frame = get_sigframe(ka, regs, sizeof(*frame));
 
-	if (fsize) {
+	if (fsize)
 		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
-		regs->stkadj = fsize;
-	}
 
 	err |= __put_user((current_thread_info()->exec_domain
 			   && current_thread_info()->exec_domain->signal_invmap
@@ -882,11 +888,21 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 
 	push_cache ((unsigned long) &frame->retcode);
 
-	/* Set up registers for signal handler */
+	/*
+	 * Set up registers for signal handler.  All the state we are about
+	 * to destroy is successfully copied to sigframe.
+	 */
 	wrusp ((unsigned long) frame);
 	regs->pc = (unsigned long) ka->sa.sa_handler;
 
-adjust_stack:
+	/*
+	 * This is subtle; if we build more than one sigframe, all but the
+	 * first one will see frame format 0 and have fsize == 0, so we won't
+	 * screw stkadj.
+	 */
+	if (fsize)
+		regs->stkadj = fsize;
+
 	/* Prepare to skip over the extra stuff in the exception frame.  */
 	if (regs->stkadj) {
 		struct pt_regs *tregs =
@@ -901,11 +917,11 @@ adjust_stack:
 		tregs->pc = regs->pc;
 		tregs->sr = regs->sr;
 	}
-	return err;
+	return 0;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
-	goto adjust_stack;
+	return err;
 }
 
 static inline void
-- 
1.5.6.5

^ permalink raw reply related

* [PATCH 6/6] m68k: fix stack mangling logics in sigreturn
From: Al Viro @ 2010-10-07 17:10 UTC (permalink / raw)
  To: linux-m68k; +Cc: linux-kernel


a) we should hold modifying regs->format until we know we *will* be
doing stack expansion; otherwise attacker can modify sigframe to
have wrong ->sc_formatvec and install SIGSEGV handler.

b) we should *not* mix copying saved extra stuff from userland with
expanding the stack; once we'd done that manual memmove, we'd better
not return to C, so cleanup is very hard to do.  The easiest way
is to copy it on stack first, making sure we won't overwrite on stack
expansion.  Fortunately that's easy to do...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 arch/m68k/kernel/signal.c |  173 ++++++++++++++++-----------------------------
 1 files changed, 61 insertions(+), 112 deletions(-)

diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 16ea319..d5f4a82 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -286,36 +286,10 @@ out:
 	return err;
 }
 
-static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
-		   int *pd0)
+static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
+			       void __user *fp)
 {
-	int fsize, formatvec;
-	struct sigcontext context;
-	int err;
-
-	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
-	/* get previous context */
-	if (copy_from_user(&context, usc, sizeof(context)))
-		goto badframe;
-
-	/* restore passed registers */
-	regs->d1 = context.sc_d1;
-	regs->a0 = context.sc_a0;
-	regs->a1 = context.sc_a1;
-	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
-	regs->pc = context.sc_pc;
-	regs->orig_d0 = -1;		/* disable syscall checks */
-	wrusp(context.sc_usp);
-	formatvec = context.sc_formatvec;
-	regs->format = formatvec >> 12;
-	regs->vector = formatvec & 0xfff;
-
-	err = restore_fpu_state(&context);
-
-	fsize = frame_extra_sizes[regs->format];
+	int fsize = frame_extra_sizes[formatvec >> 12];
 	if (fsize < 0) {
 		/*
 		 * user process trying to return with weird frame format
@@ -323,16 +297,22 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
 #ifdef DEBUG
 		printk("user process returning with weird frame format\n");
 #endif
-		goto badframe;
+		return 1;
 	}
+	if (!fsize) {
+		regs->format = formatvec >> 12;
+		regs->vector = formatvec & 0xfff;
+	} else {
+		struct switch_stack *sw = (struct switch_stack *)regs - 1;
+		unsigned long buf[fsize / 2]; /* yes, twice as much */
 
-	/* OK.	Make room on the supervisor stack for the extra junk,
-	 * if necessary.
-	 */
+		/* that'll make sure that expansion won't crap over data */
+		if (copy_from_user(buf + fsize / 4, fp, fsize))
+			return 1;
 
-	if (fsize) {
-		struct switch_stack *sw = (struct switch_stack *)regs - 1;
-		regs->d0 = context.sc_d0;
+		/* point of no return */
+		regs->format = formatvec >> 12;
+		regs->vector = formatvec & 0xfff;
 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
 		__asm__ __volatile__
 			("   movel %0,%/a0\n\t"
@@ -344,30 +324,50 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
 			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
 			 "   lsrl  #2,%1\n\t"
 			 "   subql #1,%1\n\t"
-			 "2: movesl %4@+,%2\n\t"
-			 "3: movel %2,%/a0@+\n\t"
+			 /* copy to the gap we'd made */
+			 "2: movel %4@+,%/a0@+\n\t"
 			 "   dbra %1,2b\n\t"
 			 "   bral ret_from_signal\n"
-			 "4:\n"
-			 ".section __ex_table,\"a\"\n"
-			 "   .align 4\n"
-			 "   .long 2b,4b\n"
-			 "   .long 3b,4b\n"
-			 ".previous"
 			 : /* no outputs, it doesn't ever return */
 			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
-			   "n" (frame_offset), "a" (fp)
+			   "n" (frame_offset), "a" (buf + fsize/4)
 			 : "a0");
 #undef frame_offset
-		/*
-		 * If we ever get here an exception occurred while
-		 * building the above stack-frame.
-		 */
-		goto badframe;
 	}
+	return 0;
+}
 
-	*pd0 = context.sc_d0;
-	return err;
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)
+{
+	int formatvec;
+	struct sigcontext context;
+	int err;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	/* get previous context */
+	if (copy_from_user(&context, usc, sizeof(context)))
+		goto badframe;
+
+	/* restore passed registers */
+	regs->d0 = context.sc_d0;
+	regs->d1 = context.sc_d1;
+	regs->a0 = context.sc_a0;
+	regs->a1 = context.sc_a1;
+	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
+	regs->pc = context.sc_pc;
+	regs->orig_d0 = -1;		/* disable syscall checks */
+	wrusp(context.sc_usp);
+	formatvec = context.sc_formatvec;
+
+	err = restore_fpu_state(&context);
+
+	if (err || mangle_kernel_stack(regs, formatvec, fp))
+		goto badframe;
+
+	return 0;
 
 badframe:
 	return 1;
@@ -375,9 +375,9 @@ badframe:
 
 static inline int
 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
-		    struct ucontext __user *uc, int *pd0)
+		    struct ucontext __user *uc)
 {
-	int fsize, temp;
+	int temp;
 	greg_t __user *gregs = uc->uc_mcontext.gregs;
 	unsigned long usp;
 	int err;
@@ -411,65 +411,16 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
 	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
 	regs->orig_d0 = -1;		/* disable syscall checks */
 	err |= __get_user(temp, &uc->uc_formatvec);
-	regs->format = temp >> 12;
-	regs->vector = temp & 0xfff;
 
 	err |= rt_restore_fpu_state(uc);
 
-	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
+	if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
 		goto badframe;
 
-	fsize = frame_extra_sizes[regs->format];
-	if (fsize < 0) {
-		/*
-		 * user process trying to return with weird frame format
-		 */
-#ifdef DEBUG
-		printk("user process returning with weird frame format\n");
-#endif
+	if (mangle_kernel_stack(regs, temp, &uc->uc_extra))
 		goto badframe;
-	}
 
-	/* OK.	Make room on the supervisor stack for the extra junk,
-	 * if necessary.
-	 */
-
-	if (fsize) {
-#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
-		__asm__ __volatile__
-			("   movel %0,%/a0\n\t"
-			 "   subl %1,%/a0\n\t"     /* make room on stack */
-			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
-			 /* move switch_stack and pt_regs */
-			 "1: movel %0@+,%/a0@+\n\t"
-			 "   dbra %2,1b\n\t"
-			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
-			 "   lsrl  #2,%1\n\t"
-			 "   subql #1,%1\n\t"
-			 "2: movesl %4@+,%2\n\t"
-			 "3: movel %2,%/a0@+\n\t"
-			 "   dbra %1,2b\n\t"
-			 "   bral ret_from_signal\n"
-			 "4:\n"
-			 ".section __ex_table,\"a\"\n"
-			 "   .align 4\n"
-			 "   .long 2b,4b\n"
-			 "   .long 3b,4b\n"
-			 ".previous"
-			 : /* no outputs, it doesn't ever return */
-			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
-			   "n" (frame_offset), "a" (&uc->uc_extra)
-			 : "a0");
-#undef frame_offset
-		/*
-		 * If we ever get here an exception occurred while
-		 * building the above stack-frame.
-		 */
-		goto badframe;
-	}
-
-	*pd0 = regs->d0;
-	return err;
+	return 0;
 
 badframe:
 	return 1;
@@ -482,7 +433,6 @@ asmlinkage int do_sigreturn(unsigned long __unused)
 	unsigned long usp = rdusp();
 	struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
 	sigset_t set;
-	int d0;
 
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
@@ -496,9 +446,9 @@ asmlinkage int do_sigreturn(unsigned long __unused)
 	current->blocked = set;
 	recalc_sigpending();
 
-	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
+	if (restore_sigcontext(regs, &frame->sc, frame + 1))
 		goto badframe;
-	return d0;
+	return regs->d0;
 
 badframe:
 	force_sig(SIGSEGV, current);
@@ -512,7 +462,6 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 	unsigned long usp = rdusp();
 	struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
 	sigset_t set;
-	int d0;
 
 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
@@ -523,9 +472,9 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
 	current->blocked = set;
 	recalc_sigpending();
 
-	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
+	if (rt_restore_ucontext(regs, sw, &frame->uc))
 		goto badframe;
-	return d0;
+	return regs->d0;
 
 badframe:
 	force_sig(SIGSEGV, current);
-- 
1.5.6.5

^ permalink raw reply related

* Re: [PATCH 7/7] Add S3C2440 MCI card support
From: Sascha Hauer @ 2010-10-07 17:10 UTC (permalink / raw)
  To: Juergen Beisert; +Cc: barebox, Juergen Beisert
In-Reply-To: <1286457858-29771-8-git-send-email-jbe@pengutronix.de>

On Thu, Oct 07, 2010 at 03:24:18PM +0200, Juergen Beisert wrote:
> From: Juergen Beisert <juergen@kreuzholzen.de>
> 
> Adding MCI card support for S3C2440 CPUs. This is for reference only, as there
> is currently no user in the barebox tree. Maybe one with access to the A9M2440
> development kit can check it on his/her system.
> Checked here with my own S3C2440 based system which is not in the barebox tree.
> 
> Signed-off-by: Juergen Beisert <juergen@kreuzholzen.de>
> ---
>  arch/arm/mach-s3c24xx/include/mach/mci.h |   46 ++
>  drivers/mci/Kconfig                      |    7 +
>  drivers/mci/Makefile                     |    1 +
>  drivers/mci/s3c.c                        |  801 ++++++++++++++++++++++++++++++
>  4 files changed, 855 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-s3c24xx/include/mach/mci.h
>  create mode 100644 drivers/mci/s3c.c
> 
> diff --git a/arch/arm/mach-s3c24xx/include/mach/mci.h b/arch/arm/mach-s3c24xx/include/mach/mci.h
> new file mode 100644
> index 0000000..6ba8961
> --- /dev/null
> +++ b/arch/arm/mach-s3c24xx/include/mach/mci.h
> @@ -0,0 +1,46 @@
> +/*
> + * (C) Copyright 2010 Juergen Beisert, Pengutronix
> + *
> + * This code is partially based on u-boot code:
> + *
> + * Copyright 2008, Freescale Semiconductor, Inc
> + * Andy Fleming
> + *
> + * Based (loosely) on the Linux code
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __MACH_MMC_H_
> +#define __MACH_MMC_H_
> +
> +struct s3c_mci_platform_data {
> +	unsigned caps;	/**< supported operating modes (MMC_MODE_*) */
> +	unsigned voltages; /**< supported voltage range (MMC_VDD_*) */
> +	unsigned f_min;	/**< min operating frequency in Hz (0 -> no limit) */
> +	unsigned f_max;	/**< max operating frequency in Hz (0 -> no limit) */
> +	/* TODO */
> +	/* function to modify the voltage */
> +	/* function to switch the voltage */
> +	/* function to detect the presence of a SD card in the socket */
> +	unsigned gpio_detect;
> +	unsigned detect_invert;
> +};
> +
> +#endif /* __MACH_MMC_H_ */
> diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
> index a24ae6d..644c0a3 100644
> --- a/drivers/mci/Kconfig
> +++ b/drivers/mci/Kconfig
> @@ -34,4 +34,11 @@ config MCI_STM378X
>  	  Enable this entry to add support to read and write SD cards on a
>  	  i.MX23 based system.
>  
> +config MCI_S3C
> +	bool "S3C"
> +	depends on ARCH_S3C24xx
> +	help
> +	  Enable this entry to add support to read and write SD cards on a
> +	  Samsung S3C24xx based system.
> +
>  endif
> diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
> index e5e19b0..be18446 100644
> --- a/drivers/mci/Makefile
> +++ b/drivers/mci/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_MCI)	+= mci-core.o
>  obj-$(CONFIG_MCI_STM378X) += stm378x.o
> +obj-$(CONFIG_MCI_S3C) += s3c.o
> diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
> new file mode 100644
> index 0000000..3813be7
> --- /dev/null
> +++ b/drivers/mci/s3c.c
> @@ -0,0 +1,801 @@
> +/*
> + * Copyright (C) 2010 Juergen Beisert <juergen@kreuzholzen.de>
> + *
> + * This code is partially based on u-boot code:
> + *
> + * This code is based on various Linux and u-boot sources:
> + *  Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
> + *  Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org>
> + *  (C) Copyright 2006 by OpenMoko, Inc.
> + *  Author: Harald Welte <laforge@openmoko.org>
> + *  based on u-boot pxa MMC driver and linux/drivers/mmc/s3c2410mci.c
> + *  (C) 2005-2005 Thomas Kleffel
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +/**
> + * @file
> + * @brief MCI card host interface for S3C2440 CPU
> + */
> +
> +/* #define DEBUG */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <mci.h>
> +#include <errno.h>
> +#include <clock.h>
> +#include <asm/io.h>
> +#include <mach/mci.h>
> +#include <mach/s3c24xx-generic.h>
> +#include <mach/s3c24x0-iomap.h>
> +
> +#define SDICON 0x0
> +# define SDICON_SDRESET (1 << 8)
> +# define SDICON_MMCCLOCK (1 << 5) /* this is a clock type SD or MMC style WTF? */
> +# define SDICON_BYTEORDER (1 << 4)
> +# define SDICON_SDIOIRQ (1 << 3)
> +# define SDICON_RWAITEN (1 << 2)
> +# define SDICON_FIFORESET (1 << 1) /* reserved bit on 2440 ????? */
> +# define SDICON_CLKEN (1 << 0) /* enable/disable external clock */
> +
> +#define SDIPRE 0x4
> +
> +#define SDICMDARG 0x8
> +
> +#define SDICMDCON 0xc
> +# define SDICMDCON_ABORT (1 << 12)
> +# define SDICMDCON_WITHDATA (1 << 11)
> +# define SDICMDCON_LONGRSP (1 << 10)
> +# define SDICMDCON_WAITRSP (1 << 9)
> +# define SDICMDCON_CMDSTART (1 << 8)
> +# define SDICMDCON_SENDERHOST (1 << 6)
> +# define SDICMDCON_INDEX (0x3f)
> +
> +#define SDICMDSTAT 0x10
> +# define SDICMDSTAT_CRCFAIL (1 << 12)
> +# define SDICMDSTAT_CMDSENT (1 << 11)
> +# define SDICMDSTAT_CMDTIMEOUT (1 << 10)
> +# define SDICMDSTAT_RSPFIN (1 << 9)
> +# define SDICMDSTAT_XFERING (1 << 8)
> +# define SDICMDSTAT_INDEX (0xff)
> +
> +#define SDIRSP0 0x14
> +#define SDIRSP1 0x18
> +#define SDIRSP2 0x1C
> +#define SDIRSP3 0x20
> +
> +#define SDITIMER 0x24
> +#define SDIBSIZE 0x28
> +
> +#define SDIDCON 0x2c
> +# define SDIDCON_DS_BYTE (0 << 22)
> +# define SDIDCON_DS_HALFWORD (1 << 22)
> +# define SDIDCON_DS_WORD (2 << 22)
> +# define SDIDCON_IRQPERIOD (1 << 21)
> +# define SDIDCON_TXAFTERRESP (1 << 20)
> +# define SDIDCON_RXAFTERCMD (1 << 19)
> +# define SDIDCON_BUSYAFTERCMD (1 << 18)
> +# define SDIDCON_BLOCKMODE (1 << 17)
> +# define SDIDCON_WIDEBUS (1 << 16)
> +# define SDIDCON_DMAEN (1 << 15)
> +# define SDIDCON_STOP (0 << 14)
> +# define SDIDCON_DATSTART (1 << 14)
> +# define SDIDCON_DATMODE (3 << 12)
> +# define SDIDCON_BLKNUM (0xfff)
> +# define SDIDCON_XFER_READY    (0 << 12)
> +# define SDIDCON_XFER_CHKSTART (1 << 12)
> +# define SDIDCON_XFER_RXSTART  (2 << 12)
> +# define SDIDCON_XFER_TXSTART  (3 << 12)
> +
> +#define SDIDCNT 0x30
> +# define SDIDCNT_BLKNUM_SHIFT 12
> +
> +#define SDIDSTA 0x34
> +# define SDIDSTA_RDYWAITREQ (1 << 10)
> +# define SDIDSTA_SDIOIRQDETECT (1 << 9)
> +# define SDIDSTA_FIFOFAIL (1 << 8) /* reserved on 2440 */
> +# define SDIDSTA_CRCFAIL (1 << 7)
> +# define SDIDSTA_RXCRCFAIL (1 << 6)
> +# define SDIDSTA_DATATIMEOUT (1 << 5)
> +# define SDIDSTA_XFERFINISH (1 << 4)
> +# define SDIDSTA_BUSYFINISH (1 << 3)
> +# define SDIDSTA_SBITERR (1 << 2) /* reserved on 2410a/2440 */
> +# define SDIDSTA_TXDATAON (1 << 1)
> +# define SDIDSTA_RXDATAON (1 << 0)
> +
> +#define SDIFSTA 0x38
> +# define SDIFSTA_FIFORESET (1<<16)
> +# define SDIFSTA_FIFOFAIL (3<<14)  /* 3 is correct (2 bits) */
> +# define SDIFSTA_TFDET (1<<13)
> +# define SDIFSTA_RFDET (1<<12)
> +# define SDIFSTA_TFHALF (1<<11)
> +# define SDIFSTA_TFEMPTY (1<<10)
> +# define SDIFSTA_RFLAST (1<<9)
> +# define SDIFSTA_RFFULL (1<<8)
> +# define SDIFSTA_RFHALF (1<<7)
> +# define SDIFSTA_COUNTMASK (0x7f)
> +
> +#define SDIIMSK 0x3C
> +# define SDIIMSK_RESPONSECRC    (1<<17)
> +# define SDIIMSK_CMDSENT        (1<<16)
> +# define SDIIMSK_CMDTIMEOUT     (1<<15)
> +# define SDIIMSK_RESPONSEND     (1<<14)
> +# define SDIIMSK_READWAIT       (1<<13)
> +# define SDIIMSK_SDIOIRQ        (1<<12)
> +# define SDIIMSK_FIFOFAIL       (1<<11)
> +# define SDIIMSK_CRCSTATUS      (1<<10)
> +# define SDIIMSK_DATACRC        (1<<9)
> +# define SDIIMSK_DATATIMEOUT    (1<<8)
> +# define SDIIMSK_DATAFINISH     (1<<7)
> +# define SDIIMSK_BUSYFINISH     (1<<6)
> +# define SDIIMSK_SBITERR        (1<<5) /* reserved 2440/2410a */
> +# define SDIIMSK_TXFIFOHALF     (1<<4)
> +# define SDIIMSK_TXFIFOEMPTY    (1<<3)
> +# define SDIIMSK_RXFIFOLAST     (1<<2)
> +# define SDIIMSK_RXFIFOFULL     (1<<1)
> +# define SDIIMSK_RXFIFOHALF     (1<<0)
> +
> +#define SDIDATA 0x40
> +
> +#define CLOCKRATE_MIN (1 * 1000 * 1000)

Isn't this a bit high? I thought the initialization frequnency should be
400Khz at maximum. Or does the hardware not allow lower rates?

> +#define CLOCKRATE_MAX (480 * 1000 * 1000)
> +
> +struct s3c_mci_host {
> +	int		bus_width:2; /* 0 = 1 bit, 1 = 4 bit, 2 = 8 bit */
> +	unsigned	clock;	/* current clock in Hz */
> +	unsigned	data_size;	/* data transfer in bytes */
> +};
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct s3c_mci_host host_data;
> +
> +/**
> + * Finish a request
> + * @param hw_dev Host interface instance
> + *
> + * Just a little bit paranoia.
> + */
> +static void s3c_finish_request(struct device_d *hw_dev)
> +{
> +	/* TODO ensure the engines are stopped */
> +}
> +
> +/* TODO GPIO feature is required for this architecture */
> +static unsigned gpio_get_value(unsigned val)
> +{
> +	return 0;
> +}
> +
> +/**
> + * Detect if a card is plugged in
> + * @param hw_dev Host interface instance
> + * @return 0 if a card is plugged in
> + *
> + * Note: If there is no GPIO registered to detect if a card is present, we
> + * assume a card _is_ present.
> + */
> +static int s3c_mci_card_present(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)GET_HOST_PDATA(hw_dev);
> +	int ret;
> +
> +	if (pd->gpio_detect == 0)
> +		return 0;	/* assume the card is present */
> +
> +	ret = gpio_get_value(pd->gpio_detect) ? 0 : 1;
> +	return ret ^ pd->detect_invert;
> +}
> +
> +/**
> + * Setup a new clock frequency on this MCI bus
> + * @param hw_dev Host interface instance
> + * @param nc New clock value in Hz (can be 0)
> + * @return New clock value (may differ from 'nc')
> + */
> +static unsigned s3c_setup_clock_speed(struct device_d *hw_dev, unsigned nc)
> +{
> +	unsigned clock;
> +	uint32_t mci_psc;
> +
> +	if (nc == 0)
> +		return 0;
> +
> +	clock = s3c24xx_get_pclk();
> +	/* Calculate the required prescaler value to get the requested frequency */
> +	mci_psc = (clock + (nc >> 2)) / nc;
> +
> +	if (mci_psc > 256) {
> +		mci_psc = 256;
> +		pr_warning("SD/MMC clock might be too high!\n");
> +	}
> +
> +	writel(mci_psc - 1, hw_dev->map_base + SDIPRE);
> +
> +	return clock / mci_psc;
> +}
> +
> +/**
> + * Reset the MCI engine (the hard way)
> + * @param hw_dev Host interface instance
> + *
> + * This will reset everything in all registers of this unit!
> + */
> +static void s3c_mci_reset(struct device_d *hw_dev)
> +{
> +	/* reset the hardware */
> +	writel(SDICON_SDRESET, hw_dev->map_base + SDICON);
> +	/* wait until reset it finished */
> +	while (readl(hw_dev->map_base + SDICON) & SDICON_SDRESET)
> +		;
> +}
> +
> +/**
> + * Initialize hard and software
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance (might be NULL)
> + */
> +static int s3c_mci_initialize(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +
> +	s3c_mci_reset(hw_dev);
> +
> +	/* restore last settings */
> +	host_data->clock = s3c_setup_clock_speed(hw_dev, host_data->clock);
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +	writel(SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> +	writel(512, hw_dev->map_base + SDIBSIZE);
> +
> +	return 0;
> +}
> +
> +/**
> + * Prepare engine's bits for the next command transfer
> + * @param cmd_flags MCI's command flags
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_command_setup(unsigned cmd_flags, unsigned data_flags)
> +{
> +	uint32_t reg;
> +
> +	/* source (=host) */
> +	reg = SDICMDCON_SENDERHOST;
> +
> +	if (cmd_flags & MMC_RSP_PRESENT) {
> +		reg |= SDICMDCON_WAITRSP;
> +		pr_debug("Command with response\n");
> +	}
> +	if (cmd_flags & MMC_RSP_136) {
> +		reg |= SDICMDCON_LONGRSP;
> +		pr_debug("Command with long response\n");
> +	}
> +	if (cmd_flags & MMC_RSP_CRC)
> +		; /* FIXME */
> +	if (cmd_flags & MMC_RSP_BUSY)
> +		; /* FIXME */
> +	if (cmd_flags & MMC_RSP_OPCODE)
> +		; /* FIXME */

It's ok that these flags are not handled in the first run, but I think
the driver should issue a warning when one of these flags is set.

> +	if (data_flags != 0)
> +		reg |= SDICMDCON_WITHDATA;
> +
> +	return reg;
> +}
> +
> +/**
> + * Prepare engine's bits for the next data transfer
> + * @param hw_dev Host interface device instance
> + * @param data_flags MCI's data flags
> + * @return Register bits for this transfer
> + */
> +static uint32_t s3c_prepare_data_setup(struct device_d *hw_dev, unsigned data_flags)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +	uint32_t reg = SDIDCON_BLOCKMODE;	/* block mode only is supported */
> +
> +	if (host_data->bus_width == 1)
> +		reg |= SDIDCON_WIDEBUS;
> +
> +	/* enable any kind of data transfers on demand only */
> +	if (data_flags & MMC_DATA_WRITE)
> +		reg |= SDIDCON_TXAFTERRESP | SDIDCON_XFER_TXSTART;
> +
> +	if (data_flags & MMC_DATA_READ)
> +		reg |= SDIDCON_RXAFTERCMD | SDIDCON_XFER_RXSTART;
> +
> +	/* TODO: Support more than the 2440 CPU */
> +	reg |= SDIDCON_DS_WORD | SDIDCON_DATSTART;
> +
> +	return reg;
> +}
> +
> +/**
> + * Terminate a current running transfer
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * Note: Try to stop a running transfer. This should not happen, as all
> + * transfers must complete in this driver. But who knows... ;-)
> + */
> +static int s3c_terminate_transfer(struct device_d *hw_dev)
> +{
> +	unsigned stoptries = 3;
> +
> +	while (readl(hw_dev->map_base + SDIDSTA) & (SDIDSTA_TXDATAON | SDIDSTA_RXDATAON)) {
> +		pr_debug("Transfer still in progress.\n");
> +
> +		writel(SDIDCON_STOP, hw_dev->map_base + SDIDCON);
> +		s3c_mci_initialize(hw_dev, NULL);
> +
> +		if ((stoptries--) == 0) {
> +			pr_warning("Cannot stop the engine!\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Setup registers for data transfer
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_prepare_data_transfer(struct device_d *hw_dev, struct mci_data *data)
> +{
> +	uint32_t reg;
> +
> +	writel(data->blocksize, hw_dev->map_base + SDIBSIZE);
> +	reg = s3c_prepare_data_setup(hw_dev, data->flags);
> +	reg |= data->blocks & SDIDCON_BLKNUM;
> +	writel(reg, hw_dev->map_base + SDIDCON);
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> +	return 0;
> +}
> +
> +/**
> + * Send a command and receive the response
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_send_command(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	uint32_t reg, t1;
> +	int rc;
> +
> +	writel(0x007FFFFF, hw_dev->map_base + SDITIMER);
> +
> +	/* setup argument */
> +	writel(cmd->cmdarg, hw_dev->map_base + SDICMDARG);
> +
> +	/* setup command and transfer characteristic */
> +	reg = s3c_prepare_command_setup(cmd->resp_type, data != NULL ? data->flags : 0);
> +	reg |= cmd->cmdidx & SDICMDCON_INDEX;
> +
> +	/* run the command right now */
> +	writel(reg | SDICMDCON_CMDSTART, hw_dev->map_base + SDICMDCON);
> +	t1 = readl(hw_dev->map_base + SDICMDSTAT);
> +	/* wait until command is done */
> +	while (1) {
> +		reg = readl(hw_dev->map_base + SDICMDSTAT);
> +		/* done? */
> +		if (cmd->resp_type & MMC_RSP_PRESENT) {
> +			if (reg & SDICMDSTAT_RSPFIN) {
> +				writel(SDICMDSTAT_RSPFIN, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +				rc = 0;
> +				break;
> +			}
> +		} else {
> +			if (reg & SDICMDSTAT_CMDSENT) {
> +					writel(SDICMDSTAT_CMDSENT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +					rc = 0;
> +					break;
> +			}
> +		}
> +		/* timeout? */
> +		if (reg & SDICMDSTAT_CMDTIMEOUT) {
> +			writel(SDICMDSTAT_CMDTIMEOUT, hw_dev->map_base + SDICMDSTAT); /* required??? */
> +			rc = -ETIMEDOUT;
> +			break;
> +		}
> +	}
> +
> +	if ((rc == 0) && (cmd->resp_type & MMC_RSP_PRESENT)) {
> +		cmd->response[0] = readl(hw_dev->map_base + SDIRSP0);
> +		cmd->response[1] = readl(hw_dev->map_base + SDIRSP1);
> +		cmd->response[2] = readl(hw_dev->map_base + SDIRSP2);
> +		cmd->response[3] = readl(hw_dev->map_base + SDIRSP3);
> +	}
> +	/* do not disable the clock! */
> +	return rc;
> +}
> +
> +/**
> + * Clear major registers prior a new transaction
> + * @param hw_dev Host interface device instance
> + * @return 0 on success
> + *
> + * FIFO clear is only necessary on 2440, but doesn't hurt on 2410
> + */
> +static int s3c_prepare_engine(struct device_d *hw_dev)
> +{
> +	int rc;
> +
> +	rc = s3c_terminate_transfer(hw_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	writel(-1, hw_dev->map_base + SDICMDSTAT);
> +	writel(-1, hw_dev->map_base + SDIDSTA);
> +	writel(-1, hw_dev->map_base + SDIFSTA);
> +
> +	return 0;
> +}
> +
> +/**
> + * Handle MCI commands without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @return 0 on success
> + *
> + * This functions handles the following MCI commands:
> + * - "broadcast command (BC)" without a response
> + * - "broadcast commands with response (BCR)"
> + * - "addressed command (AC)" with response, but without data
> + */
> +static int s3c_mci_std_cmds(struct device_d *hw_dev, struct mci_cmd *cmd)
> +{
> +	int rc;
> +
> +	rc = s3c_prepare_engine(hw_dev);
> +	if (rc != 0)
> +		return 0;
> +
> +	return s3c_send_command(hw_dev, cmd, NULL);
> +}
> +
> +/**
> + * Read one block of data from the FIFO
> + * @param hw_dev Host interface device instance
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + */
> +static int s3c_mci_read_block(struct device_d *hw_dev, struct mci_data *data)
> +{
> +	uint32_t *p;
> +	unsigned cnt, data_size;
> +
> +#define READ_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_RXCRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> +	p = (uint32_t*)data->dest;
> +	data_size = data->blocksize * data->blocks;
> +
> +	while (data_size > 0) {
> +
> +		/* serious error? */
> +		if (readl(hw_dev->map_base + SDIDSTA) & READ_REASON_TO_FAIL) {
> +			pr_err("Failed while reading data\n");
> +			return -EIO;
> +		}
> +
> +		/* now check the FIFO status */
> +		if (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_FIFOFAIL) {
> +			pr_err("Data loss due to FIFO overflow when reading\n");
> +			return -EIO;
> +		}
> +
> +		/* we only want to read full words */
> +		cnt = (readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) >> 2;
> +
> +		/* read one chunk of data from the FIFO */
> +		while (cnt--) {
> +			*p = readl(hw_dev->map_base + SDIDATA);
> +			p++;
> +			if (data_size >= 4)
> +				data_size -= 4;
> +			else {
> +				data_size = 0;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Write one block of data into the FIFO
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> + *
> + * We must ensure data in the FIFO when the command phase changes into the
> + * data phase. To ensure this, the FIFO gets filled first, then the command.
> + */
> +static int s3c_mci_write_block(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	const uint32_t *p = (const uint32_t*)data->src;
> +	unsigned cnt, data_size;
> +	uint32_t reg;
> +
> +#define WRITE_REASON_TO_FAIL (SDIDSTA_CRCFAIL | SDIDSTA_DATATIMEOUT)
> +
> +	data_size = data->blocksize * data->blocks;
> +	/*
> +	 * With high clock rates we must fill the FIFO as early as possible
> +	 * Its size is 16 words. We assume its empty, when this function is
> +	 * entered.
> +	 */
> +	cnt = 16;
> +	while (cnt--) {
> +		writel(*p, hw_dev->map_base + SDIDATA);
> +		p++;
> +		if (data_size >= 4)
> +			data_size -= 4;
> +		else {
> +			data_size = 0;
> +			break;
> +		}
> +	}
> +
> +	/* data is now in place and waits for transmitt. Start the command right now */
> +	s3c_send_command(hw_dev, cmd, data);
> +
> +	if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> +		pr_err("Command fails immediatly due to FIFO underrun when writing %08X\n", reg);
> +		return -EIO;
> +	}
> +
> +	while (data_size > 0) {
> +
> +		if (readl(hw_dev->map_base + SDIDSTA) & WRITE_REASON_TO_FAIL) {
> +			pr_err("Failed writing data\n");
> +			return -EIO;
> +		}
> +
> +		/* now check the FIFO status */
> +		if ((reg = readl(hw_dev->map_base + SDIFSTA)) & SDIFSTA_FIFOFAIL) {
> +			pr_err("Data loss due to FIFO underrun when writing %08X\n", reg);
> +			return -EIO;
> +		}
> +
> +		/* we only want to write full words */
> +		cnt = 16 - (((readl(hw_dev->map_base + SDIFSTA) & SDIFSTA_COUNTMASK) + 3) >> 2);
> +
> +		/* fill the FIFO if it has free entries */
> +		while (cnt--) {
> +			writel(*p, hw_dev->map_base + SDIDATA);
> +			p++;
> +			if (data_size >= 4)
> +				data_size -= 4;
> +			else {
> +				data_size = 0;
> +				break;
> +			}
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * Handle MCI commands with or without data
> + * @param hw_dev Host interface device instance
> + * @param cmd The command to handle
> + * @param data The data information (buffer, direction aso.)
> + * @return 0 on success
> +*/
> +static int s3c_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	int rc;
> +
> +	rc = s3c_prepare_engine(hw_dev);
> +	if (rc != 0)
> +		return rc;
> +
> +	rc = s3c_prepare_data_transfer(hw_dev, data);
> +	if (rc != 0)
> +		return rc;
> +
> +	if (data->flags & MMC_DATA_READ) {
> +		s3c_send_command(hw_dev, cmd, data);
> +		rc = s3c_mci_read_block(hw_dev, data);
> +		if (rc == 0) {
> +			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> +				;
> +		} else
> +			s3c_terminate_transfer(hw_dev);
> +	}
> +
> +	if (data->flags & MMC_DATA_WRITE) {
> +		rc = s3c_mci_write_block(hw_dev, cmd, data);
> +		if (rc == 0) {
> +			while (!(readl(hw_dev->map_base + SDIDSTA) & SDIDSTA_XFERFINISH))
> +				;
> +		} else
> +			s3c_terminate_transfer(hw_dev);
> +	}
> +	writel(0, hw_dev->map_base + SDIDCON);
> +
> +	return rc;
> +}
> +
> +/* ------------------------- MCI API -------------------------------------- */
> +
> +/**
> + * Keep the attached MMC/SD unit in a well know state
> + * @param hw_dev Host interface instance
> + * @param mci_dev MCI device instance
> + * @return 0 on success, negative value else
> + */
> +static int mci_reset(struct device_d *hw_dev, struct device_d *mci_dev)
> +{
> +	return s3c_mci_initialize(hw_dev, mci_dev);
> +}
> +
> +/**
> + * Process one command to the MCI card
> + * @param hw_dev Host interface instance
> + * @param cmd The command to process
> + * @param data The data to handle in the command (can be NULL)
> + * @return 0 on success, negative value else
> + */
> +static int mci_request(struct device_d *hw_dev, struct mci_cmd *cmd, struct mci_data *data)
> +{
> +	int rc;
> +
> +	/* enable clock */
> +	writel(readl(hw_dev->map_base + SDICON) | SDICON_CLKEN, hw_dev->map_base + SDICON);
> +
> +	if ((cmd->resp_type == 0) || (data == NULL))
> +		rc = s3c_mci_std_cmds(hw_dev, cmd);
> +	else
> +		rc = s3c_mci_adtc(hw_dev, cmd, data);	/* with response and data */
> +
> +	s3c_finish_request(hw_dev);
> +
> +	/* disable clock */
> +	writel(readl(hw_dev->map_base + SDICON) & ~SDICON_CLKEN, hw_dev->map_base + SDICON);
> +	return rc;
> +}
> +
> +/**
> + * Setup the bus width and IO speed
> + * @param hw_dev Host interface device instance
> + * @param mci_dev MCI device instance
> + * @param bus_width New bus width value (1, 4 or 8)
> + * @param clock New clock in Hz (can be '0' to disable the clock)
> + */
> +static void mci_set_ios(struct device_d *hw_dev, struct device_d *mci_dev, unsigned bus_width, unsigned clock)
> +{
> +	struct s3c_mci_host *host_data = (struct s3c_mci_host*)GET_HOST_DATA(hw_dev);
> +	struct mci_platformdata *mci_pdata = GET_MCI_PDATA(mci_dev);
> +	uint32_t reg;
> +
> +	switch (bus_width) {
> +	case 8:		/* no 8 bit support, fall back to 4 bit */
> +	case 4:
> +		host_data->bus_width = 1;
> +		mci_pdata->bus_width = 4;	/* 4 bit is possible */
> +		break;
> +	default:
> +		host_data->bus_width = 0;
> +		mci_pdata->bus_width = 1;	/* 1 bit is possible */
> +		break;
> +	}
> +
> +	reg = readl(hw_dev->map_base + SDICON);
> +	if (clock) {
> +		/* setup the IO clock frequency and enable it */
> +		mci_pdata->clock = host_data->clock = s3c_setup_clock_speed(hw_dev, clock);
> +		reg |= SDICON_CLKEN;	/* enable the clock */
> +	} else {
> +		reg &= ~SDICON_CLKEN;	/* disable the clock */
> +		mci_pdata->clock = host_data->clock = 0;
> +	}
> +	writel(reg, hw_dev->map_base + SDICON);
> +
> +	pr_debug("IO settings: bus width=%d, frequency=%u Hz\n", mci_pdata->bus_width, mci_pdata->clock);
> +}
> +
> +/* ----------------------------------------------------------------------- */
> +
> +#ifdef CONFIG_MCI_INFO
> +static void s3c_info(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_host *host = (struct s3c_mci_host*)hw_dev->priv;
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> +	printf("  Bus data width: %d bit\n", host->bus_width == 1 ? 4 : 1);
> +	printf("  Bus frequency: %u Hz\n", host->clock);
> +	printf("   Frequency limits: ");
> +	if (pd->f_min == 0)
> +		printf("no lower limit ");
> +	else
> +		printf("%u Hz lower limit ", pd->f_min);
> +	if (pd->f_max == 0)
> +		printf("- no upper limit");
> +	else
> +		printf("- %u Hz upper limit", pd->f_max);
> +	printf("\n  Card detection support: %s\n", pd->gpio_detect != 0 ? "yes" : "no");
> +}
> +#endif
> +
> +/*
> + * There is only one host MCI hardware instance available.
> + * It makes no sense to dynamically allocate this data
> + */
> +static struct mci_platformdata mci_pdata = {
> +	.send_cmd = mci_request,
> +	.set_ios = mci_set_ios,
> +	.init = mci_reset,
> +};
> +
> +static int s3c_mci_probe(struct device_d *hw_dev)
> +{
> +	struct s3c_mci_platform_data *pd = (struct s3c_mci_platform_data*)hw_dev->platform_data;
> +
> +	/* TODO replace by the global func: enable the SDI unit clock */
> +	writel(readl(S3C24X0_CLOCK_POWER_BASE + 0x0c) | 0x200,S3C24X0_CLOCK_POWER_BASE + 0x0c);
> +
> +	if (pd == NULL) {
> +		pr_err("Missing platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	hw_dev->priv = &host_data;
> +	mci_pdata.hw_dev = hw_dev;
> +
> +	/* feed forward the platform specific values */
> +	mci_pdata.voltages = pd->voltages;
> +	mci_pdata.host_caps = pd->caps;
> +	mci_pdata.f_min = pd->f_min == 0 ? CLOCKRATE_MIN : pd->f_min;
> +	mci_pdata.f_max = pd->f_max == 0 ? CLOCKRATE_MAX : pd->f_max;
> +
> +	/*
> +	 * Start the clock to let the engine and the card finishes its startup
> +	 */
> +	host_data.clock = s3c_setup_clock_speed(hw_dev, mci_pdata.f_min);
> +	writel(SDICON_FIFORESET | SDICON_MMCCLOCK, hw_dev->map_base + SDICON);
> +
> +	return mci_register(&mci_pdata);
> +}
> +
> +static struct driver_d s3c_mci_driver = {
> +        .name  = "s3c_mci",
> +        .probe = s3c_mci_probe,
> +#ifdef CONFIG_MCI_INFO
> +	.info = s3c_info,
> +#endif
> +};
> +
> +static int s3c_mci_init_driver(void)
> +{
> +        register_driver(&s3c_mci_driver);
> +        return 0;
> +}
> +
> +device_initcall(s3c_mci_init_driver);
> -- 
> 1.7.2.3
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply

* Re: [RFC PATCH] staging: iio: adc: ad7476 new SPI ADC driver
From: Jonathan Cameron @ 2010-10-07 17:17 UTC (permalink / raw)
  To: michael.hennerich; +Cc: linux-iio, drivers
In-Reply-To: <1286462190-2002-1-git-send-email-michael.hennerich@analog.com>

On 10/07/10 15:36, michael.hennerich@analog.com wrote:
> From: Michael Hennerich <michael.hennerich@analog.com>
> 
Hi Michael,

Just a quick look tonight, I'll take a closer one tomorrow.

> New driver handling:
> 	AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495
> SPI micropower and high speed 12-/10-/8-Bit ADCs
> 
> Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
> ---
>  drivers/staging/iio/adc/ad7476.h      |   66 +++++++
>  drivers/staging/iio/adc/ad7476_core.c |  324 +++++++++++++++++++++++++++++++++
>  drivers/staging/iio/adc/ad7476_ring.c |  184 +++++++++++++++++++
>  3 files changed, 574 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/staging/iio/adc/ad7476.h
>  create mode 100644 drivers/staging/iio/adc/ad7476_core.c
>  create mode 100644 drivers/staging/iio/adc/ad7476_ring.c
> 
> diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h
> new file mode 100644
> index 0000000..499a773
> --- /dev/null
> +++ b/drivers/staging/iio/adc/ad7476.h
> @@ -0,0 +1,66 @@
> +/*
> + * AD7476/5/7/8 (A) SPI ADC driver
> + *
> + * Copyright 2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +#ifndef IIO_ADC_AD7476_H_
> +#define IIO_ADC_AD7476_H_
> +
> +#define RES_MASK(bits)	((1 << (bits)) - 1)
> +
> +/*
> + * TODO: struct ad7476_platform_data needs to go into include/linux/iio
> + */
> +
> +struct ad7476_platform_data {
> +	char				name[12];
Why provide the name as platform data?  Isn't an appropriate
id table and correct board info for the spi bus a better bet?

The id stuff hasn't been available for spi devices for that long,
but it is now and makes things a lot easier. Similar to i2c
but you have to use spi_get_device_id to get it from
the spi_device struct.

> +	unsigned int			vref_mv;
> +};
> +
> +struct ad7476_chip_info {
> +	char				name[12];
Easier as a const char * and appropriate const string
asignment?
> +	u8				bits;
> +	u8				storagebits;
> +	u8				res_shift;
> +	char				sign;
> +	unsigned int			int_vref_mv;
> +	struct attribute_group		*scan_attrs;
> +};
I'll look at the rest tomorrow.


Jonathan

^ permalink raw reply

* [Bug 30188] X server crashes with a SIGBUS on Evergreen
From: bugzilla-daemon @ 2010-10-07 17:11 UTC (permalink / raw)
  To: dri-devel
In-Reply-To: <bug-30188-502@http.bugs.freedesktop.org/>

https://bugs.freedesktop.org/show_bug.cgi?id=30188

--- Comment #22 from Rafael Monica <monraaf@gmail.com> 2010-10-07 10:11:48 PDT ---
Just a me too. Latest drm-radeon-testing seems to have fixed my bus errors
also.

-- 
Configure bugmail: https://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

^ permalink raw reply

* [PATCH] davinci: Implement sched_clock()
From: Kevin Hilman @ 2010-10-07 17:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com>

Andreas.Gaer at baslerweb.com writes:

> From: Andreas Gaeer <Andreas.Gaer@baslerweb.com>
>
> Overwrite the default implementation of sched_clock that is based on
> jiffies by something more precise. This improves timestamps in ftrace.
> Implementation is copied from OMAP platform code.
>
> Signed-off-by: Andreas Gaeer <Andreas.Gaer@baslerweb.com>

Thanks, applying to davinci git.  

Will queue for 2.6.38 (it's a bit too late for 2.6.37 as Linus only
wants real regression fixes after -rc6.)

Kevin

> ---
>  arch/arm/mach-davinci/time.c |   24 +++++++++++++++++++++++-
>  1 files changed, 23 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
> index 0f21c36..5d1eea0 100644
> --- a/arch/arm/mach-davinci/time.c
> +++ b/arch/arm/mach-davinci/time.c
> @@ -272,15 +272,36 @@ static cycle_t read_cycles(struct clocksource *cs)
>  	return (cycles_t)timer32_read(t);
>  }
>  
> +/*
> + * Kernel assumes that sched_clock can be called early but may not have
> + * things ready yet.
> + */
> +static cycle_t read_dummy(struct clocksource *cs)
> +{
> +	return 0;
> +}
> +
> +
>  static struct clocksource clocksource_davinci = {
>  	.rating		= 300,
> -	.read		= read_cycles,
> +	.read		= read_dummy,
>  	.mask		= CLOCKSOURCE_MASK(32),
>  	.shift		= 24,
>  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
>  
>  /*
> + * Overwrite weak default sched_clock with something more precise
> + */
> +unsigned long long notrace sched_clock(void)
> +{
> +	const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
> +
> +	return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
> +				clocksource_davinci.shift);
> +}
> +
> +/*
>   * clockevent
>   */
>  static int davinci_set_next_event(unsigned long cycles,
> @@ -377,6 +398,7 @@ static void __init davinci_timer_init(void)
>  	davinci_clock_tick_rate = clk_get_rate(timer_clk);
>  
>  	/* setup clocksource */
> +	clocksource_davinci.read = read_cycles;
>  	clocksource_davinci.name = id_to_name[clocksource_id];
>  	clocksource_davinci.mult =
>  		clocksource_khz2mult(davinci_clock_tick_rate/1000,

^ permalink raw reply

* Re: Updating libtiff
From: Tom Rini @ 2010-10-07 17:11 UTC (permalink / raw)
  To: openembedded-devel
In-Reply-To: <AANLkTimRidGM5_Lob02ZqFtENcYi2hjigKs80=bkLjLh@mail.gmail.com>

Frans Meulenbroeks wrote:
> 2010/10/7 Holger Freyther <holger+oe@freyther.de>:
>> On 10/07/2010 09:46 PM, Tom Rini wrote:
>>
>>> I think we should go with:
>>> - Add tiff_4.0.0beta6.bb which should be compatible with beta5 and will get
>>> upgrades right.
>> but not with tiff_4.0.0.bb... then you would need to bump PE...
>>
> 
> Yeah, that's why I was told to use the 3.9.2+ construct.
> 
> Forgot if there was a reason (e.g. security vulnerability) not to keep 3.9.2

Why not just have this:
# Bump for 4.0.0 release!
PE = 1

In tiff_4.0.0beta6.bb ?

-- 
Tom Rini
Mentor Graphics Corporation



^ permalink raw reply

* [PATCH net-next] net: percpu net_device refcount
From: Eric Dumazet @ 2010-10-07 17:12 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

We tried very hard to remove all possible dev_hold()/dev_put() pairs in
network stack, using RCU conversions.

There is still an unavoidable device refcount change for every dst we
create/destroy, and this can slow down some workloads (routers or some
app servers)

We can switch to a percpu refcount implementation, now dynamic per_cpu
infrastructure is mature. On a 64 cpus machine, this consumes 256 bytes
per device.

On x86, dev_hold(dev) code :

before
	lock	incl 0x280(%ebx)
after:
	movl	0x260(%ebx),%eax
	incl	fs:(%eax)

Stress bench :

(Sending 160.000.000 UDP frames,
IP route cache disabled, dual E5540 @2.53GHz,
32bit kernel, FIB_TRIE)

Before:

real	1m1.662s
user	0m14.373s
sys	12m55.960s

After:

real	0m51.179s
user	0m15.329s
sys	10m15.942s

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/netdevice.h |    6 ++--
 net/core/dev.c            |   47 ++++++++++++++++++++++++++++++------
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6abcef6..fa1d88d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1020,7 +1020,7 @@ struct net_device {
 	struct timer_list	watchdog_timer;
 
 	/* Number of references to this device */
-	atomic_t		refcnt ____cacheline_aligned_in_smp;
+	int __percpu		*pcpu_refcnt;
 
 	/* delayed register/unregister */
 	struct list_head	todo_list;
@@ -1792,7 +1792,7 @@ extern void netdev_run_todo(void);
  */
 static inline void dev_put(struct net_device *dev)
 {
-	atomic_dec(&dev->refcnt);
+	irqsafe_cpu_dec(*dev->pcpu_refcnt);
 }
 
 /**
@@ -1803,7 +1803,7 @@ static inline void dev_put(struct net_device *dev)
  */
 static inline void dev_hold(struct net_device *dev)
 {
-	atomic_inc(&dev->refcnt);
+	irqsafe_cpu_inc(*dev->pcpu_refcnt);
 }
 
 /* Carrier loss detection, dial on demand. The functions netif_carrier_on
diff --git a/net/core/dev.c b/net/core/dev.c
index 7d14955..2186e1e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5195,9 +5195,6 @@ int init_dummy_netdev(struct net_device *dev)
 	 */
 	dev->reg_state = NETREG_DUMMY;
 
-	/* initialize the ref count */
-	atomic_set(&dev->refcnt, 1);
-
 	/* NAPI wants this */
 	INIT_LIST_HEAD(&dev->napi_list);
 
@@ -5205,6 +5202,19 @@ int init_dummy_netdev(struct net_device *dev)
 	set_bit(__LINK_STATE_PRESENT, &dev->state);
 	set_bit(__LINK_STATE_START, &dev->state);
 
+#if 0
+	/* We dont allocate pcpu_refcnt for dummy devices,
+	 * because users of this 'device' dont need to change
+	 * its refcount
+	 */
+	dev->pcpu_refcnt = alloc_percpu(int);
+	if (!dev->pcpu_refcnt)
+		return -ENOMEM;
+
+	/* initialize the ref count */
+	dev_hold(dev);
+#endif
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(init_dummy_netdev);
@@ -5246,6 +5256,15 @@ out:
 }
 EXPORT_SYMBOL(register_netdev);
 
+static int netdev_refcnt_read(const struct net_device *dev)
+{
+	int i, refcnt = 0;
+
+	for_each_possible_cpu(i)
+		refcnt += *per_cpu_ptr(dev->pcpu_refcnt, i);
+	return refcnt;
+}
+
 /*
  * netdev_wait_allrefs - wait until all references are gone.
  *
@@ -5260,11 +5279,14 @@ EXPORT_SYMBOL(register_netdev);
 static void netdev_wait_allrefs(struct net_device *dev)
 {
 	unsigned long rebroadcast_time, warning_time;
+	int refcnt;
 
 	linkwatch_forget_dev(dev);
 
 	rebroadcast_time = warning_time = jiffies;
-	while (atomic_read(&dev->refcnt) != 0) {
+	refcnt = netdev_refcnt_read(dev);
+
+	while (refcnt != 0) {
 		if (time_after(jiffies, rebroadcast_time + 1 * HZ)) {
 			rtnl_lock();
 
@@ -5291,11 +5313,13 @@ static void netdev_wait_allrefs(struct net_device *dev)
 
 		msleep(250);
 
+		refcnt = netdev_refcnt_read(dev);
+
 		if (time_after(jiffies, warning_time + 10 * HZ)) {
 			printk(KERN_EMERG "unregister_netdevice: "
 			       "waiting for %s to become free. Usage "
 			       "count = %d\n",
-			       dev->name, atomic_read(&dev->refcnt));
+			       dev->name, refcnt);
 			warning_time = jiffies;
 		}
 	}
@@ -5353,7 +5377,7 @@ void netdev_run_todo(void)
 		netdev_wait_allrefs(dev);
 
 		/* paranoia */
-		BUG_ON(atomic_read(&dev->refcnt));
+		BUG_ON(netdev_refcnt_read(dev));
 		WARN_ON(rcu_dereference_raw(dev->ip_ptr));
 		WARN_ON(dev->ip6_ptr);
 		WARN_ON(dev->dn_ptr);
@@ -5523,9 +5547,13 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 	dev = PTR_ALIGN(p, NETDEV_ALIGN);
 	dev->padded = (char *)dev - (char *)p;
 
-	if (dev_addr_init(dev))
+	dev->pcpu_refcnt = alloc_percpu(int);
+	if (!dev->pcpu_refcnt)
 		goto free_tx;
 
+	if (dev_addr_init(dev))
+		goto free_pcpu;
+
 	dev_mc_init(dev);
 	dev_uc_init(dev);
 
@@ -5556,6 +5584,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 
 free_tx:
 	kfree(tx);
+free_pcpu:
+	free_percpu(dev->pcpu_refcnt);
 free_p:
 	kfree(p);
 	return NULL;
@@ -5589,6 +5619,9 @@ void free_netdev(struct net_device *dev)
 	list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
 		netif_napi_del(p);
 
+	free_percpu(dev->pcpu_refcnt);
+	dev->pcpu_refcnt = NULL;
+
 	/*  Compatibility with error handling in drivers */
 	if (dev->reg_state == NETREG_UNINITIALIZED) {
 		kfree((char *)dev - dev->padded);



^ permalink raw reply related

* [RFC] tidspbridge: use a parameter to allocate shared memory
From: Omar Ramirez Luna @ 2010-10-07 17:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201010071601.04597.laurent.pinchart@ideasonboard.com>

On 10/7/2010 9:01 AM, Laurent Pinchart wrote:
> On Thursday 07 October 2010 10:32:42 Russell King - ARM Linux wrote:
>>
>> ARMv6 and above don't like having multiple mappings with different
>> memory type/shareability/cache attributes.  It's architecturally
>> forbidden.
>>
>> So if you want non-cacheable memory and you want to be architecturally
>> compliant, you have to exclude it from the kernel's direct-mapped
>> memory mapping.
>
> That's why Omar's patch uses 'mem=' to exclude system memory from the kernel
> mappings. That's not ideal though, as that memory will be wasted forever,
> hence my comments regarding whether a non-cacheable mapping was really
> required.

it is not ideal to waste that memory, but strictly speaking old bootmem 
does the same, as no one will be touching that memory. i.e. you compile 
bridge as a module but you never insmod it, the reserved bootmem space 
is there for bridge anyway; same for bootargs tweaking, if you need 
dspbridge and are going to use it then you set aside some memory for it.

What might be a pain for end-user, is to have drivers that need to do 
tweaking to bootargs to work; but right now that is a requirement, until 
a better solution is found/created.

Regards,

Omar

^ permalink raw reply

* [linux-lvm] Grub with UUID
From: Fabricio Archanjo @ 2010-10-07 17:12 UTC (permalink / raw)
  To: linux-lvm

Hey all,


Sorry because my stupid question, but i don't know more. I'm using
Debian with LVM and I wanted to use GRUB with UUID when i pass the
boot flags root=. When i did this, my system cannot mount the root
more. May someone know why it happend? is there a problem with GRUB
v1??


Thanks all,

^ permalink raw reply

* pnfs code suggestions
From: Fred Isaman @ 2010-10-07 17:13 UTC (permalink / raw)
  To: NFS list

We are starting to think about wave 2 of the code submission, which
will be LAYOUTRETURN and callback handling.  Current code does not
correctly wait for outstanding LAYOUTGETS on CB_RECALL.  Remembering
that this is for whole file layouts with the forgetful model, my
intent is to work on patches implementing the following.  Let me know
if anyone sees problems with this approach.

On CB_RECALL, set a "barrier" equal to one less than the seqid
embedded in the cb_recall stateid.  Then, instead of waiting on any
outstanding LAYOUTGETs whose seqid is less than the barrier, as
required by the spec, we just drop any LAYOUTGET reply that has a
seqid less than the barrier.  Because we are using the forgetful
model, this is functionally equivalent to waiting, and simpler.
We similarly increase the barrier based on replies from LAYOUTRETURNs.
The major issue I see with this approach is that we have to be very
careful on reset of the stateid to either drain or detect outstanding
LAYOUTGETS.

We will still need to wait on outstanding IO within any existing
layout.  I suggest we use Benny's rpc waitq code, shifting it up into
the submission branch.

Thanks,
Fred

^ permalink raw reply

* Re: [PATCH V2] Use firmware provided index to register a network interface
From: Kay Sievers @ 2010-10-07 17:13 UTC (permalink / raw)
  To: David Lamparter
  Cc: Matt Domsch, Greg KH, Narendra_K, netdev, linux-hotplug,
	linux-pci, Jordan_Hargrave, Vijay_Nijhawan, Charles_Rose
In-Reply-To: <20101007164906.GB122295@jupiter.n2.diac24.net>

On Thu, Oct 7, 2010 at 18:49, David Lamparter <equinox@diac24.net> wrote:
> On Thu, Oct 07, 2010 at 11:31:13AM -0500, Matt Domsch wrote:
>> At most, they'll have to deal with the same "eth0_rename"
>
> Getting that "eth0_rename" stuff is not something unchangeably imposed
> by the kernel. I think this should be considered an udev bug most of all
> things, since if the udev scripts did it right, this wouldn't happen. A
> "right" way to do this would for example be to first rename all devices
> to "tmpwhatever0", then rename them back to their proper ethX names.

Whats the difference between eth0_rename and tmpeth0? I don't see any. :)

> Now I don't know even a single bit about udev scripting, so maybe this
> isn't possible with the current udev infrastructure, but there's
> certainly no kernel part stopping a proper implementation.
>
> Btw, what happened to nameif(8)? It's totally outdated (and deprecated I
> guess?), but it got the job done...

It can't swap already taken device names on hotplug, and that job
might get complicated very easily. Also stuff needs to be renamed
before the device is announced to userspace, otherwise the interface
gets configured and can't be renamed anymore.

Kay

^ permalink raw reply

* Re: [PATCH V2] Use firmware provided index to register a network interface
From: Kay Sievers @ 2010-10-07 17:13 UTC (permalink / raw)
  To: David Lamparter
  Cc: Matt Domsch, Greg KH, Narendra_K, netdev, linux-hotplug,
	linux-pci, Jordan_Hargrave, Vijay_Nijhawan, Charles_Rose
In-Reply-To: <20101007164906.GB122295@jupiter.n2.diac24.net>

On Thu, Oct 7, 2010 at 18:49, David Lamparter <equinox@diac24.net> wrote:
> On Thu, Oct 07, 2010 at 11:31:13AM -0500, Matt Domsch wrote:
>> At most, they'll have to deal with the same "eth0_rename"
>
> Getting that "eth0_rename" stuff is not something unchangeably imposed
> by the kernel. I think this should be considered an udev bug most of all
> things, since if the udev scripts did it right, this wouldn't happen. A
> "right" way to do this would for example be to first rename all devices
> to "tmpwhatever0", then rename them back to their proper ethX names.

Whats the difference between eth0_rename and tmpeth0? I don't see any. :)

> Now I don't know even a single bit about udev scripting, so maybe this
> isn't possible with the current udev infrastructure, but there's
> certainly no kernel part stopping a proper implementation.
>
> Btw, what happened to nameif(8)? It's totally outdated (and deprecated I
> guess?), but it got the job done...

It can't swap already taken device names on hotplug, and that job
might get complicated very easily. Also stuff needs to be renamed
before the device is announced to userspace, otherwise the interface
gets configured and can't be renamed anymore.

Kay

^ permalink raw reply

* Re: [RFC] tidspbridge: use a parameter to allocate shared memory
From: Omar Ramirez Luna @ 2010-10-07 17:13 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Russell King - ARM Linux, linux-arm-kernel@lists.infradead.org,
	Tony Lindgren, Ohad Ben-Cohen, Greg Kroah-Hartman,
	Gomez Castellanos, Ivan, Felipe Contreras, Ramos Falcon, Ernesto,
	linux-omap@vger.kernel.org, Ameya Palande
In-Reply-To: <201010071601.04597.laurent.pinchart@ideasonboard.com>

On 10/7/2010 9:01 AM, Laurent Pinchart wrote:
> On Thursday 07 October 2010 10:32:42 Russell King - ARM Linux wrote:
>>
>> ARMv6 and above don't like having multiple mappings with different
>> memory type/shareability/cache attributes.  It's architecturally
>> forbidden.
>>
>> So if you want non-cacheable memory and you want to be architecturally
>> compliant, you have to exclude it from the kernel's direct-mapped
>> memory mapping.
>
> That's why Omar's patch uses 'mem=' to exclude system memory from the kernel
> mappings. That's not ideal though, as that memory will be wasted forever,
> hence my comments regarding whether a non-cacheable mapping was really
> required.

it is not ideal to waste that memory, but strictly speaking old bootmem 
does the same, as no one will be touching that memory. i.e. you compile 
bridge as a module but you never insmod it, the reserved bootmem space 
is there for bridge anyway; same for bootargs tweaking, if you need 
dspbridge and are going to use it then you set aside some memory for it.

What might be a pain for end-user, is to have drivers that need to do 
tweaking to bootargs to work; but right now that is a requirement, until 
a better solution is found/created.

Regards,

Omar


^ permalink raw reply

* Re: [PATCH v6 08/12] Handle async PF in a guest.
From: Gleb Natapov @ 2010-10-07 17:14 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm, linux-mm, linux-kernel, mingo, a.p.zijlstra, tglx, hpa, riel,
	cl, mtosatti
In-Reply-To: <4CADC6C3.3040305@redhat.com>

On Thu, Oct 07, 2010 at 03:10:27PM +0200, Avi Kivity wrote:
>  On 10/04/2010 05:56 PM, Gleb Natapov wrote:
> >When async PF capability is detected hook up special page fault handler
> >that will handle async page fault events and bypass other page faults to
> >regular page fault handler. Also add async PF handling to nested SVM
> >emulation. Async PF always generates exit to L1 where vcpu thread will
> >be scheduled out until page is available.
> >
> 
> Please separate guest and host changes.
> 
> >+void kvm_async_pf_task_wait(u32 token)
> >+{
> >+	u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
> >+	struct kvm_task_sleep_head *b =&async_pf_sleepers[key];
> >+	struct kvm_task_sleep_node n, *e;
> >+	DEFINE_WAIT(wait);
> >+
> >+	spin_lock(&b->lock);
> >+	e = _find_apf_task(b, token);
> >+	if (e) {
> >+		/* dummy entry exist ->  wake up was delivered ahead of PF */
> >+		hlist_del(&e->link);
> >+		kfree(e);
> >+		spin_unlock(&b->lock);
> >+		return;
> >+	}
> >+
> >+	n.token = token;
> >+	n.cpu = smp_processor_id();
> >+	init_waitqueue_head(&n.wq);
> >+	hlist_add_head(&n.link,&b->list);
> >+	spin_unlock(&b->lock);
> >+
> >+	for (;;) {
> >+		prepare_to_wait(&n.wq,&wait, TASK_UNINTERRUPTIBLE);
> >+		if (hlist_unhashed(&n.link))
> >+			break;
> >+		local_irq_enable();
> 
> Suppose we take another apf here.  And another, and another (for
> different pages, while executing schedule()).  What's to prevent
> kernel stack overflow?
> 
Host side keeps track of outstanding apfs and will not send apf for the
same phys address twice. It will halt vcpu instead.

> >+		schedule();
> >+		local_irq_disable();
> >+	}
> >+	finish_wait(&n.wq,&wait);
> >+
> >+	return;
> >+}
> >+EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait);
> >+
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.

--
			Gleb.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH v6 08/12] Handle async PF in a guest.
From: Gleb Natapov @ 2010-10-07 17:14 UTC (permalink / raw)
  To: Avi Kivity
  Cc: kvm, linux-mm, linux-kernel, mingo, a.p.zijlstra, tglx, hpa, riel,
	cl, mtosatti
In-Reply-To: <4CADC6C3.3040305@redhat.com>

On Thu, Oct 07, 2010 at 03:10:27PM +0200, Avi Kivity wrote:
>  On 10/04/2010 05:56 PM, Gleb Natapov wrote:
> >When async PF capability is detected hook up special page fault handler
> >that will handle async page fault events and bypass other page faults to
> >regular page fault handler. Also add async PF handling to nested SVM
> >emulation. Async PF always generates exit to L1 where vcpu thread will
> >be scheduled out until page is available.
> >
> 
> Please separate guest and host changes.
> 
> >+void kvm_async_pf_task_wait(u32 token)
> >+{
> >+	u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
> >+	struct kvm_task_sleep_head *b =&async_pf_sleepers[key];
> >+	struct kvm_task_sleep_node n, *e;
> >+	DEFINE_WAIT(wait);
> >+
> >+	spin_lock(&b->lock);
> >+	e = _find_apf_task(b, token);
> >+	if (e) {
> >+		/* dummy entry exist ->  wake up was delivered ahead of PF */
> >+		hlist_del(&e->link);
> >+		kfree(e);
> >+		spin_unlock(&b->lock);
> >+		return;
> >+	}
> >+
> >+	n.token = token;
> >+	n.cpu = smp_processor_id();
> >+	init_waitqueue_head(&n.wq);
> >+	hlist_add_head(&n.link,&b->list);
> >+	spin_unlock(&b->lock);
> >+
> >+	for (;;) {
> >+		prepare_to_wait(&n.wq,&wait, TASK_UNINTERRUPTIBLE);
> >+		if (hlist_unhashed(&n.link))
> >+			break;
> >+		local_irq_enable();
> 
> Suppose we take another apf here.  And another, and another (for
> different pages, while executing schedule()).  What's to prevent
> kernel stack overflow?
> 
Host side keeps track of outstanding apfs and will not send apf for the
same phys address twice. It will halt vcpu instead.

> >+		schedule();
> >+		local_irq_disable();
> >+	}
> >+	finish_wait(&n.wq,&wait);
> >+
> >+	return;
> >+}
> >+EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait);
> >+
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.

--
			Gleb.

^ permalink raw reply

* Re: [PATCH V2] Use firmware provided index to register a network
From: Greg KH @ 2010-10-07 17:15 UTC (permalink / raw)
  To: Kay Sievers
  Cc: Matt Domsch, Narendra_K, netdev, linux-hotplug, linux-pci,
	Jordan_Hargrave, Vijay_Nijhawan, Charles_Rose
In-Reply-To: <AANLkTinP5WPDPvk+kq8vsyP=xC9qcoe+c=1EBp0XJNPk@mail.gmail.com>

On Thu, Oct 07, 2010 at 07:05:14PM +0200, Kay Sievers wrote:
> On Thu, Oct 7, 2010 at 18:48, Greg KH <greg@kroah.com> wrote:
> > On Thu, Oct 07, 2010 at 11:31:13AM -0500, Matt Domsch wrote:
> >> 1) SMBIOS type 41 method.  Windows does not use this today, and I
> >>    can't speak to their future plans.  Narendra's kernel patch does,
> >>    as has biosdevname, the udev helper we first wrote for this
> >>    purpose, for several years.
> >
> > Then stick with that udev helper please :)
> 
> What about just exporting this information in sysfs, and not touch the naming?

I think this is now exported in userspace, right Narendra?

> Anyway, I'm pretty sure all of this naming of onboard devices should
> happen only at install time, or from a system management tool and not
> at hotplug time.
> 
> We should not get confused by the way the (very simple)
> automatic-rule-creater for persistent netdev naming in udev works.
> This is really just a tool for the common case, and works fine for the
> majority of people.
> 
> I'm not sure, if we should put all these special use cases in the
> hotplug path. I mean it's not that people add and remove 4 port
> network cards with special BIOS all the time, and expect proper naming
> on the first bootup, right? The installer, or the system management
> tool could just create/edit udev rules to provide proper device naming
> on whatever property is available at a specific hardware, be it the
> MAC address or some other persistent match?

I totally agree.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH V2] Use firmware provided index to register a network interface
From: Greg KH @ 2010-10-07 17:15 UTC (permalink / raw)
  To: Kay Sievers
  Cc: Matt Domsch, Narendra_K, netdev, linux-hotplug, linux-pci,
	Jordan_Hargrave, Vijay_Nijhawan, Charles_Rose
In-Reply-To: <AANLkTinP5WPDPvk+kq8vsyP=xC9qcoe+c=1EBp0XJNPk@mail.gmail.com>

On Thu, Oct 07, 2010 at 07:05:14PM +0200, Kay Sievers wrote:
> On Thu, Oct 7, 2010 at 18:48, Greg KH <greg@kroah.com> wrote:
> > On Thu, Oct 07, 2010 at 11:31:13AM -0500, Matt Domsch wrote:
> >> 1) SMBIOS type 41 method.  Windows does not use this today, and I
> >>    can't speak to their future plans.  Narendra's kernel patch does,
> >>    as has biosdevname, the udev helper we first wrote for this
> >>    purpose, for several years.
> >
> > Then stick with that udev helper please :)
> 
> What about just exporting this information in sysfs, and not touch the naming?

I think this is now exported in userspace, right Narendra?

> Anyway, I'm pretty sure all of this naming of onboard devices should
> happen only at install time, or from a system management tool and not
> at hotplug time.
> 
> We should not get confused by the way the (very simple)
> automatic-rule-creater for persistent netdev naming in udev works.
> This is really just a tool for the common case, and works fine for the
> majority of people.
> 
> I'm not sure, if we should put all these special use cases in the
> hotplug path. I mean it's not that people add and remove 4 port
> network cards with special BIOS all the time, and expect proper naming
> on the first bootup, right? The installer, or the system management
> tool could just create/edit udev rules to provide proper device naming
> on whatever property is available at a specific hardware, be it the
> MAC address or some other persistent match?

I totally agree.

thanks,

greg k-h

^ permalink raw reply

* Re: Updating libtiff
From: Tom Rini @ 2010-10-07 17:14 UTC (permalink / raw)
  To: openembedded-devel
In-Reply-To: <20101007140016.GC3163@jama>

Martin Jansa wrote:
> On Thu, Oct 07, 2010 at 06:46:06AM -0700, Tom Rini wrote:
>> Hey all,
>>
>> I'm looking to update libtiff to cover some security issues in the 
>> version we ship, and I noticed something funny about how we do it today. 
>>   Currently tiff_3.9.2.bb sets PV to 3.9.2+4.0.0beta5 and grabs and 
>> builds 4.0.0beta5.  While it's possible that in the past 3.9.2 was 
>> intended to be the last 3.9.x, it wasn't.
>>
>> I think we should go with:
>> - Add tiff_4.0.0beta6.bb which should be compatible with beta5 and will 
>> get upgrades right.
>> - Add tiff_3.9.4.bb as well, in case someone wants to stay on the 
>> released line.
>>
>> Anyone see a problem with that?
> 
> Isn't PV="4.0.0" < PV="4.0.0beta5"?
> 
> Then it would be better to stay with 3.9.2+4.0.0beta* sheme for easy
> upgrade path to 4.0.0 release.
> 
> at least that's the reason why I have ie:
> KERNEL_RELEASE = "2.6.36-rc7"
> OLD_KERNEL_RELEASE = "2.6.35"
> PV = "${OLD_KERNEL_RELEASE}+${KERNEL_RELEASE}+gitr${SRCPV}"

Ah right.  But the problem is that we're more like back in the "not 
quite 2.6.0" days of the kernel.  Unless we just skip out on doing 3.9.4 
itself, which I guess is possible.

-- 
Tom Rini
Mentor Graphics Corporation



^ permalink raw reply

* Re: Linux 2.6.36-rc7
From: Tvrtko Ursulin @ 2010-10-07 17:15 UTC (permalink / raw)
  To: Linus Torvalds, Eric Paris; +Cc: Linux Kernel Mailing List
In-Reply-To: <201010071710.46938.tvrtko.ursulin@sophos.com>

On Thursday 07 Oct 2010 17:10:46 Tvrtko Ursulin wrote:
> On Wednesday 06 Oct 2010 22:45:13 Linus Torvalds wrote:
> [snip]
>
> > And yes, that's probably as exciting as it gets, which is just fine by
> > me. This should be the last -rc, I'm not seeing any reason to keep
> > delaying a real release. There was still more changes to
> > drivers/gpu/drm than I really would have hoped for, but they all look
> > harmless and good. Famous last words.
>
> Hi Linus,
>
> Please see http://marc.info/?l=linux-kernel&m=128618485204253&w=2
>
> I have sent this proposed bugfix several times now but no one is picking it
> up and Eric seems to have disappeared. It would be suboptimal to release
> 2.6.36 with a core fanotify feature non-functional.

Unfortunately I have another showstopper. Sadly I missed it until now because
internally we were more worried of issues which were kind of direct problems
for us and I went to deep instead of spending more time reviewing it breath
first.

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=08ae89380a8210a9965d04083e1de78cb8bca4b1

Priority argument was dropped from the fanotify_init syscall, and since it is
a syscall once released it is set in stone. Without the priority argument, how
are multiple clients supposed to be ordered?

Co-existence between multiple clients was something which was supposed to be
designed in from the start. Use cases like hierarchical storage management,
anti-malware and content indexing should all be able to co-exist. Without a
priority argument I do not see how it can be assured HSM sees the perm event
before anti-malware, and content indexing after both of them? If there was any
discussion about dropping priority I missed it. :(

Tvrtko

Sophos Plc, The Pentagon, Abingdon Science Park, Abingdon, OX14 3YP, United Kingdom.
Company Reg No 2096520. VAT Reg No GB 348 3873 20.

^ permalink raw reply

* x86_64 2.6.35.* kernels and Intel Xeon X5550
From: Marc Aurele La France @ 2010-10-07 17:17 UTC (permalink / raw)
  To: linux-kernel

Greetings.

I administer a cluster composed of a mixture of various Opteron models and 
Intel Xeon X5550's.  The 2.6.34.*, and prior, kernels run fine on all of 
them.  The 2.6.35 series also runs fine on the Opterons, but not on the 
Xeon's.  All of these are CONFIG_GENERIC_CPU kernels.

On the Xeon's, 2.6.35 hangs early on, upon the first test of trace events 
(in kernel/trace/trace_events.c:event_trace_self_tests()).  When disabling 
all tracing, debugging, etc., it still hangs but slightly later.  The 
megaraid_sas module is loaded, detects the adapter, but never gets around 
to registering it with the SCSI layer.

Core2-specific kernels also hang the same way, as do UP kernels.  I've 
tried backing out certain commits that seemed likely candidates, but have 
yet to stumble upon the one (or more) that is causing this.

Does anyone have any ideas?

Thanks.

Marc.

+----------------------------------+----------------------------------+
|  Marc Aurele La France           |  work:   1-780-492-9310          |
|  Academic Information and        |  fax:    1-780-492-1729          |
|    Communications Technologies   |  email:  tsi@ualberta.ca         |
|  352 General Services Building   +----------------------------------+
|  University of Alberta           |                                  |
|  Edmonton, Alberta               |    Standard disclaimers apply    |
|  T6G 2H1                         |                                  |
|  CANADA                          |                                  |
+----------------------------------+----------------------------------+

^ permalink raw reply

* Re: SRP submaintainership
From: Bart Van Assche @ 2010-10-07 17:17 UTC (permalink / raw)
  To: Roland Dreier, David Dillow; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <adatyky3pvj.fsf-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org>

On Thu, Oct 7, 2010 at 6:54 PM, Roland Dreier <rdreier-FYB4Gu1CFyUAvxtiuMwx3w@public.gmane.org> wrote:
> Dave Dillow has been involved with both kernel development and SRP for
> a long time, and I trust Dave's technical judgement and good taste
> about the SRP code.  Dave has graciously agreed to serve as a
> submaintainer for the SRP initiator, which should mean that SRP
> patches will get more focus and also free me to spend more time on
> other maintenance/patch review.

I'd like to congratulate Dave with this new responsibility. It's good
to see the number of linux-RDMA maintainers growing.

Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.