public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/3] net/eth: set status to active before calling init
@ 2012-03-23 20:11 Sebastian Andrzej Siewior
  2012-03-23 20:11 ` [U-Boot] [PATCH 2/3] net/tsec: convert the printf() to serial_printf() Sebastian Andrzej Siewior
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Sebastian Andrzej Siewior @ 2012-03-23 20:11 UTC (permalink / raw)
  To: u-boot

If we set the status after successful init call then we get in trouble
if stdout (or setderr) is set to netconsole. If we are going to use one
of those (lets say printf) during ->init() the following happens:
- network is of (state passive)
- we switch on netconsole
- nc_getc() gets called
- in NetLoop() we switch on ethernet via eth_init()
- we end up in tsec_init() (inc case we use the tsec driver). Here we
  call a printf()
- That printf() ends up in nc_puts() because netconsole is our default
  output.
- The state is not active yet, so we call eth_init() once again.
- and we are again in tsec_init(). Another printf() is waiting. However,
  due to the recursion check nc_puts() returns early before doing
  anything.
- we return from each function. Sine nc_puts() thinks that it was in
  charge of enabling the ethernet, it disables it before leaving.
- We return now to the top-most eth_init() function. Since everything
  went fine, it sets the status to active. In reality the network is
  switched off.
- nc_getc() gets called over and over to receive new packets. Sadly the
  nic is disabled and new network packets won't be noticed.

This patch sets the network status early so nc_puts() does not get
confused and disables the network interface in case of a printf() on its
way.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 net/eth.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/net/eth.c b/net/eth.c
index 4280d6d..bca405a 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -380,14 +380,17 @@ int eth_init(bd_t *bis)
 
 	old_current = eth_current;
 	do {
+		int old_state;
+
 		debug("Trying %s\n", eth_current->name);
 
-		if (eth_current->init(eth_current,bis) >= 0) {
-			eth_current->state = ETH_STATE_ACTIVE;
-
+		old_state = eth_current->state;
+		eth_current->state = ETH_STATE_ACTIVE;
+		if (eth_current->init(eth_current,bis) >= 0)
 			return 0;
-		}
+
 		debug("FAIL\n");
+		eth_current->state = old_state;
 
 		eth_try_another(0);
 	} while (old_current != eth_current);
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-04-09 21:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-23 20:11 [U-Boot] [PATCH 1/3] net/eth: set status to active before calling init Sebastian Andrzej Siewior
2012-03-23 20:11 ` [U-Boot] [PATCH 2/3] net/tsec: convert the printf() to serial_printf() Sebastian Andrzej Siewior
2012-03-23 20:11 ` [U-Boot] [PATCH 3/3] net/tsec: Don't tell the link status if used with netconsole Sebastian Andrzej Siewior
2012-04-03 20:42   ` Mike Frysinger
2012-04-03 20:54     ` Sebastian Andrzej Siewior
2012-04-04 15:27       ` Joe Hershberger
2012-04-08  8:26         ` Mike Frysinger
2012-04-09 21:43           ` Joe Hershberger
2012-04-03 20:41 ` [U-Boot] [PATCH 1/3] net/eth: set status to active before calling init Mike Frysinger
2012-04-03 20:51   ` Sebastian Andrzej Siewior

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