Free the pending TX skb inside smc_reset() rather than doing it where smc_reset() is called. Worse, some places just didn't care. Also do it when closing the driver. Signed-off-by: Nicolas Pitre Signed-off-by: Andrew Morton --- 25-akpm/drivers/net/smc91x.c | 24 ++++++++++++++---------- 1 files changed, 14 insertions(+), 10 deletions(-) diff -puN drivers/net/smc91x.c~smc91x-fix-possible-leak-of-the-skb-waiting-for-mem drivers/net/smc91x.c --- 25/drivers/net/smc91x.c~smc91x-fix-possible-leak-of-the-skb-waiting-for-mem Thu Sep 23 15:00:14 2004 +++ 25-akpm/drivers/net/smc91x.c Thu Sep 23 15:00:14 2004 @@ -306,6 +306,7 @@ static void PRINT_PKT(u_char *buf, int l static void smc_reset(struct net_device *dev) { unsigned long ioaddr = dev->base_addr; + struct smc_local *lp = netdev_priv(dev); unsigned int ctl, cfg; DBG(2, "%s: %s\n", dev->name, __FUNCTION__); @@ -379,6 +380,14 @@ static void smc_reset(struct net_device SMC_SELECT_BANK(2); SMC_SET_MMU_CMD(MC_RESET); SMC_WAIT_MMU_BUSY(); + + /* clear anything saved */ + if (lp->saved_skb != NULL) { + dev_kfree_skb (lp->saved_skb); + lp->saved_skb = NULL; + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + } } /* @@ -1270,13 +1279,6 @@ static void smc_timeout(struct net_devic if (lp->phy_type != 0) schedule_work(&lp->phy_configure); - /* clear anything saved */ - if (lp->saved_skb != NULL) { - dev_kfree_skb (lp->saved_skb); - lp->saved_skb = NULL; - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - } /* We can accept TX packets again */ dev->trans_start = jiffies; netif_wake_queue(dev); @@ -1410,9 +1412,6 @@ smc_open(struct net_device *dev) return -EINVAL; } - /* clear out all the junk that was put here before... */ - lp->saved_skb = NULL; - /* Setup the default Register Modes */ lp->tcr_cur_mode = TCR_DEFAULT; lp->rcr_cur_mode = RCR_DEFAULT; @@ -1466,6 +1465,11 @@ static int smc_close(struct net_device * smc_phy_powerdown(dev, lp->mii.phy_id); } + if (lp->saved_skb) { + dev_kfree_skb(lp->saved_skb); + lp->saved_skb = NULL; + } + return 0; } _