diff options
author | Komuro <komurojun@nifty.com> | 2007-07-23 08:36:06 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-30 15:58:13 -0400 |
commit | 85e27831941e0d907be8e244202a293d74730e12 (patch) | |
tree | 906ebc4b9141582a422cb4aa94e50d2709adba8c | |
parent | 573608e4cde2aa3b76120685fba945d889b2ba57 (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>
-rw-r--r-- | drivers/net/pcmcia/smc91c92_cs.c | 23 |
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 | ||
2012 | static int smc_link_ok(struct net_device *dev) | 2023 | static 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 | ||