aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAnton Vorontsov <avorontsov@ru.mvista.com>2008-12-18 03:23:22 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-19 01:48:53 -0500
commitb3431c647662a3647f3500a12ec85d65e3622759 (patch)
treedada029b120f9299bef0e93e2c9434c85da4c965 /drivers
parent6086ebca13ddc9cfaaa25248ba8ebef35103fb74 (diff)
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>
Diffstat (limited to 'drivers')
-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 0a5b817fd7ac..fa25dc1fcdf1 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)
1647 struct ucc_fast_private *uccf; 1647 struct ucc_fast_private *uccf;
1648 u32 cecr_subblock; 1648 u32 cecr_subblock;
1649 u32 temp; 1649 u32 temp;
1650 int i = 10;
1650 1651
1651 uccf = ugeth->uccf; 1652 uccf = ugeth->uccf;
1652 1653
@@ -1664,8 +1665,9 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
1664 1665
1665 /* Wait for command to complete */ 1666 /* Wait for command to complete */
1666 do { 1667 do {
1668 msleep(10);
1667 temp = in_be32(uccf->p_ucce); 1669 temp = in_be32(uccf->p_ucce);
1668 } while (!(temp & UCCE_GRA)); 1670 } while (!(temp & UCCE_GRA) && --i);
1669 1671
1670 uccf->stopped_tx = 1; 1672 uccf->stopped_tx = 1;
1671 1673
@@ -1677,6 +1679,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
1677 struct ucc_fast_private *uccf; 1679 struct ucc_fast_private *uccf;
1678 u32 cecr_subblock; 1680 u32 cecr_subblock;
1679 u8 temp; 1681 u8 temp;
1682 int i = 10;
1680 1683
1681 uccf = ugeth->uccf; 1684 uccf = ugeth->uccf;
1682 1685
@@ -1694,9 +1697,9 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
1694 ucc_num); 1697 ucc_num);
1695 qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, 1698 qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
1696 QE_CR_PROTOCOL_ETHERNET, 0); 1699 QE_CR_PROTOCOL_ETHERNET, 0);
1697 1700 msleep(10);
1698 temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); 1701 temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
1699 } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX)); 1702 } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i);
1700 1703
1701 uccf->stopped_rx = 1; 1704 uccf->stopped_rx = 1;
1702 1705