aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2008-12-18 08:23:22 +0000
committerDavid S. Miller <davem@davemloft.net>2008-12-18 22:48:53 -0800
commitb3431c647662a3647f3500a12ec85d65e3622759 (patch)
treedada029b120f9299bef0e93e2c9434c85da4c965
parent6086ebca13ddc9cfaaa25248ba8ebef35103fb74 (diff)
downloadkernel_samsung_espresso10-b3431c647662a3647f3500a12ec85d65e3622759.zip
kernel_samsung_espresso10-b3431c647662a3647f3500a12ec85d65e3622759.tar.gz
kernel_samsung_espresso10-b3431c647662a3647f3500a12ec85d65e3622759.tar.bz2
ucc_geth: Fix endless loop in stop_{tx,rx} routines
Currently the routines wait for the various bits w/o an assumption that bits may never get set. When timeouts happen I see that these bits never get set and so the routines hang the kernel. With this patch we'll wait the graceful stop for 100 ms, and then will simply exit. There is nothing* we can do about that, but it's OK since we'll do full reset later. * Well, actually, there is also not-graceful variant for the TX stop, but specs says that we never should use it. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ucc_geth.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 0a5b817..fa25dc1 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1647,6 +1647,7 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
struct ucc_fast_private *uccf;
u32 cecr_subblock;
u32 temp;
+ int i = 10;
uccf = ugeth->uccf;
@@ -1664,8 +1665,9 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
/* Wait for command to complete */
do {
+ msleep(10);
temp = in_be32(uccf->p_ucce);
- } while (!(temp & UCCE_GRA));
+ } while (!(temp & UCCE_GRA) && --i);
uccf->stopped_tx = 1;
@@ -1677,6 +1679,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
struct ucc_fast_private *uccf;
u32 cecr_subblock;
u8 temp;
+ int i = 10;
uccf = ugeth->uccf;
@@ -1694,9 +1697,9 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
ucc_num);
qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
QE_CR_PROTOCOL_ETHERNET, 0);
-
+ msleep(10);
temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
- } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
+ } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i);
uccf->stopped_rx = 1;