diff options
58 files changed, 362 insertions, 216 deletions
diff --git a/Documentation/networking/s2io.txt b/Documentation/networking/s2io.txt index 4bde53e85f3f..1e28e2ddb90a 100644 --- a/Documentation/networking/s2io.txt +++ b/Documentation/networking/s2io.txt | |||
@@ -83,9 +83,9 @@ Valid range: Limited by memory on system | |||
83 | Default: 30 | 83 | Default: 30 |
84 | 84 | ||
85 | e. intr_type | 85 | e. intr_type |
86 | Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X) | 86 | Specifies interrupt type. Possible values 0(INTA), 2(MSI-X) |
87 | Valid range: 1-3 | 87 | Valid values: 0, 2 |
88 | Default: 1 | 88 | Default: 2 |
89 | 89 | ||
90 | 5. Performance suggestions | 90 | 5. Performance suggestions |
91 | General: | 91 | General: |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 85e2ba7fcfba..bf4830082a13 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/connector.h> | 28 | #include <linux/connector.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | ||
30 | 32 | ||
31 | #include <net/sock.h> | 33 | #include <net/sock.h> |
32 | 34 | ||
@@ -403,6 +405,40 @@ static void cn_callback(void *data) | |||
403 | mutex_unlock(¬ify_lock); | 405 | mutex_unlock(¬ify_lock); |
404 | } | 406 | } |
405 | 407 | ||
408 | static int cn_proc_show(struct seq_file *m, void *v) | ||
409 | { | ||
410 | struct cn_queue_dev *dev = cdev.cbdev; | ||
411 | struct cn_callback_entry *cbq; | ||
412 | |||
413 | seq_printf(m, "Name ID\n"); | ||
414 | |||
415 | spin_lock_bh(&dev->queue_lock); | ||
416 | |||
417 | list_for_each_entry(cbq, &dev->queue_list, callback_entry) { | ||
418 | seq_printf(m, "%-15s %u:%u\n", | ||
419 | cbq->id.name, | ||
420 | cbq->id.id.idx, | ||
421 | cbq->id.id.val); | ||
422 | } | ||
423 | |||
424 | spin_unlock_bh(&dev->queue_lock); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int cn_proc_open(struct inode *inode, struct file *file) | ||
430 | { | ||
431 | return single_open(file, cn_proc_show, NULL); | ||
432 | } | ||
433 | |||
434 | static const struct file_operations cn_file_ops = { | ||
435 | .owner = THIS_MODULE, | ||
436 | .open = cn_proc_open, | ||
437 | .read = seq_read, | ||
438 | .llseek = seq_lseek, | ||
439 | .release = single_release | ||
440 | }; | ||
441 | |||
406 | static int __devinit cn_init(void) | 442 | static int __devinit cn_init(void) |
407 | { | 443 | { |
408 | struct cn_dev *dev = &cdev; | 444 | struct cn_dev *dev = &cdev; |
@@ -434,6 +470,8 @@ static int __devinit cn_init(void) | |||
434 | return -EINVAL; | 470 | return -EINVAL; |
435 | } | 471 | } |
436 | 472 | ||
473 | proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops); | ||
474 | |||
437 | return 0; | 475 | return 0; |
438 | } | 476 | } |
439 | 477 | ||
@@ -443,6 +481,8 @@ static void __devexit cn_fini(void) | |||
443 | 481 | ||
444 | cn_already_initialized = 0; | 482 | cn_already_initialized = 0; |
445 | 483 | ||
484 | proc_net_remove(&init_net, "connector"); | ||
485 | |||
446 | cn_del_callback(&dev->id); | 486 | cn_del_callback(&dev->id); |
447 | cn_queue_free_dev(dev->cbdev); | 487 | cn_queue_free_dev(dev->cbdev); |
448 | netlink_kernel_release(dev->nls); | 488 | netlink_kernel_release(dev->nls); |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 2edda8cc7f99..aabad8ce7458 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1768,9 +1768,10 @@ vortex_timer(unsigned long data) | |||
1768 | case XCVR_MII: case XCVR_NWAY: | 1768 | case XCVR_MII: case XCVR_NWAY: |
1769 | { | 1769 | { |
1770 | ok = 1; | 1770 | ok = 1; |
1771 | spin_lock_bh(&vp->lock); | 1771 | /* Interrupts are already disabled */ |
1772 | spin_lock(&vp->lock); | ||
1772 | vortex_check_media(dev, 0); | 1773 | vortex_check_media(dev, 0); |
1773 | spin_unlock_bh(&vp->lock); | 1774 | spin_unlock(&vp->lock); |
1774 | } | 1775 | } |
1775 | break; | 1776 | break; |
1776 | default: /* Other media types handled by Tx timeouts. */ | 1777 | default: /* Other media types handled by Tx timeouts. */ |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f3cba5e24ec5..1037b1332312 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1803,6 +1803,8 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | |||
1803 | if (rx->prev->skb) { | 1803 | if (rx->prev->skb) { |
1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; | 1804 | struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; |
1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); | 1805 | put_unaligned_le32(rx->dma_addr, &prev_rfd->link); |
1806 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, | ||
1807 | sizeof(struct rfd), PCI_DMA_TODEVICE); | ||
1806 | } | 1808 | } |
1807 | 1809 | ||
1808 | return 0; | 1810 | return 0; |
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 701531e72e7b..a3f6a9c72ec8 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -347,7 +347,7 @@ e1000_set_tso(struct net_device *netdev, u32 data) | |||
347 | else | 347 | else |
348 | netdev->features &= ~NETIF_F_TSO; | 348 | netdev->features &= ~NETIF_F_TSO; |
349 | 349 | ||
350 | if (data) | 350 | if (data && (adapter->hw.mac_type > e1000_82547_rev_2)) |
351 | netdev->features |= NETIF_F_TSO6; | 351 | netdev->features |= NETIF_F_TSO6; |
352 | else | 352 | else |
353 | netdev->features &= ~NETIF_F_TSO6; | 353 | netdev->features &= ~NETIF_F_TSO6; |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index ccb8ca2cbb2b..0320925a42a8 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2535,7 +2535,8 @@ void e1000e_down(struct e1000_adapter *adapter) | |||
2535 | adapter->link_speed = 0; | 2535 | adapter->link_speed = 0; |
2536 | adapter->link_duplex = 0; | 2536 | adapter->link_duplex = 0; |
2537 | 2537 | ||
2538 | e1000e_reset(adapter); | 2538 | if (!pci_channel_offline(adapter->pdev)) |
2539 | e1000e_reset(adapter); | ||
2539 | e1000_clean_tx_ring(adapter); | 2540 | e1000_clean_tx_ring(adapter); |
2540 | e1000_clean_rx_ring(adapter); | 2541 | e1000_clean_rx_ring(adapter); |
2541 | 2542 | ||
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0b94833e23f7..e8cfadefa4b6 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -1077,8 +1077,6 @@ static inline void rx_off(struct scc_priv *priv) | |||
1077 | 1077 | ||
1078 | static void start_timer(struct scc_priv *priv, int t, int r15) | 1078 | static void start_timer(struct scc_priv *priv, int t, int r15) |
1079 | { | 1079 | { |
1080 | unsigned long flags; | ||
1081 | |||
1082 | outb(priv->tmr_mode, priv->tmr_ctrl); | 1080 | outb(priv->tmr_mode, priv->tmr_ctrl); |
1083 | if (t == 0) { | 1081 | if (t == 0) { |
1084 | tm_isr(priv); | 1082 | tm_isr(priv); |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 7b6b780dc8a6..6f1ad5368ae5 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -718,7 +718,8 @@ void igb_down(struct igb_adapter *adapter) | |||
718 | adapter->link_speed = 0; | 718 | adapter->link_speed = 0; |
719 | adapter->link_duplex = 0; | 719 | adapter->link_duplex = 0; |
720 | 720 | ||
721 | igb_reset(adapter); | 721 | if (!pci_channel_offline(adapter->pdev)) |
722 | igb_reset(adapter); | ||
722 | igb_clean_all_tx_rings(adapter); | 723 | igb_clean_all_tx_rings(adapter); |
723 | igb_clean_all_rx_rings(adapter); | 724 | igb_clean_all_rx_rings(adapter); |
724 | } | 725 | } |
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 679a0826780e..2c03f4e2ccc4 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
@@ -1271,7 +1271,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, | |||
1271 | 1271 | ||
1272 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; | 1272 | framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN; |
1273 | 1273 | ||
1274 | endframeLen = framelen - jumbo->current_size; | 1274 | endframelen = framelen - jumbo->current_size; |
1275 | /* | 1275 | /* |
1276 | if (framelen > IPG_RXFRAG_SIZE) | 1276 | if (framelen > IPG_RXFRAG_SIZE) |
1277 | framelen=IPG_RXFRAG_SIZE; | 1277 | framelen=IPG_RXFRAG_SIZE; |
@@ -1279,8 +1279,8 @@ static void ipg_nic_rx_with_end(struct net_device *dev, | |||
1279 | if (framelen > IPG_RXSUPPORT_SIZE) | 1279 | if (framelen > IPG_RXSUPPORT_SIZE) |
1280 | dev_kfree_skb_irq(jumbo->skb); | 1280 | dev_kfree_skb_irq(jumbo->skb); |
1281 | else { | 1281 | else { |
1282 | memcpy(skb_put(jumbo->skb, endframeLen), | 1282 | memcpy(skb_put(jumbo->skb, endframelen), |
1283 | skb->data, endframeLen); | 1283 | skb->data, endframelen); |
1284 | 1284 | ||
1285 | jumbo->skb->protocol = | 1285 | jumbo->skb->protocol = |
1286 | eth_type_trans(jumbo->skb, dev); | 1286 | eth_type_trans(jumbo->skb, dev); |
@@ -1352,16 +1352,16 @@ static int ipg_nic_rx(struct net_device *dev) | |||
1352 | 1352 | ||
1353 | switch (ipg_nic_rx_check_frame_type(dev)) { | 1353 | switch (ipg_nic_rx_check_frame_type(dev)) { |
1354 | case FRAME_WITH_START_WITH_END: | 1354 | case FRAME_WITH_START_WITH_END: |
1355 | ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry); | 1355 | ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry); |
1356 | break; | 1356 | break; |
1357 | case FRAME_WITH_START: | 1357 | case FRAME_WITH_START: |
1358 | ipg_nic_rx_with_start(dev, tp, rxfd, entry); | 1358 | ipg_nic_rx_with_start(dev, sp, rxfd, entry); |
1359 | break; | 1359 | break; |
1360 | case FRAME_WITH_END: | 1360 | case FRAME_WITH_END: |
1361 | ipg_nic_rx_with_end(dev, tp, rxfd, entry); | 1361 | ipg_nic_rx_with_end(dev, sp, rxfd, entry); |
1362 | break; | 1362 | break; |
1363 | case FRAME_NO_START_NO_END: | 1363 | case FRAME_NO_START_NO_END: |
1364 | ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry); | 1364 | ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry); |
1365 | break; | 1365 | break; |
1366 | } | 1366 | } |
1367 | } | 1367 | } |
@@ -1808,7 +1808,7 @@ static int ipg_nic_open(struct net_device *dev) | |||
1808 | /* initialize JUMBO Frame control variable */ | 1808 | /* initialize JUMBO Frame control variable */ |
1809 | sp->jumbo.found_start = 0; | 1809 | sp->jumbo.found_start = 0; |
1810 | sp->jumbo.current_size = 0; | 1810 | sp->jumbo.current_size = 0; |
1811 | sp->jumbo.skb = 0; | 1811 | sp->jumbo.skb = NULL; |
1812 | dev->mtu = IPG_TXFRAG_SIZE; | 1812 | dev->mtu = IPG_TXFRAG_SIZE; |
1813 | #endif | 1813 | #endif |
1814 | 1814 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0d37c9025be4..1674b6a5b903 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -1969,7 +1969,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) | |||
1969 | netif_carrier_off(netdev); | 1969 | netif_carrier_off(netdev); |
1970 | netif_stop_queue(netdev); | 1970 | netif_stop_queue(netdev); |
1971 | 1971 | ||
1972 | ixgbe_reset(adapter); | 1972 | if (!pci_channel_offline(adapter->pdev)) |
1973 | ixgbe_reset(adapter); | ||
1973 | ixgbe_clean_all_tx_rings(adapter); | 1974 | ixgbe_clean_all_tx_rings(adapter); |
1974 | ixgbe_clean_all_rx_rings(adapter); | 1975 | ixgbe_clean_all_rx_rings(adapter); |
1975 | 1976 | ||
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6797ed069f1f..63cd67b931e7 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -71,14 +71,18 @@ static irqreturn_t netxen_intr(int irq, void *data); | |||
71 | static irqreturn_t netxen_msi_intr(int irq, void *data); | 71 | static irqreturn_t netxen_msi_intr(int irq, void *data); |
72 | 72 | ||
73 | /* PCI Device ID Table */ | 73 | /* PCI Device ID Table */ |
74 | #define ENTRY(device) \ | ||
75 | {PCI_DEVICE(0x4040, (device)), \ | ||
76 | .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} | ||
77 | |||
74 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | 78 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { |
75 | {PCI_DEVICE(0x4040, 0x0001), PCI_DEVICE_CLASS(0x020000, ~0)}, | 79 | ENTRY(0x0001), |
76 | {PCI_DEVICE(0x4040, 0x0002), PCI_DEVICE_CLASS(0x020000, ~0)}, | 80 | ENTRY(0x0002), |
77 | {PCI_DEVICE(0x4040, 0x0003), PCI_DEVICE_CLASS(0x020000, ~0)}, | 81 | ENTRY(0x0003), |
78 | {PCI_DEVICE(0x4040, 0x0004), PCI_DEVICE_CLASS(0x020000, ~0)}, | 82 | ENTRY(0x0004), |
79 | {PCI_DEVICE(0x4040, 0x0005), PCI_DEVICE_CLASS(0x020000, ~0)}, | 83 | ENTRY(0x0005), |
80 | {PCI_DEVICE(0x4040, 0x0024), PCI_DEVICE_CLASS(0x020000, ~0)}, | 84 | ENTRY(0x0024), |
81 | {PCI_DEVICE(0x4040, 0x0025), PCI_DEVICE_CLASS(0x020000, ~0)}, | 85 | ENTRY(0x0025), |
82 | {0,} | 86 | {0,} |
83 | }; | 87 | }; |
84 | 88 | ||
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index d7018ff9e171..3f682d49a4e6 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -525,12 +525,14 @@ static int axnet_open(struct net_device *dev) | |||
525 | int ret; | 525 | int ret; |
526 | axnet_dev_t *info = PRIV(dev); | 526 | axnet_dev_t *info = PRIV(dev); |
527 | struct pcmcia_device *link = info->p_dev; | 527 | struct pcmcia_device *link = info->p_dev; |
528 | unsigned int nic_base = dev->base_addr; | ||
528 | 529 | ||
529 | DEBUG(2, "axnet_open('%s')\n", dev->name); | 530 | DEBUG(2, "axnet_open('%s')\n", dev->name); |
530 | 531 | ||
531 | if (!pcmcia_dev_present(link)) | 532 | if (!pcmcia_dev_present(link)) |
532 | return -ENODEV; | 533 | return -ENODEV; |
533 | 534 | ||
535 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
534 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); | 536 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); |
535 | if (ret) | 537 | if (ret) |
536 | return ret; | 538 | return ret; |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index fd8158a86f64..2d4c4ad89b8d 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -969,6 +969,7 @@ static int pcnet_open(struct net_device *dev) | |||
969 | int ret; | 969 | int ret; |
970 | pcnet_dev_t *info = PRIV(dev); | 970 | pcnet_dev_t *info = PRIV(dev); |
971 | struct pcmcia_device *link = info->p_dev; | 971 | struct pcmcia_device *link = info->p_dev; |
972 | unsigned int nic_base = dev->base_addr; | ||
972 | 973 | ||
973 | DEBUG(2, "pcnet_open('%s')\n", dev->name); | 974 | DEBUG(2, "pcnet_open('%s')\n", dev->name); |
974 | 975 | ||
@@ -976,6 +977,8 @@ static int pcnet_open(struct net_device *dev) | |||
976 | return -ENODEV; | 977 | return -ENODEV; |
977 | 978 | ||
978 | set_misc_reg(dev); | 979 | set_misc_reg(dev); |
980 | |||
981 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
979 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); | 982 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); |
980 | if (ret) | 983 | if (ret) |
981 | return ret; | 984 | return ret; |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index bafb69b6f7cb..fc6f4b8c64b3 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -942,7 +942,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
942 | m->msg_namelen = 0; | 942 | m->msg_namelen = 0; |
943 | 943 | ||
944 | if (skb) { | 944 | if (skb) { |
945 | total_len = min(total_len, skb->len); | 945 | total_len = min_t(size_t, total_len, skb->len); |
946 | error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); | 946 | error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); |
947 | if (error == 0) | 947 | if (error == 0) |
948 | error = total_len; | 948 | error = total_len; |
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 5f608780c3e8..e7d48a352beb 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c | |||
@@ -3701,7 +3701,9 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) | |||
3701 | printk(KERN_ERR PFX | 3701 | printk(KERN_ERR PFX |
3702 | "%s: Driver up/down cycle failed, " | 3702 | "%s: Driver up/down cycle failed, " |
3703 | "closing device\n",qdev->ndev->name); | 3703 | "closing device\n",qdev->ndev->name); |
3704 | rtnl_lock(); | ||
3704 | dev_close(qdev->ndev); | 3705 | dev_close(qdev->ndev); |
3706 | rtnl_unlock(); | ||
3705 | return -1; | 3707 | return -1; |
3706 | } | 3708 | } |
3707 | return 0; | 3709 | return 0; |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 858b191517b3..504a48ff73c8 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -273,7 +273,7 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | |||
273 | dma_addr_t mapping = desc_dma; | 273 | dma_addr_t mapping = desc_dma; |
274 | 274 | ||
275 | while (size-- > 0) { | 275 | while (size-- > 0) { |
276 | mapping += sizeof(sizeof(*desc)); | 276 | mapping += sizeof(*desc); |
277 | desc->ndesc = cpu_to_le32(mapping); | 277 | desc->ndesc = cpu_to_le32(mapping); |
278 | desc->vndescp = desc + 1; | 278 | desc->vndescp = desc + 1; |
279 | desc++; | 279 | desc++; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 5694e894fc7a..e7a3dbec674c 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -2625,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2625 | rxdp1->Buffer0_ptr = pci_map_single | 2625 | rxdp1->Buffer0_ptr = pci_map_single |
2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, | 2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, |
2627 | PCI_DMA_FROMDEVICE); | 2627 | PCI_DMA_FROMDEVICE); |
2628 | if( (rxdp1->Buffer0_ptr == 0) || | 2628 | if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
2629 | (rxdp1->Buffer0_ptr == | ||
2630 | DMA_ERROR_CODE)) | ||
2631 | goto pci_map_failed; | 2629 | goto pci_map_failed; |
2632 | 2630 | ||
2633 | rxdp->Control_2 = | 2631 | rxdp->Control_2 = |
@@ -2657,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2657 | skb->data = (void *) (unsigned long)tmp; | 2655 | skb->data = (void *) (unsigned long)tmp; |
2658 | skb_reset_tail_pointer(skb); | 2656 | skb_reset_tail_pointer(skb); |
2659 | 2657 | ||
2658 | /* AK: check is wrong. 0 can be valid dma address */ | ||
2660 | if (!(rxdp3->Buffer0_ptr)) | 2659 | if (!(rxdp3->Buffer0_ptr)) |
2661 | rxdp3->Buffer0_ptr = | 2660 | rxdp3->Buffer0_ptr = |
2662 | pci_map_single(ring->pdev, ba->ba_0, | 2661 | pci_map_single(ring->pdev, ba->ba_0, |
@@ -2665,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2665 | pci_dma_sync_single_for_device(ring->pdev, | 2664 | pci_dma_sync_single_for_device(ring->pdev, |
2666 | (dma_addr_t) rxdp3->Buffer0_ptr, | 2665 | (dma_addr_t) rxdp3->Buffer0_ptr, |
2667 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2666 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2668 | if( (rxdp3->Buffer0_ptr == 0) || | 2667 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) |
2669 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) | ||
2670 | goto pci_map_failed; | 2668 | goto pci_map_failed; |
2671 | 2669 | ||
2672 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2670 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
@@ -2681,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2681 | (ring->pdev, skb->data, ring->mtu + 4, | 2679 | (ring->pdev, skb->data, ring->mtu + 4, |
2682 | PCI_DMA_FROMDEVICE); | 2680 | PCI_DMA_FROMDEVICE); |
2683 | 2681 | ||
2684 | if( (rxdp3->Buffer2_ptr == 0) || | 2682 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
2685 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) | ||
2686 | goto pci_map_failed; | 2683 | goto pci_map_failed; |
2687 | 2684 | ||
2685 | /* AK: check is wrong */ | ||
2688 | if (!rxdp3->Buffer1_ptr) | 2686 | if (!rxdp3->Buffer1_ptr) |
2689 | rxdp3->Buffer1_ptr = | 2687 | rxdp3->Buffer1_ptr = |
2690 | pci_map_single(ring->pdev, | 2688 | pci_map_single(ring->pdev, |
2691 | ba->ba_1, BUF1_LEN, | 2689 | ba->ba_1, BUF1_LEN, |
2692 | PCI_DMA_FROMDEVICE); | 2690 | PCI_DMA_FROMDEVICE); |
2693 | 2691 | ||
2694 | if( (rxdp3->Buffer1_ptr == 0) || | 2692 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
2695 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
2696 | pci_unmap_single | 2693 | pci_unmap_single |
2697 | (ring->pdev, | 2694 | (ring->pdev, |
2698 | (dma_addr_t)(unsigned long) | 2695 | (dma_addr_t)(unsigned long) |
@@ -4264,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4264 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4261 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
4265 | fifo->ufo_in_band_v, | 4262 | fifo->ufo_in_band_v, |
4266 | sizeof(u64), PCI_DMA_TODEVICE); | 4263 | sizeof(u64), PCI_DMA_TODEVICE); |
4267 | if((txdp->Buffer_Pointer == 0) || | 4264 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4268 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4269 | goto pci_map_failed; | 4265 | goto pci_map_failed; |
4270 | txdp++; | 4266 | txdp++; |
4271 | } | 4267 | } |
4272 | 4268 | ||
4273 | txdp->Buffer_Pointer = pci_map_single | 4269 | txdp->Buffer_Pointer = pci_map_single |
4274 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 4270 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
4275 | if((txdp->Buffer_Pointer == 0) || | 4271 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4276 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4277 | goto pci_map_failed; | 4272 | goto pci_map_failed; |
4278 | 4273 | ||
4279 | txdp->Host_Control = (unsigned long) skb; | 4274 | txdp->Host_Control = (unsigned long) skb; |
@@ -6884,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6884 | pci_map_single( sp->pdev, (*skb)->data, | 6879 | pci_map_single( sp->pdev, (*skb)->data, |
6885 | size - NET_IP_ALIGN, | 6880 | size - NET_IP_ALIGN, |
6886 | PCI_DMA_FROMDEVICE); | 6881 | PCI_DMA_FROMDEVICE); |
6887 | if( (rxdp1->Buffer0_ptr == 0) || | 6882 | if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
6888 | (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6889 | goto memalloc_failed; | 6883 | goto memalloc_failed; |
6890 | } | ||
6891 | rxdp->Host_Control = (unsigned long) (*skb); | 6884 | rxdp->Host_Control = (unsigned long) (*skb); |
6892 | } | 6885 | } |
6893 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { | 6886 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { |
@@ -6913,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6913 | pci_map_single(sp->pdev, (*skb)->data, | 6906 | pci_map_single(sp->pdev, (*skb)->data, |
6914 | dev->mtu + 4, | 6907 | dev->mtu + 4, |
6915 | PCI_DMA_FROMDEVICE); | 6908 | PCI_DMA_FROMDEVICE); |
6916 | if( (rxdp3->Buffer2_ptr == 0) || | 6909 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
6917 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { | ||
6918 | goto memalloc_failed; | 6910 | goto memalloc_failed; |
6919 | } | ||
6920 | rxdp3->Buffer0_ptr = *temp0 = | 6911 | rxdp3->Buffer0_ptr = *temp0 = |
6921 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, | 6912 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, |
6922 | PCI_DMA_FROMDEVICE); | 6913 | PCI_DMA_FROMDEVICE); |
6923 | if( (rxdp3->Buffer0_ptr == 0) || | 6914 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { |
6924 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6925 | pci_unmap_single (sp->pdev, | 6915 | pci_unmap_single (sp->pdev, |
6926 | (dma_addr_t)rxdp3->Buffer2_ptr, | 6916 | (dma_addr_t)rxdp3->Buffer2_ptr, |
6927 | dev->mtu + 4, PCI_DMA_FROMDEVICE); | 6917 | dev->mtu + 4, PCI_DMA_FROMDEVICE); |
@@ -6933,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6933 | rxdp3->Buffer1_ptr = *temp1 = | 6923 | rxdp3->Buffer1_ptr = *temp1 = |
6934 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, | 6924 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, |
6935 | PCI_DMA_FROMDEVICE); | 6925 | PCI_DMA_FROMDEVICE); |
6936 | if( (rxdp3->Buffer1_ptr == 0) || | 6926 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
6937 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
6938 | pci_unmap_single (sp->pdev, | 6927 | pci_unmap_single (sp->pdev, |
6939 | (dma_addr_t)rxdp3->Buffer0_ptr, | 6928 | (dma_addr_t)rxdp3->Buffer0_ptr, |
6940 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 6929 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index d0a84ba887a5..483b17c34ae8 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -75,10 +75,6 @@ static int debug_level = ERR_DBG; | |||
75 | /* DEBUG message print. */ | 75 | /* DEBUG message print. */ |
76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) | 76 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) |
77 | 77 | ||
78 | #ifndef DMA_ERROR_CODE | ||
79 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
80 | #endif | ||
81 | |||
82 | /* Protocol assist features of the NIC */ | 78 | /* Protocol assist features of the NIC */ |
83 | #define L3_CKSUM_OK 0xFFFF | 79 | #define L3_CKSUM_OK 0xFFFF |
84 | #define L4_CKSUM_OK 0xFFFF | 80 | #define L4_CKSUM_OK 0xFFFF |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 10e4e85da3fc..b07b8cbadeaf 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -1394,6 +1394,7 @@ tc35815_open(struct net_device *dev) | |||
1394 | tc35815_chip_init(dev); | 1394 | tc35815_chip_init(dev); |
1395 | spin_unlock_irq(&lp->lock); | 1395 | spin_unlock_irq(&lp->lock); |
1396 | 1396 | ||
1397 | netif_carrier_off(dev); | ||
1397 | /* schedule a link state check */ | 1398 | /* schedule a link state check */ |
1398 | phy_start(lp->phy_dev); | 1399 | phy_start(lp->phy_dev); |
1399 | 1400 | ||
@@ -1735,7 +1736,6 @@ tc35815_rx(struct net_device *dev) | |||
1735 | skb = lp->rx_skbs[cur_bd].skb; | 1736 | skb = lp->rx_skbs[cur_bd].skb; |
1736 | prefetch(skb->data); | 1737 | prefetch(skb->data); |
1737 | lp->rx_skbs[cur_bd].skb = NULL; | 1738 | lp->rx_skbs[cur_bd].skb = NULL; |
1738 | lp->fbl_count--; | ||
1739 | pci_unmap_single(lp->pci_dev, | 1739 | pci_unmap_single(lp->pci_dev, |
1740 | lp->rx_skbs[cur_bd].skb_dma, | 1740 | lp->rx_skbs[cur_bd].skb_dma, |
1741 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 1741 | RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
@@ -1791,6 +1791,7 @@ tc35815_rx(struct net_device *dev) | |||
1791 | #ifdef TC35815_USE_PACKEDBUFFER | 1791 | #ifdef TC35815_USE_PACKEDBUFFER |
1792 | while (lp->fbl_curid != id) | 1792 | while (lp->fbl_curid != id) |
1793 | #else | 1793 | #else |
1794 | lp->fbl_count--; | ||
1794 | while (lp->fbl_count < RX_BUF_NUM) | 1795 | while (lp->fbl_count < RX_BUF_NUM) |
1795 | #endif | 1796 | #endif |
1796 | { | 1797 | { |
@@ -2453,6 +2454,7 @@ static int tc35815_resume(struct pci_dev *pdev) | |||
2453 | return 0; | 2454 | return 0; |
2454 | pci_set_power_state(pdev, PCI_D0); | 2455 | pci_set_power_state(pdev, PCI_D0); |
2455 | tc35815_restart(dev); | 2456 | tc35815_restart(dev); |
2457 | netif_carrier_off(dev); | ||
2456 | if (lp->phy_dev) | 2458 | if (lp->phy_dev) |
2457 | phy_start(lp->phy_dev); | 2459 | phy_start(lp->phy_dev); |
2458 | netif_device_attach(dev); | 2460 | netif_device_attach(dev); |
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 249e18053d5f..069f8bb0a99f 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/x25.h> | 32 | #include <linux/x25.h> |
33 | #include <linux/lapb.h> | 33 | #include <linux/lapb.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/rtnetlink.h> | ||
35 | #include "x25_asy.h" | 36 | #include "x25_asy.h" |
36 | 37 | ||
37 | #include <net/x25device.h> | 38 | #include <net/x25device.h> |
@@ -601,8 +602,10 @@ static void x25_asy_close_tty(struct tty_struct *tty) | |||
601 | if (!sl || sl->magic != X25_ASY_MAGIC) | 602 | if (!sl || sl->magic != X25_ASY_MAGIC) |
602 | return; | 603 | return; |
603 | 604 | ||
605 | rtnl_lock(); | ||
604 | if (sl->dev->flags & IFF_UP) | 606 | if (sl->dev->flags & IFF_UP) |
605 | dev_close(sl->dev); | 607 | dev_close(sl->dev); |
608 | rtnl_unlock(); | ||
606 | 609 | ||
607 | tty->disc_data = NULL; | 610 | tty->disc_data = NULL; |
608 | sl->tty = NULL; | 611 | sl->tty = NULL; |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 36a9c42df835..76f4c7bad8b8 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -72,6 +72,9 @@ static void b43_led_brightness_set(struct led_classdev *led_dev, | |||
72 | struct b43_wldev *dev = led->dev; | 72 | struct b43_wldev *dev = led->dev; |
73 | bool radio_enabled; | 73 | bool radio_enabled; |
74 | 74 | ||
75 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) | ||
76 | return; | ||
77 | |||
75 | /* Checking the radio-enabled status here is slightly racy, | 78 | /* Checking the radio-enabled status here is slightly racy, |
76 | * but we want to avoid the locking overhead and we don't care | 79 | * but we want to avoid the locking overhead and we don't care |
77 | * whether the LED has the wrong state for a second. */ | 80 | * whether the LED has the wrong state for a second. */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7bca8e981512..704dd3551fff 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2976,12 +2976,11 @@ static int b43_op_tx(struct ieee80211_hw *hw, | |||
2976 | 2976 | ||
2977 | if (unlikely(skb->len < 2 + 2 + 6)) { | 2977 | if (unlikely(skb->len < 2 + 2 + 6)) { |
2978 | /* Too short, this can't be a valid frame. */ | 2978 | /* Too short, this can't be a valid frame. */ |
2979 | dev_kfree_skb_any(skb); | 2979 | goto drop_packet; |
2980 | return NETDEV_TX_OK; | ||
2981 | } | 2980 | } |
2982 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | 2981 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
2983 | if (unlikely(!dev)) | 2982 | if (unlikely(!dev)) |
2984 | return NETDEV_TX_BUSY; | 2983 | goto drop_packet; |
2985 | 2984 | ||
2986 | /* Transmissions on seperate queues can run concurrently. */ | 2985 | /* Transmissions on seperate queues can run concurrently. */ |
2987 | read_lock_irqsave(&wl->tx_lock, flags); | 2986 | read_lock_irqsave(&wl->tx_lock, flags); |
@@ -2997,7 +2996,12 @@ static int b43_op_tx(struct ieee80211_hw *hw, | |||
2997 | read_unlock_irqrestore(&wl->tx_lock, flags); | 2996 | read_unlock_irqrestore(&wl->tx_lock, flags); |
2998 | 2997 | ||
2999 | if (unlikely(err)) | 2998 | if (unlikely(err)) |
3000 | return NETDEV_TX_BUSY; | 2999 | goto drop_packet; |
3000 | return NETDEV_TX_OK; | ||
3001 | |||
3002 | drop_packet: | ||
3003 | /* We can not transmit this packet. Drop it. */ | ||
3004 | dev_kfree_skb_any(skb); | ||
3001 | return NETDEV_TX_OK; | 3005 | return NETDEV_TX_OK; |
3002 | } | 3006 | } |
3003 | 3007 | ||
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 33cc256c5baf..203b0f42ac58 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -876,6 +876,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
876 | if (!ring) | 876 | if (!ring) |
877 | goto out; | 877 | goto out; |
878 | ring->type = type; | 878 | ring->type = type; |
879 | ring->dev = dev; | ||
879 | 880 | ||
880 | nr_slots = B43legacy_RXRING_SLOTS; | 881 | nr_slots = B43legacy_RXRING_SLOTS; |
881 | if (for_tx) | 882 | if (for_tx) |
@@ -922,7 +923,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
922 | DMA_TO_DEVICE); | 923 | DMA_TO_DEVICE); |
923 | } | 924 | } |
924 | 925 | ||
925 | ring->dev = dev; | ||
926 | ring->nr_slots = nr_slots; | 926 | ring->nr_slots = nr_slots; |
927 | ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); | 927 | ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); |
928 | ring->index = controller_index; | 928 | ring->index = controller_index; |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 5f533b93ad5d..069157eea05c 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2377,8 +2377,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw, | |||
2377 | } else | 2377 | } else |
2378 | err = b43legacy_dma_tx(dev, skb); | 2378 | err = b43legacy_dma_tx(dev, skb); |
2379 | out: | 2379 | out: |
2380 | if (unlikely(err)) | 2380 | if (unlikely(err)) { |
2381 | return NETDEV_TX_BUSY; | 2381 | /* Drop the packet. */ |
2382 | dev_kfree_skb_any(skb); | ||
2383 | } | ||
2382 | return NETDEV_TX_OK; | 2384 | return NETDEV_TX_OK; |
2383 | } | 2385 | } |
2384 | 2386 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 5ca181f7125d..5b420b43af5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -276,13 +276,18 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
276 | cancel_delayed_work(&priv->scan_check); | 276 | cancel_delayed_work(&priv->scan_check); |
277 | 277 | ||
278 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 278 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
279 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 279 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
280 | "2.4" : "5.2", | ||
280 | jiffies_to_msecs(elapsed_jiffies | 281 | jiffies_to_msecs(elapsed_jiffies |
281 | (priv->scan_pass_start, jiffies))); | 282 | (priv->scan_pass_start, jiffies))); |
282 | 283 | ||
283 | /* Remove this scanned band from the list | 284 | /* Remove this scanned band from the list of pending |
284 | * of pending bands to scan */ | 285 | * bands to scan, band G precedes A in order of scanning |
285 | priv->scan_bands--; | 286 | * as seen in iwl_bg_request_scan */ |
287 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
288 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
289 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
290 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
286 | 291 | ||
287 | /* If a request to abort was given, or the scan did not succeed | 292 | /* If a request to abort was given, or the scan did not succeed |
288 | * then we reset the scan state machine and terminate, | 293 | * then we reset the scan state machine and terminate, |
@@ -292,7 +297,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | |||
292 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 297 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
293 | } else { | 298 | } else { |
294 | /* If there are more bands on this scan pass reschedule */ | 299 | /* If there are more bands on this scan pass reschedule */ |
295 | if (priv->scan_bands > 0) | 300 | if (priv->scan_bands) |
296 | goto reschedule; | 301 | goto reschedule; |
297 | } | 302 | } |
298 | 303 | ||
@@ -389,7 +394,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
389 | 394 | ||
390 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); | 395 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); |
391 | if (!is_channel_valid(ch_info)) { | 396 | if (!is_channel_valid(ch_info)) { |
392 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 397 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
393 | scan_ch->channel); | 398 | scan_ch->channel); |
394 | continue; | 399 | continue; |
395 | } | 400 | } |
@@ -465,7 +470,10 @@ int iwl_scan_initiate(struct iwl_priv *priv) | |||
465 | } | 470 | } |
466 | 471 | ||
467 | IWL_DEBUG_INFO("Starting scan...\n"); | 472 | IWL_DEBUG_INFO("Starting scan...\n"); |
468 | priv->scan_bands = 2; | 473 | if (priv->cfg->sku & IWL_SKU_G) |
474 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
475 | if (priv->cfg->sku & IWL_SKU_A) | ||
476 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
469 | set_bit(STATUS_SCANNING, &priv->status); | 477 | set_bit(STATUS_SCANNING, &priv->status); |
470 | priv->scan_start = jiffies; | 478 | priv->scan_start = jiffies; |
471 | priv->scan_pass_start = priv->scan_start; | 479 | priv->scan_pass_start = priv->scan_start; |
@@ -803,8 +811,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
803 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 811 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
804 | 812 | ||
805 | 813 | ||
806 | switch (priv->scan_bands) { | 814 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
807 | case 2: | ||
808 | band = IEEE80211_BAND_2GHZ; | 815 | band = IEEE80211_BAND_2GHZ; |
809 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 816 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
810 | tx_ant = iwl_scan_tx_ant(priv, band); | 817 | tx_ant = iwl_scan_tx_ant(priv, band); |
@@ -818,9 +825,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
818 | tx_ant | | 825 | tx_ant | |
819 | RATE_MCS_CCK_MSK); | 826 | RATE_MCS_CCK_MSK); |
820 | scan->good_CRC_th = 0; | 827 | scan->good_CRC_th = 0; |
821 | break; | 828 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
822 | |||
823 | case 1: | ||
824 | band = IEEE80211_BAND_5GHZ; | 829 | band = IEEE80211_BAND_5GHZ; |
825 | tx_ant = iwl_scan_tx_ant(priv, band); | 830 | tx_ant = iwl_scan_tx_ant(priv, band); |
826 | scan->tx_cmd.rate_n_flags = | 831 | scan->tx_cmd.rate_n_flags = |
@@ -833,9 +838,7 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
833 | * MIMO is not used here, but value is required */ | 838 | * MIMO is not used here, but value is required */ |
834 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) | 839 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) |
835 | rx_chain = 0x6; | 840 | rx_chain = 0x6; |
836 | 841 | } else { | |
837 | break; | ||
838 | default: | ||
839 | IWL_WARNING("Invalid scan band count\n"); | 842 | IWL_WARNING("Invalid scan band count\n"); |
840 | goto done; | 843 | goto done; |
841 | } | 844 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 47cf4b997f50..92d1b2e312d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2217,7 +2217,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | |||
2217 | } | 2217 | } |
2218 | 2218 | ||
2219 | IWL_DEBUG_INFO("Starting scan...\n"); | 2219 | IWL_DEBUG_INFO("Starting scan...\n"); |
2220 | priv->scan_bands = 2; | 2220 | if (priv->cfg->sku & IWL_SKU_G) |
2221 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
2222 | if (priv->cfg->sku & IWL_SKU_A) | ||
2223 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
2221 | set_bit(STATUS_SCANNING, &priv->status); | 2224 | set_bit(STATUS_SCANNING, &priv->status); |
2222 | priv->scan_start = jiffies; | 2225 | priv->scan_start = jiffies; |
2223 | priv->scan_pass_start = priv->scan_start; | 2226 | priv->scan_pass_start = priv->scan_start; |
@@ -3342,13 +3345,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, | |||
3342 | cancel_delayed_work(&priv->scan_check); | 3345 | cancel_delayed_work(&priv->scan_check); |
3343 | 3346 | ||
3344 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 3347 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
3345 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 3348 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
3349 | "2.4" : "5.2", | ||
3346 | jiffies_to_msecs(elapsed_jiffies | 3350 | jiffies_to_msecs(elapsed_jiffies |
3347 | (priv->scan_pass_start, jiffies))); | 3351 | (priv->scan_pass_start, jiffies))); |
3348 | 3352 | ||
3349 | /* Remove this scanned band from the list | 3353 | /* Remove this scanned band from the list of pending |
3350 | * of pending bands to scan */ | 3354 | * bands to scan, band G precedes A in order of scanning |
3351 | priv->scan_bands--; | 3355 | * as seen in iwl3945_bg_request_scan */ |
3356 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3357 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3358 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3359 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3352 | 3360 | ||
3353 | /* If a request to abort was given, or the scan did not succeed | 3361 | /* If a request to abort was given, or the scan did not succeed |
3354 | * then we reset the scan state machine and terminate, | 3362 | * then we reset the scan state machine and terminate, |
@@ -4961,7 +4969,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4961 | 4969 | ||
4962 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); | 4970 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
4963 | if (!is_channel_valid(ch_info)) { | 4971 | if (!is_channel_valid(ch_info)) { |
4964 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4972 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4965 | scan_ch->channel); | 4973 | scan_ch->channel); |
4966 | continue; | 4974 | continue; |
4967 | } | 4975 | } |
@@ -6316,21 +6324,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6316 | 6324 | ||
6317 | /* flags + rate selection */ | 6325 | /* flags + rate selection */ |
6318 | 6326 | ||
6319 | switch (priv->scan_bands) { | 6327 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
6320 | case 2: | ||
6321 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6328 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6322 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6329 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6323 | scan->good_CRC_th = 0; | 6330 | scan->good_CRC_th = 0; |
6324 | band = IEEE80211_BAND_2GHZ; | 6331 | band = IEEE80211_BAND_2GHZ; |
6325 | break; | 6332 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
6326 | |||
6327 | case 1: | ||
6328 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6333 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6329 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6334 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6330 | band = IEEE80211_BAND_5GHZ; | 6335 | band = IEEE80211_BAND_5GHZ; |
6331 | break; | 6336 | } else { |
6332 | |||
6333 | default: | ||
6334 | IWL_WARNING("Invalid scan band count\n"); | 6337 | IWL_WARNING("Invalid scan band count\n"); |
6335 | goto done; | 6338 | goto done; |
6336 | } | 6339 | } |
@@ -6770,7 +6773,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6770 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, | 6773 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
6771 | conf->channel->hw_value); | 6774 | conf->channel->hw_value); |
6772 | if (!is_channel_valid(ch_info)) { | 6775 | if (!is_channel_valid(ch_info)) { |
6773 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 6776 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n", |
6774 | conf->channel->hw_value, conf->channel->band); | 6777 | conf->channel->hw_value, conf->channel->band); |
6775 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 6778 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
6776 | spin_unlock_irqrestore(&priv->lock, flags); | 6779 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 762e85bef55d..e43bae97ed8f 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb) | |||
290 | 290 | ||
291 | avs->version = cpu_to_be32(P80211CAPTURE_VERSION); | 291 | avs->version = cpu_to_be32(P80211CAPTURE_VERSION); |
292 | avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); | 292 | avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); |
293 | avs->mactime = cpu_to_be64(le64_to_cpu(clock)); | 293 | avs->mactime = cpu_to_be64(clock); |
294 | avs->hosttime = cpu_to_be64(jiffies); | 294 | avs->hosttime = cpu_to_be64(jiffies); |
295 | avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ | 295 | avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ |
296 | avs->channel = cpu_to_be32(channel_of_freq(freq)); | 296 | avs->channel = cpu_to_be32(channel_of_freq(freq)); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9851cefaabf3..0462d6d35b8a 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
138 | * Wait until the BBP becomes ready. | 138 | * Wait until the BBP becomes ready. |
139 | */ | 139 | */ |
140 | reg = rt2500usb_bbp_check(rt2x00dev); | 140 | reg = rt2500usb_bbp_check(rt2x00dev); |
141 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 141 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
142 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | 142 | goto exit_fail; |
143 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
144 | return; | ||
145 | } | ||
146 | 143 | ||
147 | /* | 144 | /* |
148 | * Write the data into the BBP. | 145 | * Write the data into the BBP. |
@@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
155 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); | 152 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
156 | 153 | ||
157 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 154 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
155 | |||
156 | return; | ||
157 | |||
158 | exit_fail: | ||
159 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
160 | |||
161 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | ||
158 | } | 162 | } |
159 | 163 | ||
160 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 164 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
168 | * Wait until the BBP becomes ready. | 172 | * Wait until the BBP becomes ready. |
169 | */ | 173 | */ |
170 | reg = rt2500usb_bbp_check(rt2x00dev); | 174 | reg = rt2500usb_bbp_check(rt2x00dev); |
171 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 175 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
172 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | 176 | goto exit_fail; |
173 | return; | ||
174 | } | ||
175 | 177 | ||
176 | /* | 178 | /* |
177 | * Write the request into the BBP. | 179 | * Write the request into the BBP. |
@@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
186 | * Wait until the BBP becomes ready. | 188 | * Wait until the BBP becomes ready. |
187 | */ | 189 | */ |
188 | reg = rt2500usb_bbp_check(rt2x00dev); | 190 | reg = rt2500usb_bbp_check(rt2x00dev); |
189 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { | 191 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) |
190 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | 192 | goto exit_fail; |
191 | *value = 0xff; | ||
192 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
193 | return; | ||
194 | } | ||
195 | 193 | ||
196 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); | 194 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
197 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); | 195 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); |
198 | 196 | ||
199 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 197 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
198 | |||
199 | return; | ||
200 | |||
201 | exit_fail: | ||
202 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
203 | |||
204 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | ||
205 | *value = 0xff; | ||
200 | } | 206 | } |
201 | 207 | ||
202 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | 208 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 0da8f972a1b2..52d8e9688219 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -818,6 +818,7 @@ struct rt2x00_dev { | |||
818 | /* | 818 | /* |
819 | * Scheduled work. | 819 | * Scheduled work. |
820 | */ | 820 | */ |
821 | struct workqueue_struct *workqueue; | ||
821 | struct work_struct intf_work; | 822 | struct work_struct intf_work; |
822 | struct work_struct filter_work; | 823 | struct work_struct filter_work; |
823 | 824 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9ea677320daa..cc4fee105ed6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -74,7 +74,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
74 | 74 | ||
75 | rt2x00lib_reset_link_tuner(rt2x00dev); | 75 | rt2x00lib_reset_link_tuner(rt2x00dev); |
76 | 76 | ||
77 | queue_delayed_work(rt2x00dev->hw->workqueue, | 77 | queue_delayed_work(rt2x00dev->workqueue, |
78 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | 78 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
79 | } | 79 | } |
80 | 80 | ||
@@ -138,14 +138,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
138 | return; | 138 | return; |
139 | 139 | ||
140 | /* | 140 | /* |
141 | * Stop all scheduled work. | ||
142 | */ | ||
143 | if (work_pending(&rt2x00dev->intf_work)) | ||
144 | cancel_work_sync(&rt2x00dev->intf_work); | ||
145 | if (work_pending(&rt2x00dev->filter_work)) | ||
146 | cancel_work_sync(&rt2x00dev->filter_work); | ||
147 | |||
148 | /* | ||
149 | * Stop the TX queues. | 141 | * Stop the TX queues. |
150 | */ | 142 | */ |
151 | ieee80211_stop_queues(rt2x00dev->hw); | 143 | ieee80211_stop_queues(rt2x00dev->hw); |
@@ -400,8 +392,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
400 | * Increase tuner counter, and reschedule the next link tuner run. | 392 | * Increase tuner counter, and reschedule the next link tuner run. |
401 | */ | 393 | */ |
402 | rt2x00dev->link.count++; | 394 | rt2x00dev->link.count++; |
403 | queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, | 395 | queue_delayed_work(rt2x00dev->workqueue, |
404 | LINK_TUNE_INTERVAL); | 396 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
405 | } | 397 | } |
406 | 398 | ||
407 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | 399 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) |
@@ -434,6 +426,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
434 | 426 | ||
435 | spin_unlock(&intf->lock); | 427 | spin_unlock(&intf->lock); |
436 | 428 | ||
429 | /* | ||
430 | * It is possible the radio was disabled while the work had been | ||
431 | * scheduled. If that happens we should return here immediately, | ||
432 | * note that in the spinlock protected area above the delayed_flags | ||
433 | * have been cleared correctly. | ||
434 | */ | ||
435 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
436 | return; | ||
437 | |||
437 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 438 | if (delayed_flags & DELAYED_UPDATE_BEACON) { |
438 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif); | 439 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif); |
439 | if (skb && | 440 | if (skb && |
@@ -442,7 +443,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
442 | } | 443 | } |
443 | 444 | ||
444 | if (delayed_flags & DELAYED_CONFIG_ERP) | 445 | if (delayed_flags & DELAYED_CONFIG_ERP) |
445 | rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); | 446 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
446 | 447 | ||
447 | if (delayed_flags & DELAYED_LED_ASSOC) | 448 | if (delayed_flags & DELAYED_LED_ASSOC) |
448 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); | 449 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); |
@@ -488,7 +489,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
488 | rt2x00lib_beacondone_iter, | 489 | rt2x00lib_beacondone_iter, |
489 | rt2x00dev); | 490 | rt2x00dev); |
490 | 491 | ||
491 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 492 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
492 | } | 493 | } |
493 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 494 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
494 | 495 | ||
@@ -1003,6 +1004,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1003 | /* | 1004 | /* |
1004 | * Initialize configuration work. | 1005 | * Initialize configuration work. |
1005 | */ | 1006 | */ |
1007 | rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib"); | ||
1008 | if (!rt2x00dev->workqueue) | ||
1009 | goto exit; | ||
1010 | |||
1006 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1011 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1007 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1012 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1008 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1013 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
@@ -1063,6 +1068,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1063 | rt2x00leds_unregister(rt2x00dev); | 1068 | rt2x00leds_unregister(rt2x00dev); |
1064 | 1069 | ||
1065 | /* | 1070 | /* |
1071 | * Stop all queued work. Note that most tasks will already be halted | ||
1072 | * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize(). | ||
1073 | */ | ||
1074 | flush_workqueue(rt2x00dev->workqueue); | ||
1075 | destroy_workqueue(rt2x00dev->workqueue); | ||
1076 | |||
1077 | /* | ||
1066 | * Free ieee80211_hw memory. | 1078 | * Free ieee80211_hw memory. |
1067 | */ | 1079 | */ |
1068 | rt2x00lib_remove_hw(rt2x00dev); | 1080 | rt2x00lib_remove_hw(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c90992f613fe..1253da89295b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
431 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 431 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
432 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); | 432 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); |
433 | else | 433 | else |
434 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | 434 | queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work); |
435 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
437 | 437 | ||
@@ -512,7 +512,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
512 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); | 512 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
513 | if (delayed) { | 513 | if (delayed) { |
514 | intf->delayed_flags |= delayed; | 514 | intf->delayed_flags |= delayed; |
515 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 515 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
516 | } | 516 | } |
517 | spin_unlock(&intf->lock); | 517 | spin_unlock(&intf->lock); |
518 | } | 518 | } |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index fceefd730ab8..675ff7900eee 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
134 | * Wait until the BBP becomes ready. | 134 | * Wait until the BBP becomes ready. |
135 | */ | 135 | */ |
136 | reg = rt73usb_bbp_check(rt2x00dev); | 136 | reg = rt73usb_bbp_check(rt2x00dev); |
137 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 137 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
138 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | 138 | goto exit_fail; |
139 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
140 | return; | ||
141 | } | ||
142 | 139 | ||
143 | /* | 140 | /* |
144 | * Write the data into the BBP. | 141 | * Write the data into the BBP. |
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
151 | 148 | ||
152 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); | 149 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
153 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 150 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
151 | |||
152 | return; | ||
153 | |||
154 | exit_fail: | ||
155 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
156 | |||
157 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
154 | } | 158 | } |
155 | 159 | ||
156 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 160 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
164 | * Wait until the BBP becomes ready. | 168 | * Wait until the BBP becomes ready. |
165 | */ | 169 | */ |
166 | reg = rt73usb_bbp_check(rt2x00dev); | 170 | reg = rt73usb_bbp_check(rt2x00dev); |
167 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 171 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
168 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | 172 | goto exit_fail; |
169 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
170 | return; | ||
171 | } | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Write the request into the BBP. | 175 | * Write the request into the BBP. |
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
184 | * Wait until the BBP becomes ready. | 185 | * Wait until the BBP becomes ready. |
185 | */ | 186 | */ |
186 | reg = rt73usb_bbp_check(rt2x00dev); | 187 | reg = rt73usb_bbp_check(rt2x00dev); |
187 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { | 188 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) |
188 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | 189 | goto exit_fail; |
189 | *value = 0xff; | ||
190 | return; | ||
191 | } | ||
192 | 190 | ||
193 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | 191 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); |
194 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | 192 | mutex_unlock(&rt2x00dev->usb_cache_mutex); |
193 | |||
194 | return; | ||
195 | |||
196 | exit_fail: | ||
197 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
198 | |||
199 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
200 | *value = 0xff; | ||
195 | } | 201 | } |
196 | 202 | ||
197 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | 203 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, |
diff --git a/include/linux/inet_lro.h b/include/linux/inet_lro.h index 80335b7d77c5..c4335faebb63 100644 --- a/include/linux/inet_lro.h +++ b/include/linux/inet_lro.h | |||
@@ -84,7 +84,11 @@ struct net_lro_mgr { | |||
84 | from received packets and eth protocol | 84 | from received packets and eth protocol |
85 | is still ETH_P_8021Q */ | 85 | is still ETH_P_8021Q */ |
86 | 86 | ||
87 | u32 ip_summed; /* Set in non generated SKBs in page mode */ | 87 | /* |
88 | * Set for generated SKBs that are not added to | ||
89 | * the frag list in fragmented mode | ||
90 | */ | ||
91 | u32 ip_summed; | ||
88 | u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY | 92 | u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY |
89 | * or CHECKSUM_NONE */ | 93 | * or CHECKSUM_NONE */ |
90 | 94 | ||
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1304ad2d7105..56dadb528f67 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -88,6 +88,8 @@ struct wireless_dev; | |||
88 | #define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ | 88 | #define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ |
89 | #define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ | 89 | #define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ |
90 | 90 | ||
91 | #ifdef __KERNEL__ | ||
92 | |||
91 | /* | 93 | /* |
92 | * Compute the worst case header length according to the protocols | 94 | * Compute the worst case header length according to the protocols |
93 | * used. | 95 | * used. |
@@ -114,6 +116,8 @@ struct wireless_dev; | |||
114 | #define MAX_HEADER (LL_MAX_HEADER + 48) | 116 | #define MAX_HEADER (LL_MAX_HEADER + 48) |
115 | #endif | 117 | #endif |
116 | 118 | ||
119 | #endif /* __KERNEL__ */ | ||
120 | |||
117 | struct net_device_subqueue | 121 | struct net_device_subqueue |
118 | { | 122 | { |
119 | /* Give a control state for each queue. This struct may contain | 123 | /* Give a control state for each queue. This struct may contain |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 7f7db8d57934..c2222ee74d66 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -365,6 +365,12 @@ static inline int ipv6_addr_any(const struct in6_addr *a) | |||
365 | a->s6_addr32[2] | a->s6_addr32[3] ) == 0); | 365 | a->s6_addr32[2] | a->s6_addr32[3] ) == 0); |
366 | } | 366 | } |
367 | 367 | ||
368 | static inline int ipv6_addr_loopback(const struct in6_addr *a) | ||
369 | { | ||
370 | return ((a->s6_addr32[0] | a->s6_addr32[1] | | ||
371 | a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); | ||
372 | } | ||
373 | |||
368 | static inline int ipv6_addr_v4mapped(const struct in6_addr *a) | 374 | static inline int ipv6_addr_v4mapped(const struct in6_addr *a) |
369 | { | 375 | { |
370 | return ((a->s6_addr32[0] | a->s6_addr32[1] | | 376 | return ((a->s6_addr32[0] | a->s6_addr32[1] | |
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 8df751b3be55..f90443045c70 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -95,6 +95,11 @@ extern struct list_head net_namespace_list; | |||
95 | #ifdef CONFIG_NET_NS | 95 | #ifdef CONFIG_NET_NS |
96 | extern void __put_net(struct net *net); | 96 | extern void __put_net(struct net *net); |
97 | 97 | ||
98 | static inline int net_alive(struct net *net) | ||
99 | { | ||
100 | return net && atomic_read(&net->count); | ||
101 | } | ||
102 | |||
98 | static inline struct net *get_net(struct net *net) | 103 | static inline struct net *get_net(struct net *net) |
99 | { | 104 | { |
100 | atomic_inc(&net->count); | 105 | atomic_inc(&net->count); |
@@ -125,6 +130,12 @@ int net_eq(const struct net *net1, const struct net *net2) | |||
125 | return net1 == net2; | 130 | return net1 == net2; |
126 | } | 131 | } |
127 | #else | 132 | #else |
133 | |||
134 | static inline int net_alive(struct net *net) | ||
135 | { | ||
136 | return 1; | ||
137 | } | ||
138 | |||
128 | static inline struct net *get_net(struct net *net) | 139 | static inline struct net *get_net(struct net *net) |
129 | { | 140 | { |
130 | return net; | 141 | return net; |
diff --git a/net/core/dev.c b/net/core/dev.c index f6944ecd5b2e..472676dd550e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2107,6 +2107,10 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2107 | 2107 | ||
2108 | rcu_read_lock(); | 2108 | rcu_read_lock(); |
2109 | 2109 | ||
2110 | /* Don't receive packets in an exiting network namespace */ | ||
2111 | if (!net_alive(dev_net(skb->dev))) | ||
2112 | goto out; | ||
2113 | |||
2110 | #ifdef CONFIG_NET_CLS_ACT | 2114 | #ifdef CONFIG_NET_CLS_ACT |
2111 | if (skb->tc_verd & TC_NCLS) { | 2115 | if (skb->tc_verd & TC_NCLS) { |
2112 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); | 2116 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); |
@@ -3034,7 +3038,7 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
3034 | /** | 3038 | /** |
3035 | * dev_unicast_add - add a secondary unicast address | 3039 | * dev_unicast_add - add a secondary unicast address |
3036 | * @dev: device | 3040 | * @dev: device |
3037 | * @addr: address to delete | 3041 | * @addr: address to add |
3038 | * @alen: length of @addr | 3042 | * @alen: length of @addr |
3039 | * | 3043 | * |
3040 | * Add a secondary unicast address to the device or increase | 3044 | * Add a secondary unicast address to the device or increase |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 72b4c184dd84..7c52fe277b62 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work) | |||
140 | struct pernet_operations *ops; | 140 | struct pernet_operations *ops; |
141 | struct net *net; | 141 | struct net *net; |
142 | 142 | ||
143 | /* Be very certain incoming network packets will not find us */ | ||
144 | rcu_barrier(); | ||
145 | |||
143 | net = container_of(work, struct net, work); | 146 | net = container_of(work, struct net, work); |
144 | 147 | ||
145 | mutex_lock(&net_mutex); | 148 | mutex_lock(&net_mutex); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2df012be973d..7c571560e9d2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1290,12 +1290,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
1290 | { | 1290 | { |
1291 | unsigned int nr_pages = spd->nr_pages; | 1291 | unsigned int nr_pages = spd->nr_pages; |
1292 | unsigned int poff, plen, len, toff, tlen; | 1292 | unsigned int poff, plen, len, toff, tlen; |
1293 | int headlen, seg; | 1293 | int headlen, seg, error = 0; |
1294 | 1294 | ||
1295 | toff = *offset; | 1295 | toff = *offset; |
1296 | tlen = *total_len; | 1296 | tlen = *total_len; |
1297 | if (!tlen) | 1297 | if (!tlen) { |
1298 | error = 1; | ||
1298 | goto err; | 1299 | goto err; |
1300 | } | ||
1299 | 1301 | ||
1300 | /* | 1302 | /* |
1301 | * if the offset is greater than the linear part, go directly to | 1303 | * if the offset is greater than the linear part, go directly to |
@@ -1337,7 +1339,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
1337 | * just jump directly to update and return, no point | 1339 | * just jump directly to update and return, no point |
1338 | * in going over fragments when the output is full. | 1340 | * in going over fragments when the output is full. |
1339 | */ | 1341 | */ |
1340 | if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb)) | 1342 | error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb); |
1343 | if (error) | ||
1341 | goto done; | 1344 | goto done; |
1342 | 1345 | ||
1343 | tlen -= plen; | 1346 | tlen -= plen; |
@@ -1367,7 +1370,8 @@ map_frag: | |||
1367 | if (!plen) | 1370 | if (!plen) |
1368 | break; | 1371 | break; |
1369 | 1372 | ||
1370 | if (spd_fill_page(spd, f->page, plen, poff, skb)) | 1373 | error = spd_fill_page(spd, f->page, plen, poff, skb); |
1374 | if (error) | ||
1371 | break; | 1375 | break; |
1372 | 1376 | ||
1373 | tlen -= plen; | 1377 | tlen -= plen; |
@@ -1380,7 +1384,10 @@ done: | |||
1380 | return 0; | 1384 | return 0; |
1381 | } | 1385 | } |
1382 | err: | 1386 | err: |
1383 | return 1; | 1387 | /* update the offset to reflect the linear part skip, if any */ |
1388 | if (!error) | ||
1389 | *offset = toff; | ||
1390 | return error; | ||
1384 | } | 1391 | } |
1385 | 1392 | ||
1386 | /* | 1393 | /* |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 4ed429bd5951..0546a0bc97ea 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -192,14 +192,21 @@ EXPORT_SYMBOL(inet_frag_evictor); | |||
192 | 192 | ||
193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, | 193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, |
194 | struct inet_frag_queue *qp_in, struct inet_frags *f, | 194 | struct inet_frag_queue *qp_in, struct inet_frags *f, |
195 | unsigned int hash, void *arg) | 195 | void *arg) |
196 | { | 196 | { |
197 | struct inet_frag_queue *qp; | 197 | struct inet_frag_queue *qp; |
198 | #ifdef CONFIG_SMP | 198 | #ifdef CONFIG_SMP |
199 | struct hlist_node *n; | 199 | struct hlist_node *n; |
200 | #endif | 200 | #endif |
201 | unsigned int hash; | ||
201 | 202 | ||
202 | write_lock(&f->lock); | 203 | write_lock(&f->lock); |
204 | /* | ||
205 | * While we stayed w/o the lock other CPU could update | ||
206 | * the rnd seed, so we need to re-calculate the hash | ||
207 | * chain. Fortunatelly the qp_in can be used to get one. | ||
208 | */ | ||
209 | hash = f->hashfn(qp_in); | ||
203 | #ifdef CONFIG_SMP | 210 | #ifdef CONFIG_SMP |
204 | /* With SMP race we have to recheck hash table, because | 211 | /* With SMP race we have to recheck hash table, because |
205 | * such entry could be created on other cpu, while we | 212 | * such entry could be created on other cpu, while we |
@@ -247,7 +254,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, | |||
247 | } | 254 | } |
248 | 255 | ||
249 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | 256 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, |
250 | struct inet_frags *f, void *arg, unsigned int hash) | 257 | struct inet_frags *f, void *arg) |
251 | { | 258 | { |
252 | struct inet_frag_queue *q; | 259 | struct inet_frag_queue *q; |
253 | 260 | ||
@@ -255,7 +262,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | |||
255 | if (q == NULL) | 262 | if (q == NULL) |
256 | return NULL; | 263 | return NULL; |
257 | 264 | ||
258 | return inet_frag_intern(nf, q, f, hash, arg); | 265 | return inet_frag_intern(nf, q, f, arg); |
259 | } | 266 | } |
260 | 267 | ||
261 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | 268 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, |
@@ -264,7 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
264 | struct inet_frag_queue *q; | 271 | struct inet_frag_queue *q; |
265 | struct hlist_node *n; | 272 | struct hlist_node *n; |
266 | 273 | ||
267 | read_lock(&f->lock); | ||
268 | hlist_for_each_entry(q, n, &f->hash[hash], list) { | 274 | hlist_for_each_entry(q, n, &f->hash[hash], list) { |
269 | if (q->net == nf && f->match(q, key)) { | 275 | if (q->net == nf && f->match(q, key)) { |
270 | atomic_inc(&q->refcnt); | 276 | atomic_inc(&q->refcnt); |
@@ -274,6 +280,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
274 | } | 280 | } |
275 | read_unlock(&f->lock); | 281 | read_unlock(&f->lock); |
276 | 282 | ||
277 | return inet_frag_create(nf, f, key, hash); | 283 | return inet_frag_create(nf, f, key); |
278 | } | 284 | } |
279 | EXPORT_SYMBOL(inet_frag_find); | 285 | EXPORT_SYMBOL(inet_frag_find); |
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 4a4d49fca1f2..cfd034a2b96e 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c | |||
@@ -383,8 +383,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, | |||
383 | out2: /* send aggregated SKBs to stack */ | 383 | out2: /* send aggregated SKBs to stack */ |
384 | lro_flush(lro_mgr, lro_desc); | 384 | lro_flush(lro_mgr, lro_desc); |
385 | 385 | ||
386 | out: /* Original SKB has to be posted to stack */ | 386 | out: |
387 | skb->ip_summed = lro_mgr->ip_summed; | ||
388 | return 1; | 387 | return 1; |
389 | } | 388 | } |
390 | 389 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 91e321407313..fbd5804b5d83 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -227,6 +227,8 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) | |||
227 | 227 | ||
228 | arg.iph = iph; | 228 | arg.iph = iph; |
229 | arg.user = user; | 229 | arg.user = user; |
230 | |||
231 | read_lock(&ip4_frags.lock); | ||
230 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); | 232 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); |
231 | 233 | ||
232 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); | 234 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index cf0850c068f5..c66ac83316e8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -258,6 +258,8 @@ | |||
258 | #include <linux/socket.h> | 258 | #include <linux/socket.h> |
259 | #include <linux/random.h> | 259 | #include <linux/random.h> |
260 | #include <linux/bootmem.h> | 260 | #include <linux/bootmem.h> |
261 | #include <linux/highmem.h> | ||
262 | #include <linux/swap.h> | ||
261 | #include <linux/cache.h> | 263 | #include <linux/cache.h> |
262 | #include <linux/err.h> | 264 | #include <linux/err.h> |
263 | #include <linux/crypto.h> | 265 | #include <linux/crypto.h> |
@@ -2688,7 +2690,7 @@ __setup("thash_entries=", set_thash_entries); | |||
2688 | void __init tcp_init(void) | 2690 | void __init tcp_init(void) |
2689 | { | 2691 | { |
2690 | struct sk_buff *skb = NULL; | 2692 | struct sk_buff *skb = NULL; |
2691 | unsigned long limit; | 2693 | unsigned long nr_pages, limit; |
2692 | int order, i, max_share; | 2694 | int order, i, max_share; |
2693 | 2695 | ||
2694 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 2696 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
@@ -2757,8 +2759,9 @@ void __init tcp_init(void) | |||
2757 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 2759 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
2758 | * memory, with a floor of 128 pages. | 2760 | * memory, with a floor of 128 pages. |
2759 | */ | 2761 | */ |
2760 | limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | 2762 | nr_pages = totalram_pages - totalhigh_pages; |
2761 | limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | 2763 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); |
2764 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
2762 | limit = max(limit, 128UL); | 2765 | limit = max(limit, 128UL); |
2763 | sysctl_tcp_mem[0] = limit / 4 * 3; | 2766 | sysctl_tcp_mem[0] = limit / 4 * 3; |
2764 | sysctl_tcp_mem[1] = limit; | 2767 | sysctl_tcp_mem[1] = limit; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 0db9b75c1fa2..4300bcf2ceaf 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2189,7 +2189,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2189 | } | 2189 | } |
2190 | 2190 | ||
2191 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " | 2191 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " |
2192 | "%08X %5d %8d %lu %d %p %u %u %u %u %d%n", | 2192 | "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n", |
2193 | i, src, srcp, dest, destp, sk->sk_state, | 2193 | i, src, srcp, dest, destp, sk->sk_state, |
2194 | tp->write_seq - tp->snd_una, | 2194 | tp->write_seq - tp->snd_una, |
2195 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : | 2195 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : |
@@ -2201,8 +2201,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
2201 | icsk->icsk_probes_out, | 2201 | icsk->icsk_probes_out, |
2202 | sock_i_ino(sk), | 2202 | sock_i_ino(sk), |
2203 | atomic_read(&sk->sk_refcnt), sk, | 2203 | atomic_read(&sk->sk_refcnt), sk, |
2204 | icsk->icsk_rto, | 2204 | jiffies_to_clock_t(icsk->icsk_rto), |
2205 | icsk->icsk_ack.ato, | 2205 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
2206 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, | 2206 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, |
2207 | tp->snd_cwnd, | 2207 | tp->snd_cwnd, |
2208 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, | 2208 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index f77a6011c302..34e5a96623ae 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -100,6 +100,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
100 | if (hdr->version != 6) | 100 | if (hdr->version != 6) |
101 | goto err; | 101 | goto err; |
102 | 102 | ||
103 | /* | ||
104 | * RFC4291 2.5.3 | ||
105 | * A packet received on an interface with a destination address | ||
106 | * of loopback must be dropped. | ||
107 | */ | ||
108 | if (!(dev->flags & IFF_LOOPBACK) && | ||
109 | ipv6_addr_loopback(&hdr->daddr)) | ||
110 | goto err; | ||
111 | |||
103 | skb->transport_header = skb->network_header + sizeof(*hdr); | 112 | skb->transport_header = skb->network_header + sizeof(*hdr); |
104 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); | 113 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
105 | 114 | ||
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index a9988841172a..030c0c956f9d 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -343,18 +343,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
343 | case IPV6_DSTOPTS: | 343 | case IPV6_DSTOPTS: |
344 | { | 344 | { |
345 | struct ipv6_txoptions *opt; | 345 | struct ipv6_txoptions *opt; |
346 | |||
347 | /* remove any sticky options header with a zero option | ||
348 | * length, per RFC3542. | ||
349 | */ | ||
346 | if (optlen == 0) | 350 | if (optlen == 0) |
347 | optval = NULL; | 351 | optval = NULL; |
352 | else if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
353 | optlen & 0x7 || optlen > 8 * 255) | ||
354 | goto e_inval; | ||
348 | 355 | ||
349 | /* hop-by-hop / destination options are privileged option */ | 356 | /* hop-by-hop / destination options are privileged option */ |
350 | retv = -EPERM; | 357 | retv = -EPERM; |
351 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) | 358 | if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) |
352 | break; | 359 | break; |
353 | 360 | ||
354 | if (optlen < sizeof(struct ipv6_opt_hdr) || | ||
355 | optlen & 0x7 || optlen > 8 * 255) | ||
356 | goto e_inval; | ||
357 | |||
358 | opt = ipv6_renew_options(sk, np->opt, optname, | 361 | opt = ipv6_renew_options(sk, np->opt, optname, |
359 | (struct ipv6_opt_hdr __user *)optval, | 362 | (struct ipv6_opt_hdr __user *)optval, |
360 | optlen); | 363 | optlen); |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 27a5e8b48d93..f405cea21a8b 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = { | |||
129 | .priority = NF_IP6_PRI_MANGLE, | 129 | .priority = NF_IP6_PRI_MANGLE, |
130 | }, | 130 | }, |
131 | { | 131 | { |
132 | .hook = ip6t_local_hook, | 132 | .hook = ip6t_route_hook, |
133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
134 | .pf = PF_INET6, | 134 | .pf = PF_INET6, |
135 | .hooknum = NF_INET_LOCAL_IN, | 135 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e65e26e210ee..cf20bc4fd60d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
207 | arg.id = id; | 207 | arg.id = id; |
208 | arg.src = src; | 208 | arg.src = src; |
209 | arg.dst = dst; | 209 | arg.dst = dst; |
210 | |||
211 | read_lock_bh(&nf_frags.lock); | ||
210 | hash = ip6qhashfn(id, src, dst); | 212 | hash = ip6qhashfn(id, src, dst); |
211 | 213 | ||
212 | local_bh_disable(); | ||
213 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 214 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
214 | local_bh_enable(); | 215 | local_bh_enable(); |
215 | if (q == NULL) | 216 | if (q == NULL) |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 13509f906d89..6ab957ec2dd6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -245,6 +245,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
245 | arg.id = id; | 245 | arg.id = id; |
246 | arg.src = src; | 246 | arg.src = src; |
247 | arg.dst = dst; | 247 | arg.dst = dst; |
248 | |||
249 | read_lock(&ip6_frags.lock); | ||
248 | hash = ip6qhashfn(id, src, dst); | 250 | hash = ip6qhashfn(id, src, dst); |
249 | 251 | ||
250 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); | 252 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index efe036aa3dd1..751e98f9b8b4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -238,7 +238,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr) | |||
238 | static inline struct rt6_info *rt6_device_match(struct net *net, | 238 | static inline struct rt6_info *rt6_device_match(struct net *net, |
239 | struct rt6_info *rt, | 239 | struct rt6_info *rt, |
240 | int oif, | 240 | int oif, |
241 | int strict) | 241 | int flags) |
242 | { | 242 | { |
243 | struct rt6_info *local = NULL; | 243 | struct rt6_info *local = NULL; |
244 | struct rt6_info *sprt; | 244 | struct rt6_info *sprt; |
@@ -251,7 +251,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
251 | if (dev->flags & IFF_LOOPBACK) { | 251 | if (dev->flags & IFF_LOOPBACK) { |
252 | if (sprt->rt6i_idev == NULL || | 252 | if (sprt->rt6i_idev == NULL || |
253 | sprt->rt6i_idev->dev->ifindex != oif) { | 253 | sprt->rt6i_idev->dev->ifindex != oif) { |
254 | if (strict && oif) | 254 | if (flags & RT6_LOOKUP_F_IFACE && oif) |
255 | continue; | 255 | continue; |
256 | if (local && (!oif || | 256 | if (local && (!oif || |
257 | local->rt6i_idev->dev->ifindex == oif)) | 257 | local->rt6i_idev->dev->ifindex == oif)) |
@@ -264,7 +264,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
264 | if (local) | 264 | if (local) |
265 | return local; | 265 | return local; |
266 | 266 | ||
267 | if (strict) | 267 | if (flags & RT6_LOOKUP_F_IFACE) |
268 | return net->ipv6.ip6_null_entry; | 268 | return net->ipv6.ip6_null_entry; |
269 | } | 269 | } |
270 | return rt; | 270 | return rt; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 09be09cc1aa6..30dbab7cc3cc 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1946,7 +1946,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
1946 | 1946 | ||
1947 | seq_printf(seq, | 1947 | seq_printf(seq, |
1948 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 1948 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
1949 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", | 1949 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n", |
1950 | i, | 1950 | i, |
1951 | src->s6_addr32[0], src->s6_addr32[1], | 1951 | src->s6_addr32[0], src->s6_addr32[1], |
1952 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 1952 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
@@ -1962,8 +1962,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
1962 | icsk->icsk_probes_out, | 1962 | icsk->icsk_probes_out, |
1963 | sock_i_ino(sp), | 1963 | sock_i_ino(sp), |
1964 | atomic_read(&sp->sk_refcnt), sp, | 1964 | atomic_read(&sp->sk_refcnt), sp, |
1965 | icsk->icsk_rto, | 1965 | jiffies_to_clock_t(icsk->icsk_rto), |
1966 | icsk->icsk_ack.ato, | 1966 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
1967 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, | 1967 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, |
1968 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh | 1968 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh |
1969 | ); | 1969 | ); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index d4893bd17754..6597c779e35a 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -387,6 +387,15 @@ void ieee80211_key_free(struct ieee80211_key *key) | |||
387 | if (!key) | 387 | if (!key) |
388 | return; | 388 | return; |
389 | 389 | ||
390 | if (!key->sdata) { | ||
391 | /* The key has not been linked yet, simply free it | ||
392 | * and don't Oops */ | ||
393 | if (key->conf.alg == ALG_CCMP) | ||
394 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
395 | kfree(key); | ||
396 | return; | ||
397 | } | ||
398 | |||
390 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); | 399 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); |
391 | __ieee80211_key_free(key); | 400 | __ieee80211_key_free(key); |
392 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); | 401 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 0099da5b2591..52b2611a6eb6 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -1534,7 +1534,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, | |||
1534 | } | 1534 | } |
1535 | } | 1535 | } |
1536 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { | 1536 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { |
1537 | if (addr6->valid || iter_addr6++ < skip_addr6) | 1537 | if (!addr6->valid || iter_addr6++ < skip_addr6) |
1538 | continue; | 1538 | continue; |
1539 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, | 1539 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, |
1540 | iface, | 1540 | iface, |
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index 47bbf45ae5d7..2d106cfe1d27 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
@@ -132,6 +132,7 @@ errout: | |||
132 | * @maxtype: maximum attribute type to be expected | 132 | * @maxtype: maximum attribute type to be expected |
133 | * @head: head of attribute stream | 133 | * @head: head of attribute stream |
134 | * @len: length of attribute stream | 134 | * @len: length of attribute stream |
135 | * @policy: validation policy | ||
135 | * | 136 | * |
136 | * Parses a stream of attributes and stores a pointer to each attribute in | 137 | * Parses a stream of attributes and stores a pointer to each attribute in |
137 | * the tb array accessable via the attribute type. Attributes with a type | 138 | * the tb array accessable via the attribute type. Attributes with a type |
@@ -194,7 +195,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) | |||
194 | /** | 195 | /** |
195 | * nla_strlcpy - Copy string attribute payload into a sized buffer | 196 | * nla_strlcpy - Copy string attribute payload into a sized buffer |
196 | * @dst: where to copy the string to | 197 | * @dst: where to copy the string to |
197 | * @src: attribute to copy the string from | 198 | * @nla: attribute to copy the string from |
198 | * @dstsize: size of destination buffer | 199 | * @dstsize: size of destination buffer |
199 | * | 200 | * |
200 | * Copies at most dstsize - 1 bytes into the destination buffer. | 201 | * Copies at most dstsize - 1 bytes into the destination buffer. |
@@ -340,9 +341,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) | |||
340 | } | 341 | } |
341 | 342 | ||
342 | /** | 343 | /** |
343 | * nla_reserve - reserve room for attribute without header | 344 | * nla_reserve_nohdr - reserve room for attribute without header |
344 | * @skb: socket buffer to reserve room on | 345 | * @skb: socket buffer to reserve room on |
345 | * @len: length of attribute payload | 346 | * @attrlen: length of attribute payload |
346 | * | 347 | * |
347 | * Reserves room for attribute payload without a header. | 348 | * Reserves room for attribute payload without a header. |
348 | * | 349 | * |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 82adfe6447d7..9437b27ff84d 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -106,17 +106,6 @@ config NET_SCH_PRIO | |||
106 | To compile this code as a module, choose M here: the | 106 | To compile this code as a module, choose M here: the |
107 | module will be called sch_prio. | 107 | module will be called sch_prio. |
108 | 108 | ||
109 | config NET_SCH_RR | ||
110 | tristate "Multi Band Round Robin Queuing (RR)" | ||
111 | select NET_SCH_PRIO | ||
112 | ---help--- | ||
113 | Say Y here if you want to use an n-band round robin packet | ||
114 | scheduler. | ||
115 | |||
116 | The module uses sch_prio for its framework and is aliased as | ||
117 | sch_rr, so it will load sch_prio, although it is referred | ||
118 | to using sch_rr. | ||
119 | |||
120 | config NET_SCH_RED | 109 | config NET_SCH_RED |
121 | tristate "Random Early Detection (RED)" | 110 | tristate "Random Early Detection (RED)" |
122 | ---help--- | 111 | ---help--- |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index d355e5e47fe3..13afa7214392 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) | |||
468 | 468 | ||
469 | return sch; | 469 | return sch; |
470 | errout: | 470 | errout: |
471 | return ERR_PTR(-err); | 471 | return ERR_PTR(err); |
472 | } | 472 | } |
473 | 473 | ||
474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, | 474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f98650cc48d8..43460a1cb6d0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4512,7 +4512,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, | |||
4512 | if (copy_from_user(&getaddrs, optval, len)) | 4512 | if (copy_from_user(&getaddrs, optval, len)) |
4513 | return -EFAULT; | 4513 | return -EFAULT; |
4514 | 4514 | ||
4515 | if (getaddrs.addr_num <= 0) return -EINVAL; | 4515 | if (getaddrs.addr_num <= 0 || |
4516 | getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr))) | ||
4517 | return -EINVAL; | ||
4516 | /* | 4518 | /* |
4517 | * For UDP-style sockets, id specifies the association to query. | 4519 | * For UDP-style sockets, id specifies the association to query. |
4518 | * If the id field is set to the value '0' then the locally bound | 4520 | * If the id field is set to the value '0' then the locally bound |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index b4280490cf6e..70ceb1604ad8 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -485,8 +485,8 @@ static int unix_socketpair(struct socket *, struct socket *); | |||
485 | static int unix_accept(struct socket *, struct socket *, int); | 485 | static int unix_accept(struct socket *, struct socket *, int); |
486 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); | 486 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); |
487 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); | 487 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); |
488 | static unsigned int unix_datagram_poll(struct file *, struct socket *, | 488 | static unsigned int unix_dgram_poll(struct file *, struct socket *, |
489 | poll_table *); | 489 | poll_table *); |
490 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); | 490 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); |
491 | static int unix_shutdown(struct socket *, int); | 491 | static int unix_shutdown(struct socket *, int); |
492 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, | 492 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, |
@@ -532,7 +532,7 @@ static const struct proto_ops unix_dgram_ops = { | |||
532 | .socketpair = unix_socketpair, | 532 | .socketpair = unix_socketpair, |
533 | .accept = sock_no_accept, | 533 | .accept = sock_no_accept, |
534 | .getname = unix_getname, | 534 | .getname = unix_getname, |
535 | .poll = unix_datagram_poll, | 535 | .poll = unix_dgram_poll, |
536 | .ioctl = unix_ioctl, | 536 | .ioctl = unix_ioctl, |
537 | .listen = sock_no_listen, | 537 | .listen = sock_no_listen, |
538 | .shutdown = unix_shutdown, | 538 | .shutdown = unix_shutdown, |
@@ -553,7 +553,7 @@ static const struct proto_ops unix_seqpacket_ops = { | |||
553 | .socketpair = unix_socketpair, | 553 | .socketpair = unix_socketpair, |
554 | .accept = unix_accept, | 554 | .accept = unix_accept, |
555 | .getname = unix_getname, | 555 | .getname = unix_getname, |
556 | .poll = unix_datagram_poll, | 556 | .poll = unix_dgram_poll, |
557 | .ioctl = unix_ioctl, | 557 | .ioctl = unix_ioctl, |
558 | .listen = unix_listen, | 558 | .listen = unix_listen, |
559 | .shutdown = unix_shutdown, | 559 | .shutdown = unix_shutdown, |
@@ -1992,29 +1992,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl | |||
1992 | return mask; | 1992 | return mask; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | 1995 | static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, |
1996 | poll_table *wait) | 1996 | poll_table *wait) |
1997 | { | 1997 | { |
1998 | struct sock *sk = sock->sk, *peer; | 1998 | struct sock *sk = sock->sk, *other; |
1999 | unsigned int mask; | 1999 | unsigned int mask, writable; |
2000 | 2000 | ||
2001 | poll_wait(file, sk->sk_sleep, wait); | 2001 | poll_wait(file, sk->sk_sleep, wait); |
2002 | |||
2003 | peer = unix_peer_get(sk); | ||
2004 | if (peer) { | ||
2005 | if (peer != sk) { | ||
2006 | /* | ||
2007 | * Writability of a connected socket additionally | ||
2008 | * depends on the state of the receive queue of the | ||
2009 | * peer. | ||
2010 | */ | ||
2011 | poll_wait(file, &unix_sk(peer)->peer_wait, wait); | ||
2012 | } else { | ||
2013 | sock_put(peer); | ||
2014 | peer = NULL; | ||
2015 | } | ||
2016 | } | ||
2017 | |||
2018 | mask = 0; | 2002 | mask = 0; |
2019 | 2003 | ||
2020 | /* exceptional events? */ | 2004 | /* exceptional events? */ |
@@ -2040,14 +2024,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | |||
2040 | } | 2024 | } |
2041 | 2025 | ||
2042 | /* writable? */ | 2026 | /* writable? */ |
2043 | if (unix_writable(sk) && !(peer && unix_recvq_full(peer))) | 2027 | writable = unix_writable(sk); |
2028 | if (writable) { | ||
2029 | other = unix_peer_get(sk); | ||
2030 | if (other) { | ||
2031 | if (unix_peer(other) != sk) { | ||
2032 | poll_wait(file, &unix_sk(other)->peer_wait, | ||
2033 | wait); | ||
2034 | if (unix_recvq_full(other)) | ||
2035 | writable = 0; | ||
2036 | } | ||
2037 | |||
2038 | sock_put(other); | ||
2039 | } | ||
2040 | } | ||
2041 | |||
2042 | if (writable) | ||
2044 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 2043 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
2045 | else | 2044 | else |
2046 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 2045 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
2047 | 2046 | ||
2048 | if (peer) | ||
2049 | sock_put(peer); | ||
2050 | |||
2051 | return mask; | 2047 | return mask; |
2052 | } | 2048 | } |
2053 | 2049 | ||