From 1a79d1c37178935a3092f73c8832933e9fed1f66 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 2 Jun 2008 10:59:02 +0100 Subject: s2io iomem annotations Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- drivers/net/s2io.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a20693e09ae..b5c1e663417 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2861,7 +2861,8 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) struct config_param *config; struct mac_info *mac_control; int pkts_processed = 0; - u8 *addr = NULL, val8 = 0; + u8 __iomem *addr = NULL; + u8 val8 = 0; struct s2io_nic *nic = dev->priv; struct XENA_dev_config __iomem *bar0 = nic->bar0; int budget_org = budget; @@ -2878,7 +2879,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); /*Re Enable MSI-Rx Vector*/ - addr = (u8 *)&bar0->xmsi_mask_reg; + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; addr += 7 - ring->ring_no; val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; writeb(val8, addr); @@ -4364,9 +4365,10 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) return IRQ_HANDLED; if (sp->config.napi) { - u8 *addr = NULL, val8 = 0; + u8 __iomem *addr = NULL; + u8 val8 = 0; - addr = (u8 *)&bar0->xmsi_mask_reg; + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; addr += (7 - ring->ring_no); val8 = (ring->ring_no == 0) ? 0x7f : 0xff; writeb(val8, addr); -- cgit v1.2.3-70-g09d2 From 60d5019be8acef268f4676d229c490186d338fbc Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Wed, 4 Jun 2008 08:31:28 +1000 Subject: [POWERPC] ehea: Remove dependency on MEMORY_HOTPLUG Now that walk_memory_resource() is available regardless of MEMORY_HOTPLUG's setting, this dependency is not needed. Signed-off-by: Nathan Lynch Acked-by: Jeff Garzik Acked-by: Yasunori Goto Signed-off-by: Paul Mackerras --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dd0ec9ebc93..f4182cfffe9 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2426,7 +2426,7 @@ config CHELSIO_T3 config EHEA tristate "eHEA Ethernet support" - depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG + depends on IBMEBUS && INET && SPARSEMEM select INET_LRO ---help--- This driver supports the IBM pSeries eHEA ethernet adapter. -- cgit v1.2.3-70-g09d2 From 6b6707a50c7598a83820077393f8823ab791abf8 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Tue, 10 Jun 2008 12:35:00 -0700 Subject: l2tp: Fix potential memory corruption in pppol2tp_recvmsg() This patch fixes a potential memory corruption in pppol2tp_recvmsg(). If skb->len is bigger than the caller's buffer length, memcpy_toiovec() will go into unintialized data on the kernel heap, interpret it as an iovec and start modifying memory. The fix is to change the memcpy_toiovec() call to skb_copy_datagram_iovec() so that paged packets (rare for PPPOL2TP) are handled properly. Also check that the caller's buffer is big enough for the data and set the MSG_TRUNC flag if it is not so. Reported-by: Ilja Signed-off-by: James Chapman Signed-off-by: David S. Miller --- drivers/net/pppol2tp.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 70cfdb46aa2..f9298827a76 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -783,14 +783,18 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err = 0; skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); - if (skb) { - err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, - skb->len); - if (err < 0) - goto do_skb_free; - err = skb->len; - } -do_skb_free: + if (!skb) + goto end; + + if (len > skb->len) + len = skb->len; + else if (len < skb->len) + msg->msg_flags |= MSG_TRUNC; + + err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len); + if (likely(err == 0)) + err = len; + kfree_skb(skb); end: return err; -- cgit v1.2.3-70-g09d2 From 392fdb0e35055b96faa9c1cd6ab537805337cdce Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 10 Jun 2008 14:07:25 -0700 Subject: net pppoe: Check packet length on all receive paths The length field in the PPPOE header wasn't checked completely. This patch causes all packets shorter than the declared length to be dropped. It also changes the memcpy_toiovec call to skb_copy_datagram_iovec so that paged packets (rare for PPPOE) are handled properly. Thanks to Ilja of the Netric Security Team for discovering and reporting this bug, and Chris Wright for the total_len check. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 58a26a47af2..d89ccfd6650 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -341,12 +341,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) struct pppox_sock *relay_po; if (sk->sk_state & PPPOX_BOUND) { - struct pppoe_hdr *ph = pppoe_hdr(skb); - int len = ntohs(ph->length); - skb_pull_rcsum(skb, sizeof(struct pppoe_hdr)); - if (pskb_trim_rcsum(skb, len)) - goto abort_kfree; - ppp_input(&po->chan, skb); } else if (sk->sk_state & PPPOX_RELAY) { relay_po = get_item_by_addr(&po->pppoe_relay); @@ -357,7 +351,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) goto abort_put; - skb_pull(skb, sizeof(struct pppoe_hdr)); if (!__pppoe_xmit(sk_pppox(relay_po), skb)) goto abort_put; } else { @@ -388,6 +381,7 @@ static int pppoe_rcv(struct sk_buff *skb, { struct pppoe_hdr *ph; struct pppox_sock *po; + int len; if (!(skb = skb_share_check(skb, GFP_ATOMIC))) goto out; @@ -399,10 +393,21 @@ static int pppoe_rcv(struct sk_buff *skb, goto drop; ph = pppoe_hdr(skb); + len = ntohs(ph->length); + + skb_pull_rcsum(skb, sizeof(*ph)); + if (skb->len < len) + goto drop; po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); - if (po != NULL) - return sk_receive_skb(sk_pppox(po), skb, 0); + if (!po) + goto drop; + + if (pskb_trim_rcsum(skb, len)) + goto drop; + + return sk_receive_skb(sk_pppox(po), skb, 0); + drop: kfree_skb(skb); out: @@ -937,12 +942,10 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, m->msg_namelen = 0; if (skb) { - struct pppoe_hdr *ph = pppoe_hdr(skb); - const int len = ntohs(ph->length); - - error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len); + total_len = min(total_len, skb->len); + error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); if (error == 0) - error = len; + error = total_len; } kfree_skb(skb); -- cgit v1.2.3-70-g09d2 From bc6cffd177f9266af38dba96a2cea06c1e7ff932 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 10 Jun 2008 14:08:25 -0700 Subject: pppoe: Unshare skb before anything else We need to unshare the skb first as otherwise pskb_may_pull may write to a shared skb which could be bad. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d89ccfd6650..bafb69b6f7c 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -432,12 +432,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb, if (dev_net(dev) != &init_net) goto abort; - if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) - goto abort; - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) goto out; + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) + goto abort; + ph = pppoe_hdr(skb); if (ph->code != PADT_CODE) goto abort; -- cgit v1.2.3-70-g09d2 From 4db0ee176e256444695ee2d7b004552e82fec987 Mon Sep 17 00:00:00 2001 From: Ayaz Abdulla Date: Mon, 9 Jun 2008 16:51:06 -0700 Subject: forcedeth: msi interrupts Add a workaround for lost MSI interrupts. There is a race condition in the HW in which future interrupts could be missed. The workaround is to toggle the MSI irq mask. Added cleanup based on comments from Andrew Morton. Signed-off-by: Ayaz Abdulla Cc: Manfred Spraul Cc: Jeff Garzik Cc: Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/forcedeth.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 9eca97fb0a5..2cb24476329 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3273,6 +3273,20 @@ static void nv_link_irq(struct net_device *dev) dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } +static void nv_msi_workaround(struct fe_priv *np) +{ + + /* Need to toggle the msi irq mask within the ethernet device, + * otherwise, future interrupts will not be detected. + */ + if (np->msi_flags & NV_MSI_ENABLED) { + u8 __iomem *base = np->base; + + writel(0, base + NvRegMSIIrqMask); + writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); + } +} + static irqreturn_t nv_nic_irq(int foo, void *data) { struct net_device *dev = (struct net_device *) data; @@ -3295,6 +3309,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) if (!(events & np->irqmask)) break; + nv_msi_workaround(np); + spin_lock(&np->lock); nv_tx_done(dev); spin_unlock(&np->lock); @@ -3410,6 +3426,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) if (!(events & np->irqmask)) break; + nv_msi_workaround(np); + spin_lock(&np->lock); nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); spin_unlock(&np->lock); @@ -3750,6 +3768,8 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) if (!(events & NVREG_IRQ_TIMER)) return IRQ_RETVAL(0); + nv_msi_workaround(np); + spin_lock(&np->lock); np->intr_test = 1; spin_unlock(&np->lock); -- cgit v1.2.3-70-g09d2 From ff68cdbf86f09e602eb2b04e1a7d448a3c3a3b28 Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Mon, 9 Jun 2008 15:57:17 -0700 Subject: ixgbe: fix typo Define names were accidently transposed. Signed-off-by: Jeff Kirsher Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_82598.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 6321b059ce1..2f38e847e2c 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -58,8 +58,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) { - hw->mac.num_rx_queues = IXGBE_82598_MAX_TX_QUEUES; - hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES; + hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES; + hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES; hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; /* PHY ops are filled in by default properly for Fiber only */ -- cgit v1.2.3-70-g09d2 From bf4d593479e0a3f349118f9b8c40a6bc37bf1e2e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 10 Jun 2008 01:22:16 +0300 Subject: add missing lance_* exports This patch fixes the following build error: <-- snip --> ... Building modules, stage 2. MODPOST 1203 modules ERROR: "lance_open" [drivers/net/mvme147.ko] undefined! ERROR: "lance_close" [drivers/net/mvme147.ko] undefined! ERROR: "lance_tx_timeout" [drivers/net/mvme147.ko] undefined! ERROR: "lance_set_multicast" [drivers/net/mvme147.ko] undefined! ERROR: "lance_start_xmit" [drivers/net/mvme147.ko] undefined! ... make[2]: *** [__modpost] Error 1 <-- snip --> Reported-by: Adrian Bunk Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/7990.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/7990.c b/drivers/net/7990.c index 750a46f4bc5..ad6b8a5b657 100644 --- a/drivers/net/7990.c +++ b/drivers/net/7990.c @@ -506,6 +506,7 @@ int lance_open (struct net_device *dev) return res; } +EXPORT_SYMBOL_GPL(lance_open); int lance_close (struct net_device *dev) { @@ -521,6 +522,7 @@ int lance_close (struct net_device *dev) return 0; } +EXPORT_SYMBOL_GPL(lance_close); void lance_tx_timeout(struct net_device *dev) { @@ -529,7 +531,7 @@ void lance_tx_timeout(struct net_device *dev) dev->trans_start = jiffies; netif_wake_queue (dev); } - +EXPORT_SYMBOL_GPL(lance_tx_timeout); int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { @@ -586,6 +588,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) return 0; } +EXPORT_SYMBOL_GPL(lance_start_xmit); /* taken from the depca driver via a2065.c */ static void lance_load_multicast (struct net_device *dev) @@ -654,6 +657,7 @@ void lance_set_multicast (struct net_device *dev) if (!stopped) netif_start_queue (dev); } +EXPORT_SYMBOL_GPL(lance_set_multicast); #ifdef CONFIG_NET_POLL_CONTROLLER void lance_poll(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 23bdfdd388723b8213f597743b1d4aba0d62de9c Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Mon, 9 Jun 2008 19:34:32 +0100 Subject: sfc: Recover from RX queue flush failure RX queue flush can fail if traffic continues to arrive. Recover by performing an invisible reset. Signed-off-by: Ben Hutchings Signed-off-by: Jeff Garzik --- drivers/net/sfc/falcon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index d3f749c72d4..790db89db34 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -733,8 +733,10 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) continue; break; } - if (rc) + if (rc) { EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); + efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); + } /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); -- cgit v1.2.3-70-g09d2 From 00aaea2f95d73d4e2b5e45cf77c3cbb16c59e87f Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Mon, 9 Jun 2008 15:17:37 +0100 Subject: ehea: set mac address fix eHEA has to call firmware functions in order to change the mac address of a logical port. This patch checks if the logical port is up when calling the register / deregister mac address calls. If the port is down these firmware calls would fail and are therefore not executed. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 287a6191873..faae01dc1c4 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1766,16 +1766,20 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) mutex_lock(&ehea_bcmc_regs.lock); /* Deregister old MAC in pHYP */ - ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); - if (ret) - goto out_upregs; + if (port->state == EHEA_PORT_UP) { + ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); + if (ret) + goto out_upregs; + } port->mac_addr = cb0->port_mac_addr << 16; /* Register new MAC in pHYP */ - ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); - if (ret) - goto out_upregs; + if (port->state == EHEA_PORT_UP) { + ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); + if (ret) + goto out_upregs; + } ret = 0; -- cgit v1.2.3-70-g09d2 From 23cde76d801246a702e7a84c3fe3d655b35c89a1 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Sun, 8 Jun 2008 20:49:00 +1000 Subject: virtio_net: Fix skb->csum_start computation hdr->csum_start is the offset from the start of the ethernet header to the transport layer checksum field. skb->csum_start is the offset from skb->head. skb_partial_csum_set() assumes that skb->data points to the ethernet header - i.e. it computes skb->csum_start by adding the headroom to hdr->csum_start. Since eth_type_trans() skb_pull()s the ethernet header, skb_partial_csum_set() should be called before eth_type_trans(). (Without this patch, GSO packets from a guest to the world outside the host are corrupted). Signed-off-by: Mark McLoughlin Acked-by: Herbert Xu Signed-off-by: Rusty Russell Signed-off-by: Jeff Garzik --- drivers/net/virtio_net.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 5450eac9e26..9a3b85e55cc 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -94,9 +94,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, BUG_ON(len > MAX_PACKET_LEN); skb_trim(skb, len); - skb->protocol = eth_type_trans(skb, dev); - pr_debug("Receiving skb proto 0x%04x len %i type %i\n", - ntohs(skb->protocol), skb->len, skb->pkt_type); + dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; @@ -106,6 +104,10 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, goto frame_err; } + skb->protocol = eth_type_trans(skb, dev); + pr_debug("Receiving skb proto 0x%04x len %i type %i\n", + ntohs(skb->protocol), skb->len, skb->pkt_type); + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { -- cgit v1.2.3-70-g09d2 From 14c998f034bdc9a5bfa53bca18fbd0738cbc65e8 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Sun, 8 Jun 2008 20:50:56 +1000 Subject: virtio: virtio_net free transmit skbs in a timer virtio_net currently only frees old transmit skbs just before queueing new ones. If the queue is full, it then enables interrupts and waits for notification that more work has been performed. However, a side-effect of this scheme is that there are always xmit skbs left dangling when no new packets are sent, against the Documentation/networking/driver.txt guideline: "... it is not allowed for your TX mitigation scheme to let TX packets "hang out" in the TX ring unreclaimed forever if no new TX packets are sent." Add a timer to ensure that any time we queue new TX skbs, we will shortly free them again. This fixes an easily reproduced hang at shutdown where iptables attempts to unload nf_conntrack and nf_conntrack waits for an skb it is tracking to be freed, but virtio_net never frees it. Signed-off-by: Mark McLoughlin Signed-off-by: Rusty Russell Signed-off-by: Jeff Garzik --- drivers/net/virtio_net.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9a3b85e55cc..156d76fee16 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -44,6 +44,8 @@ struct virtnet_info /* The skb we couldn't send because buffers were full. */ struct sk_buff *last_xmit_skb; + struct timer_list xmit_free_timer; + /* Number of input buffers, and max we've ever had. */ unsigned int num, max; @@ -240,9 +242,23 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) } } +static void xmit_free(unsigned long data) +{ + struct virtnet_info *vi = (void *)data; + + netif_tx_lock(vi->dev); + + free_old_xmit_skbs(vi); + + if (!skb_queue_empty(&vi->send)) + mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); + + netif_tx_unlock(vi->dev); +} + static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) { - int num; + int num, err; struct scatterlist sg[2+MAX_SKB_FRAGS]; struct virtio_net_hdr *hdr; const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; @@ -285,7 +301,11 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) vnet_hdr_to_sg(sg, skb); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; - return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); + err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); + if (!err) + mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); + + return err; } static void xmit_tasklet(unsigned long data) @@ -456,6 +476,8 @@ static int virtnet_probe(struct virtio_device *vdev) tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); + setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); + err = register_netdev(dev); if (err) { pr_debug("virtio_net: registering device failed\n"); @@ -493,6 +515,8 @@ static void virtnet_remove(struct virtio_device *vdev) /* Stop all the virtqueues. */ vdev->config->reset(vdev); + del_timer_sync(&vi->xmit_free_timer); + /* Free our skbs in send and recv queues, if any. */ while ((skb = __skb_dequeue(&vi->recv)) != NULL) { kfree_skb(skb); -- cgit v1.2.3-70-g09d2 From 363f15149cfba67d29f1e6a6103dda079f27f3fa Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 8 Jun 2008 20:51:55 +1000 Subject: virtio: use callback on empty in virtio_net virtio_net uses a timer to free old transmitted packets, rather than leaving callbacks enabled all the time. If the host promises to always notify us when the transmit ring is empty, we can free packets at that point and avoid the timer. Signed-off-by: Rusty Russell Signed-off-by: Jeff Garzik --- drivers/net/virtio_net.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 156d76fee16..4452306d532 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -44,6 +44,7 @@ struct virtnet_info /* The skb we couldn't send because buffers were full. */ struct sk_buff *last_xmit_skb; + /* If we need to free in a timer, this is it. */ struct timer_list xmit_free_timer; /* Number of input buffers, and max we've ever had. */ @@ -51,6 +52,7 @@ struct virtnet_info /* For cleaning up after transmission. */ struct tasklet_struct tasklet; + bool free_in_tasklet; /* Receive & send queues. */ struct sk_buff_head recv; @@ -74,7 +76,7 @@ static void skb_xmit_done(struct virtqueue *svq) /* Suppress further interrupts. */ svq->vq_ops->disable_cb(svq); - /* We were waiting for more output buffers. */ + /* We were probably waiting for more output buffers. */ netif_wake_queue(vi->dev); /* Make sure we re-xmit last_xmit_skb: if there are no more packets @@ -242,6 +244,8 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) } } +/* If the virtio transport doesn't always notify us when all in-flight packets + * are consumed, we fall back to using this function on a timer to free them. */ static void xmit_free(unsigned long data) { struct virtnet_info *vi = (void *)data; @@ -302,7 +306,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); - if (!err) + if (!err && !vi->free_in_tasklet) mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); return err; @@ -317,6 +321,8 @@ static void xmit_tasklet(unsigned long data) vi->svq->vq_ops->kick(vi->svq); vi->last_xmit_skb = NULL; } + if (vi->free_in_tasklet) + free_old_xmit_skbs(vi); netif_tx_unlock_bh(vi->dev); } @@ -457,6 +463,10 @@ static int virtnet_probe(struct virtio_device *vdev) vi->vdev = vdev; vdev->priv = vi; + /* If they give us a callback when all buffers are done, we don't need + * the timer. */ + vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); + /* We expect two virtqueues, receive then send. */ vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); if (IS_ERR(vi->rvq)) { @@ -476,7 +486,8 @@ static int virtnet_probe(struct virtio_device *vdev) tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); - setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); + if (!vi->free_in_tasklet) + setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); err = register_netdev(dev); if (err) { @@ -515,7 +526,8 @@ static void virtnet_remove(struct virtio_device *vdev) /* Stop all the virtqueues. */ vdev->config->reset(vdev); - del_timer_sync(&vi->xmit_free_timer); + if (!vi->free_in_tasklet) + del_timer_sync(&vi->xmit_free_timer); /* Free our skbs in send and recv queues, if any. */ while ((skb = __skb_dequeue(&vi->recv)) != NULL) { @@ -540,7 +552,7 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, - VIRTIO_NET_F_HOST_ECN, + VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, }; static struct virtio_driver virtio_net = { -- cgit v1.2.3-70-g09d2 From ae6b4d9ab6129467415801f30e487bc141a3f471 Mon Sep 17 00:00:00 2001 From: Jay Cliburn Date: Sun, 1 Jun 2008 16:57:11 -0500 Subject: atl1: fix suspend regression Using vendor magic to force the PHY into power save mode breaks suspend. It isn't needed anyway, so remove it. Tested-by: Avuton Olrich Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- drivers/net/atlx/atl1.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 6ddc911e7d1..99e0b4cdc56 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -636,22 +636,6 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) return atl1_write_phy_reg(hw, 30, 0); } -/* - * Force the PHY into power saving mode using vendor magic. - */ -#ifdef CONFIG_PM -static void atl1_phy_enter_power_saving(struct atl1_hw *hw) -{ - atl1_write_phy_reg(hw, MII_DBG_ADDR, 0); - atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E); - atl1_write_phy_reg(hw, MII_DBG_ADDR, 2); - atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000); - atl1_write_phy_reg(hw, MII_DBG_ADDR, 3); - atl1_write_phy_reg(hw, MII_DBG_DATA, 0); - -} -#endif - /* * Resets the PHY and make all config validate * hw - Struct containing variables accessed by shared code @@ -2860,7 +2844,6 @@ disable_wol: ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC); - atl1_phy_enter_power_saving(hw); hw->phy_configured = false; pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); exit: -- cgit v1.2.3-70-g09d2 From 69de8d23d10694bdd63fe715b98e1a61c56ed288 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 2 Jun 2008 10:59:02 +0100 Subject: s2io iomem annotations Signed-off-by: Al Viro Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index a20693e09ae..b5c1e663417 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2861,7 +2861,8 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) struct config_param *config; struct mac_info *mac_control; int pkts_processed = 0; - u8 *addr = NULL, val8 = 0; + u8 __iomem *addr = NULL; + u8 val8 = 0; struct s2io_nic *nic = dev->priv; struct XENA_dev_config __iomem *bar0 = nic->bar0; int budget_org = budget; @@ -2878,7 +2879,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); /*Re Enable MSI-Rx Vector*/ - addr = (u8 *)&bar0->xmsi_mask_reg; + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; addr += 7 - ring->ring_no; val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; writeb(val8, addr); @@ -4364,9 +4365,10 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) return IRQ_HANDLED; if (sp->config.napi) { - u8 *addr = NULL, val8 = 0; + u8 __iomem *addr = NULL; + u8 val8 = 0; - addr = (u8 *)&bar0->xmsi_mask_reg; + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; addr += (7 - ring->ring_no); val8 = (ring->ring_no == 0) ? 0x7f : 0xff; writeb(val8, addr); -- cgit v1.2.3-70-g09d2 From 68c2889834602f6efed195f44439ef5d526683a8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 31 May 2008 16:52:52 +0100 Subject: sky2: Hold RTNL while calling dev_close() dev_close() must be called holding the RTNL. Signed-off-by: Ben Hutchings Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3bb60530d4d..62436b3a18c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4404,7 +4404,9 @@ static int sky2_resume(struct pci_dev *pdev) if (err) { printk(KERN_ERR PFX "%s: could not up: %d\n", dev->name, err); + rtnl_lock(); dev_close(dev); + rtnl_unlock(); goto out; } } -- cgit v1.2.3-70-g09d2 From 7427d8b815c7fc0b005a17cf3952b7ebef0481d2 Mon Sep 17 00:00:00 2001 From: Bryan Wu Date: Wed, 11 Jun 2008 12:08:39 +0800 Subject: smc91x: fix build error from the SMC_GET_MAC_ADDR API change Cc: Jeff Garzik Cc: Andrew Morton Signed-off-by: Bryan Wu Signed-off-by: Linus Torvalds --- drivers/net/smc91x.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 69e97a1cb1c..8606818653f 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -93,14 +93,14 @@ #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) # endif /* check if the mac in reg is valid */ -#define SMC_GET_MAC_ADDR(addr) \ +#define SMC_GET_MAC_ADDR(lp, addr) \ do { \ unsigned int __v; \ - __v = SMC_inw(ioaddr, ADDR0_REG); \ + __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ addr[0] = __v; addr[1] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR1_REG); \ + __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ addr[2] = __v; addr[3] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR2_REG); \ + __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ addr[4] = __v; addr[5] = __v >> 8; \ if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ random_ether_addr(addr); \ -- cgit v1.2.3-70-g09d2 From 0761248f08ccd94ddceb5454eb1ad96626b10611 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 9 Jun 2008 16:33:50 -0700 Subject: ipg: fix receivemode IPG_RM_RECEIVEMULTICAST{,HASH} in ipg_nic_set_multicast_list() The branches are dead code. even when dev->flag IFF_MULTICAST (defined 0x1000) is set, dev->flags & IFF_MULTICAST & [boolean] always evaluates to 0. Signed-off-by: Roel Kluin Cc: Francois Romieu Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/ipg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9b358f61ed7..679a0826780 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -577,12 +577,12 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) /* NIC to be configured in promiscuous mode. */ receivemode = IPG_RM_RECEIVEALLFRAMES; } else if ((dev->flags & IFF_ALLMULTI) || - (dev->flags & IFF_MULTICAST & + ((dev->flags & IFF_MULTICAST) && (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { /* NIC to be configured to receive all multicast * frames. */ receivemode |= IPG_RM_RECEIVEMULTICAST; - } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { + } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { /* NIC to be configured to receive selected * multicast addresses. */ receivemode |= IPG_RM_RECEIVEMULTICASTHASH; -- cgit v1.2.3-70-g09d2 From 8b9835108f68938a5f7e74fd2c0fc65da2abad92 Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Mon, 9 Jun 2008 16:33:51 -0700 Subject: fec_mpc52xx: MPC52xx_MESSAGES_DEFAULT: 2nd NETIF_MSG_IFDOWN => IFUP Duplicate NETIF_MSG_IFDOWN, 2nd should be NETIF_MSG_IFUP Signed-off-by: Roel Kluin Acked-by: Sylvain Munaut Cc: Grant Likely Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/fec_mpc52xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 5f9c42e7a7f..329edd9c08f 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -78,7 +78,7 @@ module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0); MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ - NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN ) + NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) static int debug = -1; /* the above default */ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "debugging messages level"); -- cgit v1.2.3-70-g09d2 From 208aefa2451cc1f4d87622cb9b2ca4333afa8337 Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Thu, 15 May 2008 23:26:22 +0200 Subject: drivers/net/r6040.c: correct bad use of round_jiffies() Compared to other places in the kernel, I think that this driver misuses the function round_jiffies. Signed-off-by: Christophe Jaillet Signed-off-by: Jeff Garzik --- drivers/net/r6040.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 169edc15492..858b191517b 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -733,7 +733,7 @@ static void r6040_timer(unsigned long data) } /* Timer active again */ - mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); + mod_timer(&lp->timer, round_jiffies(jiffies + HZ)); } /* Read/set MAC address routines */ -- cgit v1.2.3-70-g09d2 From 4bb073c0e32a0862bdb5215d11af19f6c0180c98 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 12 Jun 2008 02:22:02 -0700 Subject: net: Eliminate flush_scheduled_work() calls while RTNL is held. If the RTNL is held when we invoke flush_scheduled_work() we could deadlock. One such case is linkwatch, it is a work struct which tries to grab the RTNL semaphore. The most common case are net driver ->stop() methods. The simplest conversion is to instead use cancel_{delayed_}work_sync() explicitly on the various work struct the driver uses. This is an OK transformation because these work structs are doing things like resetting the chip, restarting link negotiation, and so forth. And if we're bringing down the device, we're about to turn the chip off and reset it anways. So if we cancel a pending work event, that's fine here. Some drivers were working around this deadlock by using a msleep() polling loop of some sort, and those cases are converted to instead use cancel_{delayed_}work_sync() as well. Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 9 +-------- drivers/net/bnx2.h | 1 - drivers/net/ehea/ehea_main.c | 3 ++- drivers/net/hamradio/baycom_epp.c | 2 +- drivers/net/smc911x.c | 24 +++++------------------- drivers/net/smc91x.c | 17 +++-------------- drivers/net/tulip/tulip_core.c | 2 +- drivers/net/usb/kaweth.c | 2 +- drivers/net/wireless/hostap/hostap_main.c | 8 +++++++- 9 files changed, 21 insertions(+), 47 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4b46e68183e..367b6d46270 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -5724,14 +5724,12 @@ bnx2_reset_task(struct work_struct *work) if (!netif_running(bp->dev)) return; - bp->in_reset_task = 1; bnx2_netif_stop(bp); bnx2_init_nic(bp); atomic_set(&bp->intr_sem, 1); bnx2_netif_start(bp); - bp->in_reset_task = 0; } static void @@ -5907,12 +5905,7 @@ bnx2_close(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); u32 reset_code; - /* Calling flush_scheduled_work() may deadlock because - * linkwatch_event() may be on the workqueue and it will try to get - * the rtnl_lock which we are holding. - */ - while (bp->in_reset_task) - msleep(1); + cancel_work_sync(&bp->reset_task); bnx2_disable_int_sync(bp); bnx2_napi_disable(bp); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 1eaf5bb3d9c..2377cc13bf6 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6656,7 +6656,6 @@ struct bnx2 { int current_interval; struct timer_list timer; struct work_struct reset_task; - int in_reset_task; /* Used to synchronize phy accesses. */ spinlock_t phy_lock; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index faae01dc1c4..075fd547421 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2605,7 +2605,8 @@ static int ehea_stop(struct net_device *dev) if (netif_msg_ifdown(port)) ehea_info("disabling port %s", dev->name); - flush_scheduled_work(); + cancel_work_sync(&port->reset_task); + mutex_lock(&port->port_lock); netif_stop_queue(dev); port_napi_disable(port); diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index dde9c7e6408..00bc7fbb6b3 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -959,7 +959,7 @@ static int epp_close(struct net_device *dev) unsigned char tmp[1]; bc->work_running = 0; - flush_scheduled_work(); + cancel_delayed_work_sync(&bc->run_work); bc->stat = EPP_DCDBIT; tmp[0] = 0; pp->ops->epp_write_addr(pp, tmp, 1, 0); diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4e280020518..e2ee91a6ae7 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -136,7 +136,6 @@ struct smc911x_local { /* work queue */ struct work_struct phy_configure; - int work_pending; int tx_throttle; spinlock_t lock; @@ -960,11 +959,11 @@ static void smc911x_phy_configure(struct work_struct *work) * We should not be called if phy_type is zero. */ if (lp->phy_type == 0) - goto smc911x_phy_configure_exit_nolock; + return; if (smc911x_phy_reset(dev, phyaddr)) { printk("%s: PHY reset timed out\n", dev->name); - goto smc911x_phy_configure_exit_nolock; + return; } spin_lock_irqsave(&lp->lock, flags); @@ -1033,8 +1032,6 @@ static void smc911x_phy_configure(struct work_struct *work) smc911x_phy_configure_exit: spin_unlock_irqrestore(&lp->lock, flags); -smc911x_phy_configure_exit_nolock: - lp->work_pending = 0; } /* @@ -1356,11 +1353,8 @@ static void smc911x_timeout(struct net_device *dev) * smc911x_phy_configure() calls msleep() which calls schedule_timeout() * which calls schedule(). Hence we use a work queue. */ - if (lp->phy_type != 0) { - if (schedule_work(&lp->phy_configure)) { - lp->work_pending = 1; - } - } + if (lp->phy_type != 0) + schedule_work(&lp->phy_configure); /* We can accept TX packets again */ dev->trans_start = jiffies; @@ -1531,16 +1525,8 @@ static int smc911x_close(struct net_device *dev) if (lp->phy_type != 0) { /* We need to ensure that no calls to * smc911x_phy_configure are pending. - - * flush_scheduled_work() cannot be called because we - * are running with the netlink semaphore held (from - * devinet_ioctl()) and the pending work queue - * contains linkwatch_event() (scheduled by - * netif_carrier_off() above). linkwatch_event() also - * wants the netlink semaphore. */ - while (lp->work_pending) - schedule(); + cancel_work_sync(&lp->phy_configure); smc911x_phy_powerdown(dev, lp->mii.phy_id); } diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index a188e33484e..f2051b209da 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1016,15 +1016,8 @@ static void smc_phy_powerdown(struct net_device *dev) /* We need to ensure that no calls to smc_phy_configure are pending. - - flush_scheduled_work() cannot be called because we are - running with the netlink semaphore held (from - devinet_ioctl()) and the pending work queue contains - linkwatch_event() (scheduled by netif_carrier_off() - above). linkwatch_event() also wants the netlink semaphore. */ - while(lp->work_pending) - yield(); + cancel_work_sync(&lp->phy_configure); bmcr = smc_phy_read(dev, phy, MII_BMCR); smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); @@ -1161,7 +1154,6 @@ static void smc_phy_configure(struct work_struct *work) smc_phy_configure_exit: SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); - lp->work_pending = 0; } /* @@ -1389,11 +1381,8 @@ static void smc_timeout(struct net_device *dev) * smc_phy_configure() calls msleep() which calls schedule_timeout() * which calls schedule(). Hence we use a work queue. */ - if (lp->phy_type != 0) { - if (schedule_work(&lp->phy_configure)) { - lp->work_pending = 1; - } - } + if (lp->phy_type != 0) + schedule_work(&lp->phy_configure); /* We can accept TX packets again */ dev->trans_start = jiffies; diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 55670b5eb61..af8d2c436ef 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -731,7 +731,7 @@ static void tulip_down (struct net_device *dev) void __iomem *ioaddr = tp->base_addr; unsigned long flags; - flush_scheduled_work(); + cancel_work_sync(&tp->media_work); #ifdef CONFIG_TULIP_NAPI napi_disable(&tp->napi); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 0dcfc031026..7c66b052f55 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -706,7 +706,7 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) usb_kill_urb(kaweth->rx_urb); usb_kill_urb(kaweth->tx_urb); - flush_scheduled_work(); + cancel_delayed_work_sync(&kaweth->lowmem_work); /* a scheduled work may have resubmitted, we hit them again */ diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 20d387f6658..f7aec9309d0 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -682,7 +682,13 @@ static int prism2_close(struct net_device *dev) netif_device_detach(dev); } - flush_scheduled_work(); + cancel_work_sync(&local->reset_queue); + cancel_work_sync(&local->set_multicast_list_queue); + cancel_work_sync(&local->set_tim_queue); +#ifndef PRISM2_NO_STATION_MODES + cancel_work_sync(&local->info_queue); +#endif + cancel_work_sync(&local->comms_qual_update); module_put(local->hw_module); -- cgit v1.2.3-70-g09d2 From 24e3fcefb9cc61acce59ed54c00c4e4c32537de7 Mon Sep 17 00:00:00 2001 From: Eilon Greenstein Date: Thu, 12 Jun 2008 14:30:28 -0700 Subject: bnx2x: Updating the Maintainer I would like to thank Eliezer Tamir for writing and maintaining the driver for the past two years. I will take over maintaining the bnx2x driver from now on. Signed-off-by: Eilon Greenstein Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller --- MAINTAINERS | 4 ++-- drivers/net/bnx2x.c | 5 +++-- drivers/net/bnx2x.h | 3 ++- drivers/net/bnx2x_init.h | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/MAINTAINERS b/MAINTAINERS index 46fa1797707..7c8e561dbe1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -995,8 +995,8 @@ L: netdev@vger.kernel.org S: Supported BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER -P: Eliezer Tamir -M: eliezert@broadcom.com +P: Eilon Greenstein +M: eilong@broadcom.com L: netdev@vger.kernel.org S: Supported diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 7bdb5af3595..70cba64732c 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c @@ -6,7 +6,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Written by: Eliezer Tamir + * Maintained by: Eilon Greenstein + * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver * UDP CSUM errata workaround by Arik Gendelman * Slowpath rework by Vladislav Zolotarov @@ -74,7 +75,7 @@ static char version[] __devinitdata = "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -MODULE_AUTHOR("Eliezer Tamir "); +MODULE_AUTHOR("Eliezer Tamir"); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f0c0d31e7c..8e68d06510a 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -6,7 +6,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Written by: Eliezer Tamir + * Maintained by: Eilon Greenstein + * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver */ diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index dcaecc53bdb..370686eef97 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h @@ -6,7 +6,8 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Written by: Eliezer Tamir + * Maintained by: Eilon Greenstein + * Written by: Eliezer Tamir */ #ifndef BNX2X_INIT_H -- cgit v1.2.3-70-g09d2