diff options
author | Ishizaki Kou <kou.ishizaki@toshiba.co.jp> | 2008-04-10 23:32:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-04-16 20:06:50 -0400 |
commit | 9a11fcb5215d6ecade9aca1f1fba272746a3882d (patch) | |
tree | adf3d70d05fefb026557417b673a7fb0aac5b2a5 /drivers/net/spider_net.c | |
parent | fcfcfa205ef59f10d80e67a1762ad27e765d4868 (diff) |
spidernet: fix error interrupt handling
In addition to the value of GHIINT0STS, spidernet interrupt handler
should check the values of GHIINT1STS/GHIINT2STS registers at the
beginning of spider_net_interrupt() so as not to drop error
interrupts.
GHIINT1STS/GHIINT2STS registers indicates some of erroneous conditions
in spidernet, and a few bits of GHIINT0STS register reflects these
conditions. But GHIINT0MSK masks these bits, so you should check these
conditions by reading GHIINT1STS/GHIINT2STS registers directly.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Jens Osterkamp <jens@de.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r-- | drivers/net/spider_net.c | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index f7781ec181f3..e8b3b0802e73 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -1415,18 +1415,12 @@ spider_net_link_reset(struct net_device *netdev) | |||
1415 | * found when an interrupt is presented | 1415 | * found when an interrupt is presented |
1416 | */ | 1416 | */ |
1417 | static void | 1417 | static void |
1418 | spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | 1418 | spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg, |
1419 | u32 error_reg1, u32 error_reg2) | ||
1419 | { | 1420 | { |
1420 | u32 error_reg1, error_reg2; | ||
1421 | u32 i; | 1421 | u32 i; |
1422 | int show_error = 1; | 1422 | int show_error = 1; |
1423 | 1423 | ||
1424 | error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); | ||
1425 | error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); | ||
1426 | |||
1427 | error_reg1 &= SPIDER_NET_INT1_MASK_VALUE; | ||
1428 | error_reg2 &= SPIDER_NET_INT2_MASK_VALUE; | ||
1429 | |||
1430 | /* check GHIINT0STS ************************************/ | 1424 | /* check GHIINT0STS ************************************/ |
1431 | if (status_reg) | 1425 | if (status_reg) |
1432 | for (i = 0; i < 32; i++) | 1426 | for (i = 0; i < 32; i++) |
@@ -1656,12 +1650,15 @@ spider_net_interrupt(int irq, void *ptr) | |||
1656 | { | 1650 | { |
1657 | struct net_device *netdev = ptr; | 1651 | struct net_device *netdev = ptr; |
1658 | struct spider_net_card *card = netdev_priv(netdev); | 1652 | struct spider_net_card *card = netdev_priv(netdev); |
1659 | u32 status_reg; | 1653 | u32 status_reg, error_reg1, error_reg2; |
1660 | 1654 | ||
1661 | status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); | 1655 | status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS); |
1662 | status_reg &= SPIDER_NET_INT0_MASK_VALUE; | 1656 | error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS); |
1657 | error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS); | ||
1663 | 1658 | ||
1664 | if (!status_reg) | 1659 | if (!(status_reg & SPIDER_NET_INT0_MASK_VALUE) && |
1660 | !(error_reg1 & SPIDER_NET_INT1_MASK_VALUE) && | ||
1661 | !(error_reg2 & SPIDER_NET_INT2_MASK_VALUE)) | ||
1665 | return IRQ_NONE; | 1662 | return IRQ_NONE; |
1666 | 1663 | ||
1667 | if (status_reg & SPIDER_NET_RXINT ) { | 1664 | if (status_reg & SPIDER_NET_RXINT ) { |
@@ -1676,7 +1673,8 @@ spider_net_interrupt(int irq, void *ptr) | |||
1676 | spider_net_link_reset(netdev); | 1673 | spider_net_link_reset(netdev); |
1677 | 1674 | ||
1678 | if (status_reg & SPIDER_NET_ERRINT ) | 1675 | if (status_reg & SPIDER_NET_ERRINT ) |
1679 | spider_net_handle_error_irq(card, status_reg); | 1676 | spider_net_handle_error_irq(card, status_reg, |
1677 | error_reg1, error_reg2); | ||
1680 | 1678 | ||
1681 | /* clear interrupt sources */ | 1679 | /* clear interrupt sources */ |
1682 | spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); | 1680 | spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); |