From 518ff04fd84290a7ad9042e8a46d78d29cb443d3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 17 Aug 2009 12:09:26 -0400 Subject: orinoco: correct key bounds check in orinoco_hw_get_tkip_iv If key is 4 that is an array out of bounds. Reported-by: Dan Carpenter Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 632fac86a308..b3946272c72e 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -70,7 +70,7 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc) int err = 0; u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE]; - if ((key < 0) || (key > 4)) + if ((key < 0) || (key >= 4)) return -EINVAL; err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, -- cgit v1.2.3 From e7a5965a81a29a13cd4994fa23a6a7a1488bcdb6 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Tue, 18 Aug 2009 20:21:40 -0700 Subject: yellowfin: Fix buffer underrun after dev_alloc_skb() failure yellowfin_init_ring() needs to clean up if dev_alloc_skb() fails and should pass an error status up to the caller. This also prevents an buffer underrun if failure occurred in the first iteration. yellowfin_open() which calls yellowfin_init_ring() should free its requested irq upon failure. Signed-off-by: Roel Kluin Signed-off-by: David S. Miller --- drivers/net/yellowfin.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index a07580138e81..c2fd6187773f 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int yellowfin_open(struct net_device *dev); static void yellowfin_timer(unsigned long data); static void yellowfin_tx_timeout(struct net_device *dev); -static void yellowfin_init_ring(struct net_device *dev); +static int yellowfin_init_ring(struct net_device *dev); static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); static int yellowfin_rx(struct net_device *dev); @@ -573,19 +573,24 @@ static int yellowfin_open(struct net_device *dev) { struct yellowfin_private *yp = netdev_priv(dev); void __iomem *ioaddr = yp->base; - int i; + int i, ret; /* Reset the chip. */ iowrite32(0x80000000, ioaddr + DMACtrl); - i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); - if (i) return i; + ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); + if (ret) + return ret; if (yellowfin_debug > 1) printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", dev->name, dev->irq); - yellowfin_init_ring(dev); + ret = yellowfin_init_ring(dev); + if (ret) { + free_irq(dev->irq, dev); + return ret; + } iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); @@ -725,10 +730,10 @@ static void yellowfin_tx_timeout(struct net_device *dev) } /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ -static void yellowfin_init_ring(struct net_device *dev) +static int yellowfin_init_ring(struct net_device *dev) { struct yellowfin_private *yp = netdev_priv(dev); - int i; + int i, j; yp->tx_full = 0; yp->cur_rx = yp->cur_tx = 0; @@ -753,6 +758,11 @@ static void yellowfin_init_ring(struct net_device *dev) yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } + if (i != RX_RING_SIZE) { + for (j = 0; j < i; j++) + dev_kfree_skb(yp->rx_skbuff[j]); + return -ENOMEM; + } yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -769,8 +779,6 @@ static void yellowfin_init_ring(struct net_device *dev) yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); #else { - int j; - /* Tx ring needs a pair of descriptors, the second for the status. */ for (i = 0; i < TX_RING_SIZE; i++) { j = 2*i; @@ -805,7 +813,7 @@ static void yellowfin_init_ring(struct net_device *dev) } #endif yp->tx_tail_desc = &yp->tx_status[0]; - return; + return 0; } static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) -- cgit v1.2.3 From 456d8991a795ff5e44dbc1c2a7f8d5b4ed675866 Mon Sep 17 00:00:00 2001 From: Wan ZongShun Date: Tue, 18 Aug 2009 23:34:58 -0700 Subject: net: Rename MAC platform driver for w90p910 platform Due to I modified the corresponding platform device name, so I make the patch to rename MAC platform driver for w90p910 platform. Signed-off-by: Wan ZongShun Signed-off-by: David S. Miller --- drivers/net/arm/w90p910_ether.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c index 616fb7985a34..ddd231cb54b7 100644 --- a/drivers/net/arm/w90p910_ether.c +++ b/drivers/net/arm/w90p910_ether.c @@ -1080,7 +1080,7 @@ static struct platform_driver w90p910_ether_driver = { .probe = w90p910_ether_probe, .remove = __devexit_p(w90p910_ether_remove), .driver = { - .name = "w90p910-emc", + .name = "nuc900-emc", .owner = THIS_MODULE, }, }; @@ -1101,5 +1101,5 @@ module_exit(w90p910_ether_exit); MODULE_AUTHOR("Wan ZongShun "); MODULE_DESCRIPTION("w90p910 MAC driver!"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:w90p910-emc"); +MODULE_ALIAS("platform:nuc900-emc"); -- cgit v1.2.3 From cbb35f8a2858f7e0fff5df598cb286c4bcae5976 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 19 Aug 2009 12:13:31 -0700 Subject: net: fix ks8851 build errors Fix build errors due to missing Kconfig select of CRC32: ks8851.c:(.text+0x7d2ee): undefined reference to `crc32_le' ks8851.c:(.text+0x7d2f5): undefined reference to `bitrev32' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5f6509a5f640..7a90e7ce5a9c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1733,6 +1733,7 @@ config KS8851 tristate "Micrel KS8851 SPI" depends on SPI select MII + select CRC32 help SPI driver for Micrel KS8851 SPI attached network chip. -- cgit v1.2.3 From d3b325f9c25be6d504bc73afce7f92d0e25001d7 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Thu, 20 Aug 2009 02:21:27 -0700 Subject: ibm_newemac: emac_close() needs to call netif_carrier_off() When ibm_newemac netdev instance is shutdown with "ifconfig down", the netdev interface does not go properly down. netif_carrier_ok() keeps returning TRUE even after "ifconfig down". The problem can be seen when ibm_newemac instances are slaves of a bonding interface. The bonding interface code uses netif_carrier_ok() to determine the link status of its slaves. When ibm_newemac slave is shutdown with "ifconfig down", the bonding interface won't detect any link status change because netif_carrier_ok() keeps returning TRUE. Signed-off-by: Petri Gynther Signed-off-by: David S. Miller --- drivers/net/ibm_newemac/core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index beb84213b671..f0f890803710 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -1305,6 +1305,8 @@ static int emac_close(struct net_device *ndev) free_irq(dev->emac_irq, dev); + netif_carrier_off(ndev); + return 0; } -- cgit v1.2.3 From 1a9937b7f07ab6e35515e32a7625f0ba50ab7670 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Thu, 20 Aug 2009 21:16:17 -0300 Subject: rtl8187: always set MSR_LINK_ENEDCA flag with RTL8187B RTL8187B always needs MSR_LINK_ENEDCA flag to be set even when it is in no link mode, otherwise it'll not be able to associate when this flag is not set after the change "mac80211: fix managed mode BSSID handling". By accident, setting BSSID of AP before association makes 8187B to successfuly associate even when ENEDCA flag isn't set, which was the case before the mac80211 change. But now the BSSID of AP we are trying to associate is only available after association is successful, and any attempt to associate without the needed flag doesn't work. Signed-off-by: Herton Ronaldo Krzesinski Tested-by: Larry Finger Acked-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 294250e294dd..87a95588a8e3 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -869,6 +869,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev) priv->aifsn[3] = 3; /* AIFSN[AC_BE] */ rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0); + /* ENEDCA flag must always be set, transmit issues? */ + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA); + return 0; } @@ -1173,13 +1176,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, rtl818x_iowrite8(priv, &priv->map->BSSID[i], info->bssid[i]); + if (priv->is_rtl8187b) + reg = RTL818X_MSR_ENEDCA; + else + reg = 0; + if (is_valid_ether_addr(info->bssid)) { - reg = RTL818X_MSR_INFRA; - if (priv->is_rtl8187b) - reg |= RTL818X_MSR_ENEDCA; + reg |= RTL818X_MSR_INFRA; rtl818x_iowrite8(priv, &priv->map->MSR, reg); } else { - reg = RTL818X_MSR_NO_LINK; + reg |= RTL818X_MSR_NO_LINK; rtl818x_iowrite8(priv, &priv->map->MSR, reg); } -- cgit v1.2.3 From 6ff9c2e7fa8ca63a575792534b63c5092099c286 Mon Sep 17 00:00:00 2001 From: Krzysztof Hałasa Date: Sun, 23 Aug 2009 19:02:13 -0700 Subject: E100: fix interaction with swiotlb on X86. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit E100 places it's RX packet descriptors inside skb->data and uses them with bidirectional streaming DMA mapping. Data in descriptors is accessed simultaneously by the chip (writing status and size when a packet is received) and CPU (reading to check if the packet was received). This isn't a valid usage of PCI DMA API, which requires use of the coherent (consistent) memory for such purpose. Unfortunately e100 chips working in "simplified" RX mode have to store received data directly after the descriptor. Fixing the driver to conform to the API would require using unsupported "flexible" RX mode or receiving data into a coherent memory and using CPU to copy it to network buffers. This patch, while not yet making the driver conform to the PCI DMA API, allows it to work correctly on X86 with swiotlb (while not breaking other architectures). Signed-off-by: Krzysztof Hałasa Signed-off-by: David S. Miller --- drivers/net/e100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 41b648a67fec..3a6735dc9f6a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1899,7 +1899,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, nic->ru_running = RU_SUSPENDED; pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, sizeof(struct rfd), - PCI_DMA_BIDIRECTIONAL); + PCI_DMA_FROMDEVICE); return -ENODATA; } -- cgit v1.2.3 From c189308bd8b6a29b11c3ec29a42a3f0aabad6bc8 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 21 Aug 2009 00:46:06 +0000 Subject: net: Fix Micrel KSZ8842 Kconfig description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andreas Mohr Acked-by: Richard Röjfors Signed-off-by: David S. Miller --- drivers/net/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7a90e7ce5a9c..5ce7cbabd7a7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1727,7 +1727,8 @@ config KS8842 tristate "Micrel KSZ8842" depends on HAS_IOMEM help - This platform driver is for Micrel KSZ8842 chip. + This platform driver is for Micrel KSZ8842 / KS8842 + 2-port ethernet switch chip (managed, VLAN, QoS). config KS8851 tristate "Micrel KS8851 SPI" -- cgit v1.2.3 From 4871953c0ef2cafeb37bbe186d9d13dcb24fc2c5 Mon Sep 17 00:00:00 2001 From: Dongdong Deng Date: Sun, 23 Aug 2009 19:49:07 -0700 Subject: drivers/net: fixed drivers that support netpoll use ndo_start_xmit() The NETPOLL API requires that interrupts remain disabled in netpoll_send_skb(). The use of "A functions set" in the NETPOLL API callbacks causes the interrupts to get enabled and can lead to kernel instability. The solution is to use "B functions set" to prevent the irqs from getting enabled while in netpoll_send_skb(). A functions set: local_irq_disable()/local_irq_enable() spin_lock_irq()/spin_unlock_irq() spin_trylock_irq()/spin_unlock_irq() B functions set: local_irq_save()/local_irq_restore() spin_lock_irqsave()/spin_unlock_irqrestore() spin_trylock_irqsave()/spin_unlock_irqrestore() Signed-off-by: Dongdong Deng Acked-by: Matt Mackall Signed-off-by: David S. Miller --- drivers/net/fec_mpc52xx.c | 5 +++-- drivers/net/ixp2000/ixpdev.c | 5 +++-- drivers/net/macb.c | 7 ++++--- drivers/net/mlx4/en_tx.c | 5 +++-- 4 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index cc786333d95c..c40113f58963 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -309,6 +309,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct mpc52xx_fec_priv *priv = netdev_priv(dev); struct bcom_fec_bd *bd; + unsigned long flags; if (bcom_queue_full(priv->tx_dmatsk)) { if (net_ratelimit()) @@ -316,7 +317,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - spin_lock_irq(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); dev->trans_start = jiffies; bd = (struct bcom_fec_bd *) @@ -332,7 +333,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); } - spin_unlock_irq(&priv->lock); + spin_unlock_irqrestore(&priv->lock, flags); return NETDEV_TX_OK; } diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 2a0174b62e96..92fb8235c766 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -41,6 +41,7 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev) struct ixpdev_priv *ip = netdev_priv(dev); struct ixpdev_tx_desc *desc; int entry; + unsigned long flags; if (unlikely(skb->len > PAGE_SIZE)) { /* @@@ Count drops. */ @@ -63,11 +64,11 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; - local_irq_disable(); + local_irq_save(flags); ip->tx_queue_entries++; if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN) netif_stop_queue(dev); - local_irq_enable(); + local_irq_restore(flags); return 0; } diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 5b5c25368d1e..e3601cf3f931 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -620,6 +620,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) dma_addr_t mapping; unsigned int len, entry; u32 ctrl; + unsigned long flags; #ifdef DEBUG int i; @@ -635,12 +636,12 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) #endif len = skb->len; - spin_lock_irq(&bp->lock); + spin_lock_irqsave(&bp->lock, flags); /* This is a hard error, log it. */ if (TX_BUFFS_AVAIL(bp) < 1) { netif_stop_queue(dev); - spin_unlock_irq(&bp->lock); + spin_unlock_irqrestore(&bp->lock, flags); dev_err(&bp->pdev->dev, "BUG! Tx Ring full when queue awake!\n"); dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n", @@ -674,7 +675,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) if (TX_BUFFS_AVAIL(bp) < 1) netif_stop_queue(dev); - spin_unlock_irq(&bp->lock); + spin_unlock_irqrestore(&bp->lock, flags); dev->trans_start = jiffies; diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 5a88b3f57693..62208401c4df 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -437,6 +437,7 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) { struct mlx4_en_cq *cq = &priv->tx_cq[tx_ind]; struct mlx4_en_tx_ring *ring = &priv->tx_ring[tx_ind]; + unsigned long flags; /* If we don't have a pending timer, set one up to catch our recent post in case the interface becomes idle */ @@ -445,9 +446,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */ if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0) - if (spin_trylock_irq(&ring->comp_lock)) { + if (spin_trylock_irqsave(&ring->comp_lock, flags)) { mlx4_en_process_tx_cq(priv->dev, cq); - spin_unlock_irq(&ring->comp_lock); + spin_unlock_irqrestore(&ring->comp_lock, flags); } } -- cgit v1.2.3 From d2f3ad4cedc00c8ee848e7abe9b2bbc93b9a8c2d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 23 Aug 2009 22:57:30 -0700 Subject: pxaficp-ir: remove incorrect net_device_ops This patch fixes broken pxaficp-ir. The problem was in incorrect net_device_ops being specified which prevented the driver from operating. The symptoms were: - failing ifconfig for IrLAN, resulting in SIOCSIFFLAGS: Cannot assign requested address - irattach working for IrCOMM, but the port stayed disabled Moreover this patch corrects missing sysfs device link. Signed-off-by: Marek Vasut Signed-off-by: David S. Miller --- drivers/net/irda/pxaficp_ir.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 3376a4f39e0a..77d10edefd25 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -803,9 +803,6 @@ static const struct net_device_ops pxa_irda_netdev_ops = { .ndo_stop = pxa_irda_stop, .ndo_start_xmit = pxa_irda_hard_xmit, .ndo_do_ioctl = pxa_irda_ioctl, - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, }; static int pxa_irda_probe(struct platform_device *pdev) @@ -830,6 +827,7 @@ static int pxa_irda_probe(struct platform_device *pdev) if (!dev) goto err_mem_3; + SET_NETDEV_DEV(dev, &pdev->dev); si = netdev_priv(dev); si->dev = &pdev->dev; si->pdata = pdev->dev.platform_data; -- cgit v1.2.3 From 8ff499e43c537648399fca8ba39d24c0768b3fab Mon Sep 17 00:00:00 2001 From: Dongdong Deng Date: Sun, 23 Aug 2009 22:59:04 -0700 Subject: smc91x: let smc91x work well under netpoll The NETPOLL requires that interrupts remain disabled in its callbacks. Using *_irq_save()/irq_restore() to replace *_irq_disable()/irq_enable() functions in NETPOLL's callbacks of smc91x, so that it doesn't enable interrupts when already disabled, and kgdboe/netconsole would work properly over smc91x. Signed-off-by: Dongdong Deng Acked-by: Nicolas Pitre Signed-off-by: David S. Miller --- drivers/net/smc91x.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 1c70e999cc50..9da1fa12a67c 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -196,21 +196,23 @@ static void PRINT_PKT(u_char *buf, int length) /* this enables an interrupt in the interrupt mask register */ #define SMC_ENABLE_INT(lp, x) do { \ unsigned char mask; \ - spin_lock_irq(&lp->lock); \ + unsigned long smc_enable_flags; \ + spin_lock_irqsave(&lp->lock, smc_enable_flags); \ mask = SMC_GET_INT_MASK(lp); \ mask |= (x); \ SMC_SET_INT_MASK(lp, mask); \ - spin_unlock_irq(&lp->lock); \ + spin_unlock_irqrestore(&lp->lock, smc_enable_flags); \ } while (0) /* this disables an interrupt from the interrupt mask register */ #define SMC_DISABLE_INT(lp, x) do { \ unsigned char mask; \ - spin_lock_irq(&lp->lock); \ + unsigned long smc_disable_flags; \ + spin_lock_irqsave(&lp->lock, smc_disable_flags); \ mask = SMC_GET_INT_MASK(lp); \ mask &= ~(x); \ SMC_SET_INT_MASK(lp, mask); \ - spin_unlock_irq(&lp->lock); \ + spin_unlock_irqrestore(&lp->lock, smc_disable_flags); \ } while (0) /* @@ -520,21 +522,21 @@ static inline void smc_rcv(struct net_device *dev) * any other concurrent access and C would always interrupt B. But life * isn't that easy in a SMP world... */ -#define smc_special_trylock(lock) \ +#define smc_special_trylock(lock, flags) \ ({ \ int __ret; \ - local_irq_disable(); \ + local_irq_save(flags); \ __ret = spin_trylock(lock); \ if (!__ret) \ - local_irq_enable(); \ + local_irq_restore(flags); \ __ret; \ }) -#define smc_special_lock(lock) spin_lock_irq(lock) -#define smc_special_unlock(lock) spin_unlock_irq(lock) +#define smc_special_lock(lock, flags) spin_lock_irq(lock, flags) +#define smc_special_unlock(lock, flags) spin_unlock_irqrestore(lock, flags) #else -#define smc_special_trylock(lock) (1) -#define smc_special_lock(lock) do { } while (0) -#define smc_special_unlock(lock) do { } while (0) +#define smc_special_trylock(lock, flags) (1) +#define smc_special_lock(lock, flags) do { } while (0) +#define smc_special_unlock(lock, flags) do { } while (0) #endif /* @@ -548,10 +550,11 @@ static void smc_hardware_send_pkt(unsigned long data) struct sk_buff *skb; unsigned int packet_no, len; unsigned char *buf; + unsigned long flags; DBG(3, "%s: %s\n", dev->name, __func__); - if (!smc_special_trylock(&lp->lock)) { + if (!smc_special_trylock(&lp->lock, flags)) { netif_stop_queue(dev); tasklet_schedule(&lp->tx_task); return; @@ -559,7 +562,7 @@ static void smc_hardware_send_pkt(unsigned long data) skb = lp->pending_tx_skb; if (unlikely(!skb)) { - smc_special_unlock(&lp->lock); + smc_special_unlock(&lp->lock, flags); return; } lp->pending_tx_skb = NULL; @@ -569,7 +572,7 @@ static void smc_hardware_send_pkt(unsigned long data) printk("%s: Memory allocation failed.\n", dev->name); dev->stats.tx_errors++; dev->stats.tx_fifo_errors++; - smc_special_unlock(&lp->lock); + smc_special_unlock(&lp->lock, flags); goto done; } @@ -608,7 +611,7 @@ static void smc_hardware_send_pkt(unsigned long data) /* queue the packet for TX */ SMC_SET_MMU_CMD(lp, MC_ENQUEUE); - smc_special_unlock(&lp->lock); + smc_special_unlock(&lp->lock, flags); dev->trans_start = jiffies; dev->stats.tx_packets++; @@ -633,6 +636,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct smc_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; unsigned int numPages, poll_count, status; + unsigned long flags; DBG(3, "%s: %s\n", dev->name, __func__); @@ -658,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - smc_special_lock(&lp->lock); + smc_special_lock(&lp->lock, flags); /* now, try to allocate the memory */ SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages); @@ -676,7 +680,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } } while (--poll_count); - smc_special_unlock(&lp->lock); + smc_special_unlock(&lp->lock, flags); lp->pending_tx_skb = skb; if (!poll_count) { -- cgit v1.2.3