From ee04448d8871e71f55520d62cf6adbf5dd403c99 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 1 Nov 2008 06:32:20 +0100 Subject: [PATCH] mv643xx_eth: fix SMI bus access timeouts The mv643xx_eth mii bus implementation uses wait_event_timeout() to wait for SMI completion interrupts. If wait_event_timeout() would return zero, mv643xx_eth would conclude that the SMI access timed out, but this is not necessarily true -- wait_event_timeout() can also return zero in the case where the SMI completion interrupt did happen in time but where it took longer than the requested timeout for the process performing the SMI access to be scheduled again. This would lead to occasional SMI access timeouts when the system would be under heavy load. The fix is to ignore the return value of wait_event_timeout(), and to re-check the SMI done bit after wait_event_timeout() returns to determine whether or not the SMI access timed out. Signed-off-by: Lennert Buytenhek Signed-off-by: Jeff Garzik --- drivers/net/mv643xx_eth.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index a9c8c08044b1..b9dcdbd369f8 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1066,9 +1066,12 @@ static int smi_wait_ready(struct mv643xx_eth_shared_private *msp) return 0; } - if (!wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), - msecs_to_jiffies(100))) - return -ETIMEDOUT; + if (!smi_is_done(msp)) { + wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), + msecs_to_jiffies(100)); + if (!smi_is_done(msp)) + return -ETIMEDOUT; + } return 0; }