| From stable-bounces@linux.kernel.org Thu Oct 12 15:38:57 2006 |
| Date: Thu, 12 Oct 2006 15:32:42 -0700 |
| From: Stephen Hemminger <shemminger@osdl.org> |
| To: stable@kernel.org |
| Message-ID: <20061012153242.43fb9c38@freekitty> |
| Mime-Version: 1.0 |
| Subject: sky2: turn off PHY IRQ on shutdown |
| Content-Type: text/plain; charset="us-ascii" |
| |
| From: Stephen Hemminger <shemminger@osdl.org> |
| |
| When PHY is turned off on shutdown, it can causes the IRQ to get stuck on. |
| Make sure and disable the IRQ first, and if IRQ occurs when device |
| is not running, don't access PHY because that can hang. |
| |
| Signed-off-by: Stephen Hemminger <shemminger@osdl.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| Signed-off-by: Chris Wright <chrisw@sous-sol.org> |
| |
| --- |
| drivers/net/sky2.c | 16 ++++++++-------- |
| 1 file changed, 8 insertions(+), 8 deletions(-) |
| |
| --- linux-2.6.18.1.orig/drivers/net/sky2.c |
| +++ linux-2.6.18.1/drivers/net/sky2.c |
| @@ -1429,6 +1429,11 @@ static int sky2_down(struct net_device * |
| /* Stop more packets from being queued */ |
| netif_stop_queue(dev); |
| |
| + /* Disable port IRQ */ |
| + imask = sky2_read32(hw, B0_IMSK); |
| + imask &= ~portirq_msk[port]; |
| + sky2_write32(hw, B0_IMSK, imask); |
| + |
| sky2_phy_reset(hw, port); |
| |
| /* Stop transmitter */ |
| @@ -1472,11 +1477,6 @@ static int sky2_down(struct net_device * |
| sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
| sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
| |
| - /* Disable port IRQ */ |
| - imask = sky2_read32(hw, B0_IMSK); |
| - imask &= ~portirq_msk[port]; |
| - sky2_write32(hw, B0_IMSK, imask); |
| - |
| /* turn off LED's */ |
| sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
| |
| @@ -1687,13 +1687,13 @@ static void sky2_phy_intr(struct sky2_hw |
| struct sky2_port *sky2 = netdev_priv(dev); |
| u16 istatus, phystat; |
| |
| + if (!netif_running(dev)) |
| + return; |
| + |
| spin_lock(&sky2->phy_lock); |
| istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); |
| phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); |
| |
| - if (!netif_running(dev)) |
| - goto out; |
| - |
| if (netif_msg_intr(sky2)) |
| printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
| sky2->netdev->name, istatus, phystat); |