aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/smc91c92_cs.c
diff options
context:
space:
mode:
authorKomuro <komurojun@nifty.com>2007-07-23 08:36:06 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-30 15:58:13 -0400
commit85e27831941e0d907be8e244202a293d74730e12 (patch)
tree906ebc4b9141582a422cb4aa94e50d2709adba8c /drivers/net/pcmcia/smc91c92_cs.c
parent573608e4cde2aa3b76120685fba945d889b2ba57 (diff)
PATCH kernel 2.6.22] PCMCIA-NETDEV : modify smc91c92_cs.c to become SMP safe
protect smc_start_xmit, smc_interrupt and media_check by spin_lock. Signed-off-by: Komuro <komurojun-mbn@nifty.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/pcmcia/smc91c92_cs.c')
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7912dbd14251..af6728cb49c3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1368,6 +1368,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
1368 kio_addr_t ioaddr = dev->base_addr; 1368 kio_addr_t ioaddr = dev->base_addr;
1369 u_short num_pages; 1369 u_short num_pages;
1370 short time_out, ir; 1370 short time_out, ir;
1371 unsigned long flags;
1371 1372
1372 netif_stop_queue(dev); 1373 netif_stop_queue(dev);
1373 1374
@@ -1395,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
1395 /* A packet is now waiting. */ 1396 /* A packet is now waiting. */
1396 smc->packets_waiting++; 1397 smc->packets_waiting++;
1397 1398
1399 spin_lock_irqsave(&smc->lock, flags);
1398 SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */ 1400 SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */
1399 1401
1400 /* need MC_RESET to keep the memory consistent. errata? */ 1402 /* need MC_RESET to keep the memory consistent. errata? */
@@ -1411,6 +1413,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
1411 /* Acknowledge the interrupt, send the packet. */ 1413 /* Acknowledge the interrupt, send the packet. */
1412 outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT); 1414 outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
1413 smc_hardware_send_packet(dev); /* Send the packet now.. */ 1415 smc_hardware_send_packet(dev); /* Send the packet now.. */
1416 spin_unlock_irqrestore(&smc->lock, flags);
1414 return 0; 1417 return 0;
1415 } 1418 }
1416 } 1419 }
@@ -1418,6 +1421,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
1418 /* Otherwise defer until the Tx-space-allocated interrupt. */ 1421 /* Otherwise defer until the Tx-space-allocated interrupt. */
1419 DEBUG(2, "%s: memory allocation deferred.\n", dev->name); 1422 DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
1420 outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT); 1423 outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
1424 spin_unlock_irqrestore(&smc->lock, flags);
1421 1425
1422 return 0; 1426 return 0;
1423} 1427}
@@ -1523,6 +1527,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
1523 DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name, 1527 DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
1524 irq, ioaddr); 1528 irq, ioaddr);
1525 1529
1530 spin_lock(&smc->lock);
1526 smc->watchdog = 0; 1531 smc->watchdog = 0;
1527 saved_bank = inw(ioaddr + BANK_SELECT); 1532 saved_bank = inw(ioaddr + BANK_SELECT);
1528 if ((saved_bank & 0xff00) != 0x3300) { 1533 if ((saved_bank & 0xff00) != 0x3300) {
@@ -1620,6 +1625,7 @@ irq_done:
1620 readb(smc->base+MEGAHERTZ_ISR); 1625 readb(smc->base+MEGAHERTZ_ISR);
1621 } 1626 }
1622#endif 1627#endif
1628 spin_unlock(&smc->lock);
1623 return IRQ_RETVAL(handled); 1629 return IRQ_RETVAL(handled);
1624} 1630}
1625 1631
@@ -1902,6 +1908,9 @@ static void media_check(u_long arg)
1902 kio_addr_t ioaddr = dev->base_addr; 1908 kio_addr_t ioaddr = dev->base_addr;
1903 u_short i, media, saved_bank; 1909 u_short i, media, saved_bank;
1904 u_short link; 1910 u_short link;
1911 unsigned long flags;
1912
1913 spin_lock_irqsave(&smc->lock, flags);
1905 1914
1906 saved_bank = inw(ioaddr + BANK_SELECT); 1915 saved_bank = inw(ioaddr + BANK_SELECT);
1907 1916
@@ -1934,6 +1943,7 @@ static void media_check(u_long arg)
1934 smc->media.expires = jiffies + HZ/100; 1943 smc->media.expires = jiffies + HZ/100;
1935 add_timer(&smc->media); 1944 add_timer(&smc->media);
1936 SMC_SELECT_BANK(saved_bank); 1945 SMC_SELECT_BANK(saved_bank);
1946 spin_unlock_irqrestore(&smc->lock, flags);
1937 return; 1947 return;
1938 } 1948 }
1939 1949
@@ -2007,6 +2017,7 @@ reschedule:
2007 smc->media.expires = jiffies + HZ; 2017 smc->media.expires = jiffies + HZ;
2008 add_timer(&smc->media); 2018 add_timer(&smc->media);
2009 SMC_SELECT_BANK(saved_bank); 2019 SMC_SELECT_BANK(saved_bank);
2020 spin_unlock_irqrestore(&smc->lock, flags);
2010} 2021}
2011 2022
2012static int smc_link_ok(struct net_device *dev) 2023static int smc_link_ok(struct net_device *dev)
@@ -2094,14 +2105,14 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
2094 u16 saved_bank = inw(ioaddr + BANK_SELECT); 2105 u16 saved_bank = inw(ioaddr + BANK_SELECT);
2095 int ret; 2106 int ret;
2096 2107
2097 SMC_SELECT_BANK(3);
2098 spin_lock_irq(&smc->lock); 2108 spin_lock_irq(&smc->lock);
2109 SMC_SELECT_BANK(3);
2099 if (smc->cfg & CFG_MII_SELECT) 2110 if (smc->cfg & CFG_MII_SELECT)
2100 ret = mii_ethtool_gset(&smc->mii_if, ecmd); 2111 ret = mii_ethtool_gset(&smc->mii_if, ecmd);
2101 else 2112 else
2102 ret = smc_netdev_get_ecmd(dev, ecmd); 2113 ret = smc_netdev_get_ecmd(dev, ecmd);
2103 spin_unlock_irq(&smc->lock);
2104 SMC_SELECT_BANK(saved_bank); 2114 SMC_SELECT_BANK(saved_bank);
2115 spin_unlock_irq(&smc->lock);
2105 return ret; 2116 return ret;
2106} 2117}
2107 2118
@@ -2112,14 +2123,14 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
2112 u16 saved_bank = inw(ioaddr + BANK_SELECT); 2123 u16 saved_bank = inw(ioaddr + BANK_SELECT);
2113 int ret; 2124 int ret;
2114 2125
2115 SMC_SELECT_BANK(3);
2116 spin_lock_irq(&smc->lock); 2126 spin_lock_irq(&smc->lock);
2127 SMC_SELECT_BANK(3);
2117 if (smc->cfg & CFG_MII_SELECT) 2128 if (smc->cfg & CFG_MII_SELECT)
2118 ret = mii_ethtool_sset(&smc->mii_if, ecmd); 2129 ret = mii_ethtool_sset(&smc->mii_if, ecmd);
2119 else 2130 else
2120 ret = smc_netdev_set_ecmd(dev, ecmd); 2131 ret = smc_netdev_set_ecmd(dev, ecmd);
2121 spin_unlock_irq(&smc->lock);
2122 SMC_SELECT_BANK(saved_bank); 2132 SMC_SELECT_BANK(saved_bank);
2133 spin_unlock_irq(&smc->lock);
2123 return ret; 2134 return ret;
2124} 2135}
2125 2136
@@ -2130,11 +2141,11 @@ static u32 smc_get_link(struct net_device *dev)
2130 u16 saved_bank = inw(ioaddr + BANK_SELECT); 2141 u16 saved_bank = inw(ioaddr + BANK_SELECT);
2131 u32 ret; 2142 u32 ret;
2132 2143
2133 SMC_SELECT_BANK(3);
2134 spin_lock_irq(&smc->lock); 2144 spin_lock_irq(&smc->lock);
2145 SMC_SELECT_BANK(3);
2135 ret = smc_link_ok(dev); 2146 ret = smc_link_ok(dev);
2136 spin_unlock_irq(&smc->lock);
2137 SMC_SELECT_BANK(saved_bank); 2147 SMC_SELECT_BANK(saved_bank);
2148 spin_unlock_irq(&smc->lock);
2138 return ret; 2149 return ret;
2139} 2150}
2140 2151