[U-Boot] [PATCH 1/3] net/eth: set status to active before calling init
Sebastian Andrzej Siewior
bigeasy at linutronix.de
Fri Mar 23 21:11:17 CET 2012
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 at 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
More information about the U-Boot
mailing list