Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Mar 2008 20:08:09 +0000 (13:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Mar 2008 20:08:09 +0000 (13:08 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (47 commits)
  [SCTP]: Fix local_addr deletions during list traversals.
  net: fix build with CONFIG_NET=n
  [TCP]: Prevent sending past receiver window with TSO (at last skb)
  rt2x00: Add new D-Link USB ID
  rt2x00: never disable multicast because it disables broadcast too
  libertas: fix the 'compare command with itself' properly
  drivers/net/Kconfig: fix whitespace for GELIC_WIRELESS entry
  [NETFILTER]: nf_queue: don't return error when unregistering a non-existant handler
  [NETFILTER]: nfnetlink_queue: fix EPERM when binding/unbinding and instance 0 exists
  [NETFILTER]: nfnetlink_log: fix EPERM when binding/unbinding and instance 0 exists
  [NETFILTER]: nf_conntrack: replace horrible hack with ksize()
  [NETFILTER]: nf_conntrack: add \n to "expectation table full" message
  [NETFILTER]: xt_time: fix failure to match on Sundays
  [NETFILTER]: nfnetlink_log: fix computation of netlink skb size
  [NETFILTER]: nfnetlink_queue: fix computation of allocated size for netlink skb.
  [NETFILTER]: nfnetlink: fix ifdef in nfnetlink_compat.h
  [NET]: include <linux/types.h> into linux/ethtool.h for __u* typedef
  [NET]: Make /proc/net a symlink on /proc/self/net (v3)
  RxRPC: fix rxrpc_recvmsg()'s returning of msg_name
  net/enc28j60: oops fix
  ...

55 files changed:
MAINTAINERS
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/idt77252.c
drivers/bluetooth/hci_usb.c
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_v110.c
drivers/net/Kconfig
drivers/net/ac3200.c
drivers/net/apne.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/capmode.c
drivers/net/atarilance.c
drivers/net/e100.c
drivers/net/enc28j60.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/mv643xx_eth.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/phy/Kconfig
drivers/net/phy/davicom.c
drivers/net/pppol2tp.c
drivers/net/s2io.c
drivers/net/tulip/de2104x.c
drivers/net/wan/sbni.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
fs/proc/base.c
fs/proc/generic.c
fs/proc/internal.h
fs/proc/proc_net.c
include/linux/ethtool.h
include/linux/netfilter/nfnetlink_compat.h
include/linux/proc_fs.h
include/net/bluetooth/bluetooth.h
include/net/irda/irttp.h
include/net/net_namespace.h
include/net/netfilter/nf_conntrack_extend.h
net/bluetooth/bnep/bnep.h
net/bluetooth/bnep/sock.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c
net/ipv4/tcp_output.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_extend.c
net/netfilter/nf_queue.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netfilter/xt_time.c
net/rxrpc/ar-recvmsg.c
net/sctp/bind_addr.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/socket.c

index 25f450fe1059602a3d38292964d4c4ca9a0d38c1..0f95a4a787a68e3da0eeb79afa9c6ed7d7d63b9c 100644 (file)
@@ -2052,43 +2052,19 @@ M:      kernel@wantstofly.org
 L:     netdev@vger.kernel.org
 S:     Maintained
 
-INTEL PRO/100 ETHERNET SUPPORT
+INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe)
 P:     Auke Kok
 M:     auke-jan.h.kok@intel.com
 P:     Jesse Brandeburg
 M:     jesse.brandeburg@intel.com
 P:     Jeff Kirsher
 M:     jeffrey.t.kirsher@intel.com
+P:     Bruce Allan
+M:     bruce.w.allan@intel.com
 P:     John Ronciak
 M:     john.ronciak@intel.com
 L:     e1000-devel@lists.sourceforge.net
-W:     http://sourceforge.net/projects/e1000/
-S:     Supported
-
-INTEL PRO/1000 GIGABIT ETHERNET SUPPORT
-P:     Auke Kok
-M:     auke-jan.h.kok@intel.com
-P:     Jesse Brandeburg
-M:     jesse.brandeburg@intel.com
-P:     Jeff Kirsher
-M:     jeffrey.t.kirsher@intel.com
-P:     John Ronciak
-M:     john.ronciak@intel.com
-L:     e1000-devel@lists.sourceforge.net
-W:     http://sourceforge.net/projects/e1000/
-S:     Supported
-
-INTEL PRO/10GbE SUPPORT
-P:     Ayyappan Veeraiyan
-M:     ayyappan.veeraiyan@intel.com
-P:     Auke Kok
-M:     auke-jan.h.kok@intel.com
-P:     Jesse Brandeburg
-M:     jesse.brandeburg@intel.com
-P:     John Ronciak
-M:     john.ronciak@intel.com
-L:     e1000-devel@lists.sourceforge.net
-W:     http://sourceforge.net/projects/e1000/
+W:     http://e1000.sourceforge.net/
 S:     Supported
 
 INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
index c662d686154a1ac64ad5b1c1e7deca1029fce0bc..47c57a4294b7c8beccb38ee7e4ed62fc388ad4fc 100644 (file)
@@ -331,8 +331,8 @@ module_param(fs_keystream, int, 0);
 #define FS_DEBUG_QSIZE   0x00001000
 
 
-#define func_enter() fs_dprintk (FS_DEBUG_FLOW, "fs: enter %s\n", __FUNCTION__)
-#define func_exit()  fs_dprintk (FS_DEBUG_FLOW, "fs: exit  %s\n", __FUNCTION__)
+#define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__)
+#define func_exit()  fs_dprintk(FS_DEBUG_FLOW, "fs: exit  %s\n", __func__)
 
 
 static struct fs_dev *fs_boards = NULL;
index f97e050338f04a0dd24431dafe194fb8600f3de9..9427a61f62b0e36f3ec538f7d99d4b854212aa74 100644 (file)
@@ -95,8 +95,8 @@
 #if 1
 #define ASSERT(expr)     if (!(expr)) { \
                             printk(FORE200E "assertion failed! %s[%d]: %s\n", \
-                                   __FUNCTION__, __LINE__, #expr); \
-                            panic(FORE200E "%s", __FUNCTION__); \
+                                   __func__, __LINE__, #expr); \
+                            panic(FORE200E "%s", __func__); \
                         }
 #else
 #define ASSERT(expr)     do {} while (0)
index eee54c0cde6819ad064ada9cb619bdb3954f0052..b967919fb7e2e91a763ab8a6c53307f21cbfa443 100644 (file)
@@ -555,7 +555,7 @@ idt77252_tx_dump(struct idt77252_dev *card)
        struct vc_map *vc;
        int i;
 
-       printk("%s\n", __FUNCTION__);
+       printk("%s\n", __func__);
        for (i = 0; i < card->tct_size; i++) {
                vc = card->vcs[i];
                if (!vc)
@@ -1035,7 +1035,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
        skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2));
        if (skb == NULL) {
                printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n",
-                      card->name, __FUNCTION__,
+                      card->name, __func__,
                       le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2),
                       le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4));
                return;
@@ -1873,7 +1873,7 @@ add_rx_skb(struct idt77252_dev *card, int queue,
                        return;
 
                if (sb_pool_add(card, skb, queue)) {
-                       printk("%s: SB POOL full\n", __FUNCTION__);
+                       printk("%s: SB POOL full\n", __func__);
                        goto outfree;
                }
 
@@ -1883,7 +1883,7 @@ add_rx_skb(struct idt77252_dev *card, int queue,
                IDT77252_PRV_PADDR(skb) = paddr;
 
                if (push_rx_skb(card, skb, queue)) {
-                       printk("%s: FB QUEUE full\n", __FUNCTION__);
+                       printk("%s: FB QUEUE full\n", __func__);
                        goto outunmap;
                }
        }
@@ -3821,12 +3821,12 @@ static int __init idt77252_init(void)
 {
        struct sk_buff *skb;
 
-       printk("%s: at %p\n", __FUNCTION__, idt77252_init);
+       printk("%s: at %p\n", __func__, idt77252_init);
 
        if (sizeof(skb->cb) < sizeof(struct atm_skb_data) +
                              sizeof(struct idt77252_skb_prv)) {
                printk(KERN_ERR "%s: skb->cb is too small (%lu < %lu)\n",
-                      __FUNCTION__, (unsigned long) sizeof(skb->cb),
+                      __func__, (unsigned long) sizeof(skb->cb),
                       (unsigned long) sizeof(struct atm_skb_data) +
                                       sizeof(struct idt77252_skb_prv));
                return -EIO;
index f16c94cbf4888addf06fa0c8b29eb0f494d56c4a..8b884f87d8b7be56d4a290469cab518ebac62ba9 100644 (file)
@@ -149,6 +149,9 @@ static struct usb_device_id blacklist_ids[] = {
        { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
        { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
 
+       /* CONWISE Technology based adapters with buggy SCO support */
+       { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC },
+
        /* Belkin F8T012 and F8T013 devices */
        { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
        { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
index 9cef6fcf587b6baaef9df48c3616779262d6d3a9..d4ad6992f776c895d637b72c779b04fd5dd7915e 100644 (file)
@@ -981,13 +981,13 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
 }
 
 
-static __inline int
+static inline int
 isdn_minor2drv(int minor)
 {
        return (dev->drvmap[minor]);
 }
 
-static __inline int
+static inline int
 isdn_minor2chan(int minor)
 {
        return (dev->chanmap[minor]);
index 5484d3c38a5761b76ab888d146cab65719add51b..c5d02b6aafabb614ed731ff9318b9e7281ec93a2 100644 (file)
@@ -62,7 +62,7 @@ static unsigned char V110_OffMatrix_38400[] =
  * and to 67452301 when keylen = 2. This is necessary because ordering on
  * the isdn line is the other way.
  */
-static __inline unsigned char
+static inline unsigned char
 FlipBits(unsigned char c, int keylen)
 {
        unsigned char b = c;
index a0f0e605d630389bbed8450c1446905002e1a836..fe7b5ec09708adac2efa77442066a095608a802a 100644 (file)
@@ -2366,15 +2366,15 @@ config GELIC_NET
          module will be called ps3_gelic.
 
 config GELIC_WIRELESS
-       bool "PS3 Wireless support"
-       depends on GELIC_NET
-       select WIRELESS_EXT
-       help
-        This option adds the support for the wireless feature of PS3.
-        If you have the wireless-less model of PS3 or have no plan to
-        use wireless feature, disabling this option saves memory.  As
-        the driver automatically distinguishes the models, you can
-        safely enable this option even if you have a wireless-less model.
+       bool "PS3 Wireless support"
+       depends on GELIC_NET
+       select WIRELESS_EXT
+       help
+         This option adds the support for the wireless feature of PS3.
+         If you have the wireless-less model of PS3 or have no plan to
+         use wireless feature, disabling this option saves memory.  As
+         the driver automatically distinguishes the models, you can
+         safely enable this option even if you have a wireless-less model.
 
 config GIANFAR
        tristate "Gianfar Ethernet"
@@ -2519,7 +2519,7 @@ config CHELSIO_T3
 
 config EHEA
        tristate "eHEA Ethernet support"
-       depends on IBMEBUS && INET
+       depends on IBMEBUS && INET && SPARSEMEM
        select INET_LRO
        ---help---
          This driver supports the IBM pSeries eHEA ethernet adapter.
index 5136d94923aa3910e0007982dd7893c493e2fd62..b1448637107f3fada6f1a97536dfd6492a9d9117 100644 (file)
@@ -369,7 +369,7 @@ MODULE_PARM_DESC(mem, "Memory base address(es)");
 MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
 MODULE_LICENSE("GPL");
 
-int __init init_module(void)
+static int __init ac3200_module_init(void)
 {
        struct net_device *dev;
        int this_dev, found = 0;
@@ -404,8 +404,7 @@ static void cleanup_card(struct net_device *dev)
        iounmap(ei_status.mem);
 }
 
-void __exit
-cleanup_module(void)
+static void __exit ac3200_module_exit(void)
 {
        int this_dev;
 
@@ -418,4 +417,6 @@ cleanup_module(void)
                }
        }
 }
+module_init(ac3200_module_init);
+module_exit(ac3200_module_exit);
 #endif /* MODULE */
index c12cbdf368b1edbe37b3077e9debdcf4f93cc847..47a8275d396281bd79f6a2631dbfd1da93273529 100644 (file)
@@ -569,7 +569,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id)
 #ifdef MODULE
 static struct net_device *apne_dev;
 
-int __init init_module(void)
+static int __init apne_module_init(void)
 {
        apne_dev = apne_probe(-1);
        if (IS_ERR(apne_dev))
@@ -577,7 +577,7 @@ int __init init_module(void)
        return 0;
 }
 
-void __exit cleanup_module(void)
+static void __exit apne_module_exit(void)
 {
        unregister_netdev(apne_dev);
 
@@ -591,7 +591,8 @@ void __exit cleanup_module(void)
 
        free_netdev(apne_dev);
 }
-
+module_init(apne_module_init);
+module_exit(apne_module_exit);
 #endif
 
 static int init_pcmcia(void)
index 6ab2c2d4d673de32baf44307a32a0d5baf00183b..fef5560bc7a2ee2d8c6aee66f6e413022fdfdca1 100644 (file)
@@ -1252,7 +1252,7 @@ module_param(irq, int, 0);
 module_param(dma, int, 0);
 
 
-int __init init_module(void)
+static int __init ltpc_module_init(void)
 {
         if(io == 0)
                printk(KERN_NOTICE
@@ -1263,6 +1263,7 @@ int __init init_module(void)
                return PTR_ERR(dev_ltpc);
        return 0;
 }
+module_init(ltpc_module_init);
 #endif
 
 static void __exit ltpc_cleanup(void)
index cc4610db6395f9e743e16ff374fd88f860d5dbe2..02cb8f1c11484b23460100c85f60faec62bd3ea5 100644 (file)
@@ -80,17 +80,19 @@ void arcnet_cap_init(void)
 
 #ifdef MODULE
 
-int __init init_module(void)
+static int __init capmode_module_init(void)
 {
        printk(VERSION);
        arcnet_cap_init();
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit capmode_module_exit(void)
 {
        arcnet_unregister_proto(&capmode_proto);
 }
+module_init(capmode_module_init);
+module_exit(capmode_module_exit);
 
 MODULE_LICENSE("GPL");
 #endif                         /* MODULE */
index b74dbeef805018f2d64f246130239f147fce8191..13c293b286de37f4509e039c66a384b00ebc0249 100644 (file)
@@ -336,8 +336,6 @@ struct lance_addr {
 
 /***************************** Prototypes *****************************/
 
-static int addr_accessible( volatile void *regp, int wordflag, int
-                            writeflag );
 static unsigned long lance_probe1( struct net_device *dev, struct lance_addr
                                    *init_rec );
 static int lance_open( struct net_device *dev );
@@ -406,7 +404,8 @@ struct net_device * __init atarilance_probe(int unit)
 
 /* Derived from hwreg_present() in atari/config.c: */
 
-static int __init addr_accessible( volatile void *regp, int wordflag, int writeflag )
+static noinline int __init addr_accessible(volatile void *regp, int wordflag,
+                                          int writeflag)
 {
        int             ret;
        long    flags;
index 36ba6dc96acc8494605c41315a8acecaa13f702f..cdf3090a1885fbe6ebfdc537c313af036aaf4b76 100644 (file)
@@ -2782,16 +2782,13 @@ static void __devexit e100_remove(struct pci_dev *pdev)
        }
 }
 
-#ifdef CONFIG_PM
 static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
 
        if (netif_running(netdev))
-               napi_disable(&nic->napi);
-       del_timer_sync(&nic->watchdog);
-       netif_carrier_off(nic->netdev);
+               e100_down(nic);
        netif_device_detach(netdev);
 
        pci_save_state(pdev);
@@ -2804,14 +2801,13 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
                pci_enable_wake(pdev, PCI_D3cold, 0);
        }
 
-       free_irq(pdev->irq, netdev);
-
        pci_disable_device(pdev);
        pci_set_power_state(pdev, PCI_D3hot);
 
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int e100_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2832,26 +2828,7 @@ static int e100_resume(struct pci_dev *pdev)
 
 static void e100_shutdown(struct pci_dev *pdev)
 {
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct nic *nic = netdev_priv(netdev);
-
-       if (netif_running(netdev))
-               napi_disable(&nic->napi);
-       del_timer_sync(&nic->watchdog);
-       netif_carrier_off(nic->netdev);
-
-       if ((nic->flags & wol_magic) | e100_asf(nic)) {
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
-       } else {
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
-       }
-
-       free_irq(pdev->irq, netdev);
-
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
+       e100_suspend(pdev, PMSG_SUSPEND);
 }
 
 /* ------------------ PCI Error Recovery infrastructure  -------------- */
index 0809a6a5a286ec8325a562a4acc510a2b60ae765..46a90e9ec56320e4eaca6d48ba21c6d463981ddc 100644 (file)
@@ -900,7 +900,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                if (RSV_GETBIT(rxstat, RSV_LENCHECKERR))
                        ndev->stats.rx_frame_errors++;
        } else {
-               skb = dev_alloc_skb(len);
+               skb = dev_alloc_skb(len + NET_IP_ALIGN);
                if (!skb) {
                        if (netif_msg_rx_err(priv))
                                dev_err(&ndev->dev,
@@ -908,6 +908,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                        ndev->stats.rx_dropped++;
                } else {
                        skb->dev = ndev;
+                       skb_reserve(skb, NET_IP_ALIGN);
                        /* copy the packet from the receive buffer */
                        enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
                                        len, skb_put(skb, len));
index 23d0a4afe0e1d786db4ace8b93ba352f7eef28c1..c2095ce531c9b7fdb9785a0dea063f45516b8f10 100644 (file)
@@ -2133,7 +2133,7 @@ static void ixgbe_watchdog(unsigned long data)
                                (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
                                 "10 Gbps" :
                                 (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
-                                 "1 Gpbs" : "unknown speed")),
+                                 "1 Gbps" : "unknown speed")),
                                ((FLOW_RX && FLOW_TX) ? "RX/TX" :
                                 (FLOW_RX ? "RX" :
                                 (FLOW_TX ? "TX" : "None"))));
index b528ce77c4069997d67ffaac2e0c00b1b6f5d383..771139e283af3609b3ae1b0e46b989ec6ea1a9be 100644 (file)
@@ -2104,6 +2104,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
                " and Dale Farnsworth");
 MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
+MODULE_ALIAS("platform:mv643xx_eth");
 
 /*
  * The second part is the low level driver of the gigE ethernet ports.
index e8a63e483a2be034f9c4a057d0b3cc8457ac645a..ce95c5d168fe9922382726ce71e295392548f2a3 100644 (file)
@@ -1268,7 +1268,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
                }
        }
     
-       if (interrupts && ei_debug) 
+       if (interrupts && ei_debug > 3
        {
                handled = 1;
                if (nr_serviced >= MAX_SERVICE) 
index f4ca0591231d233f63a2d98cb6036f106fde21c4..3ac8529bb92ca9915b76b2cb1026f5308f05c107 100644 (file)
@@ -67,6 +67,7 @@ config REALTEK_PHY
 
 config FIXED_PHY
        bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
+       depends on PHYLIB=y
        ---help---
          Adds the platform "fixed" MDIO Bus to cover the boards that use
          PHYs that are not connected to the real MDIO bus.
index 7ed632db00d77dac9fb36df9629d74ea8e217b6d..d926168bc7809c62e46d32d5d9fe98e493ad6e7e 100644 (file)
@@ -37,6 +37,7 @@
 
 #define MII_DM9161_SCR         0x10
 #define MII_DM9161_SCR_INIT    0x0610
+#define MII_DM9161_SCR_RMII    0x0100
 
 /* DM9161 Interrupt Register */
 #define MII_DM9161_INTR        0x15
@@ -103,7 +104,7 @@ static int dm9161_config_aneg(struct phy_device *phydev)
 
 static int dm9161_config_init(struct phy_device *phydev)
 {
-       int err;
+       int err, temp;
 
        /* Isolate the PHY */
        err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
@@ -111,9 +112,19 @@ static int dm9161_config_init(struct phy_device *phydev)
        if (err < 0)
                return err;
 
-       /* Do not bypass the scrambler/descrambler */
-       err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
+       switch (phydev->interface) {
+       case PHY_INTERFACE_MODE_MII:
+               temp = MII_DM9161_SCR_INIT;
+               break;
+       case PHY_INTERFACE_MODE_RMII:
+               temp =  MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII;
+               break;
+       default:
+               return -EINVAL;
+       }
 
+       /* Do not bypass the scrambler/descrambler */
+       err = phy_write(phydev, MII_DM9161_SCR, temp);
        if (err < 0)
                return err;
 
index 86e5dba079fed6d9a62bcd6d9e9e31fb40888999..3d10ca050b7991b9f53cf4a6cc3d5adb873137aa 100644 (file)
@@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
        struct pppol2tp_session *session;
        struct hlist_node *walk;
 
-       read_lock(&tunnel->hlist_lock);
+       read_lock_bh(&tunnel->hlist_lock);
        hlist_for_each_entry(session, walk, session_list, hlist) {
                if (session->tunnel_addr.s_session == session_id) {
-                       read_unlock(&tunnel->hlist_lock);
+                       read_unlock_bh(&tunnel->hlist_lock);
                        return session;
                }
        }
-       read_unlock(&tunnel->hlist_lock);
+       read_unlock_bh(&tunnel->hlist_lock);
 
        return NULL;
 }
@@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
 {
        struct pppol2tp_tunnel *tunnel = NULL;
 
-       read_lock(&pppol2tp_tunnel_list_lock);
+       read_lock_bh(&pppol2tp_tunnel_list_lock);
        list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
                if (tunnel->stats.tunnel_id == tunnel_id) {
-                       read_unlock(&pppol2tp_tunnel_list_lock);
+                       read_unlock_bh(&pppol2tp_tunnel_list_lock);
                        return tunnel;
                }
        }
-       read_unlock(&pppol2tp_tunnel_list_lock);
+       read_unlock_bh(&pppol2tp_tunnel_list_lock);
 
        return NULL;
 }
@@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
 static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb)
 {
        struct sk_buff *skbp;
+       struct sk_buff *tmp;
        u16 ns = PPPOL2TP_SKB_CB(skb)->ns;
 
-       spin_lock(&session->reorder_q.lock);
-       skb_queue_walk(&session->reorder_q, skbp) {
+       spin_lock_bh(&session->reorder_q.lock);
+       skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
                        __skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
                        PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
@@ -360,7 +361,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_
        __skb_queue_tail(&session->reorder_q, skb);
 
 out:
-       spin_unlock(&session->reorder_q.lock);
+       spin_unlock_bh(&session->reorder_q.lock);
 }
 
 /* Dequeue a single skb.
@@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s
        int length = PPPOL2TP_SKB_CB(skb)->length;
        struct sock *session_sock = NULL;
 
-       /* We're about to requeue the skb, so unlink it and return resources
+       /* We're about to requeue the skb, so return resources
         * to its current owner (a socket receive buffer).
         */
-       skb_unlink(skb, &session->reorder_q);
        skb_orphan(skb);
 
        tunnel->stats.rx_packets++;
@@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
         * expect to send up next, dequeue it and any other
         * in-sequence packets behind it.
         */
-       spin_lock(&session->reorder_q.lock);
+       spin_lock_bh(&session->reorder_q.lock);
        skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
                if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) {
                        session->stats.rx_seq_discards++;
@@ -470,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session)
                                goto out;
                        }
                }
-               spin_unlock(&session->reorder_q.lock);
+               __skb_unlink(skb, &session->reorder_q);
+
+               /* Process the skb. We release the queue lock while we
+                * do so to let other contexts process the queue.
+                */
+               spin_unlock_bh(&session->reorder_q.lock);
                pppol2tp_recv_dequeue_skb(session, skb);
-               spin_lock(&session->reorder_q.lock);
+               spin_lock_bh(&session->reorder_q.lock);
        }
 
 out:
-       spin_unlock(&session->reorder_q.lock);
+       spin_unlock_bh(&session->reorder_q.lock);
 }
 
 /* Internal receive frame. Do the real work of receiving an L2TP data frame
@@ -1059,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
 
        /* Get routing info from the tunnel socket */
        dst_release(skb->dst);
-       skb->dst = sk_dst_get(sk_tun);
+       skb->dst = dst_clone(__sk_dst_get(sk_tun));
        skb_orphan(skb);
        skb->sk = sk_tun;
 
@@ -1107,7 +1112,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
        PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
               "%s: closing all sessions...\n", tunnel->name);
 
-       write_lock(&tunnel->hlist_lock);
+       write_lock_bh(&tunnel->hlist_lock);
        for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) {
 again:
                hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {
@@ -1129,7 +1134,7 @@ again:
                         * disappear as we're jumping between locks.
                         */
                        sock_hold(sk);
-                       write_unlock(&tunnel->hlist_lock);
+                       write_unlock_bh(&tunnel->hlist_lock);
                        lock_sock(sk);
 
                        if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -1154,11 +1159,11 @@ again:
                         * list so we are guaranteed to make forward
                         * progress.
                         */
-                       write_lock(&tunnel->hlist_lock);
+                       write_lock_bh(&tunnel->hlist_lock);
                        goto again;
                }
        }
-       write_unlock(&tunnel->hlist_lock);
+       write_unlock_bh(&tunnel->hlist_lock);
 }
 
 /* Really kill the tunnel.
@@ -1167,9 +1172,9 @@ again:
 static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
 {
        /* Remove from socket list */
-       write_lock(&pppol2tp_tunnel_list_lock);
+       write_lock_bh(&pppol2tp_tunnel_list_lock);
        list_del_init(&tunnel->list);
-       write_unlock(&pppol2tp_tunnel_list_lock);
+       write_unlock_bh(&pppol2tp_tunnel_list_lock);
 
        atomic_dec(&pppol2tp_tunnel_count);
        kfree(tunnel);
@@ -1245,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk)
                                /* Delete the session socket from the
                                 * hash
                                 */
-                               write_lock(&tunnel->hlist_lock);
+                               write_lock_bh(&tunnel->hlist_lock);
                                hlist_del_init(&session->hlist);
-                               write_unlock(&tunnel->hlist_lock);
+                               write_unlock_bh(&tunnel->hlist_lock);
 
                                atomic_dec(&pppol2tp_session_count);
                        }
@@ -1392,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
 
        /* Add tunnel to our list */
        INIT_LIST_HEAD(&tunnel->list);
-       write_lock(&pppol2tp_tunnel_list_lock);
+       write_lock_bh(&pppol2tp_tunnel_list_lock);
        list_add(&tunnel->list, &pppol2tp_tunnel_list);
-       write_unlock(&pppol2tp_tunnel_list_lock);
+       write_unlock_bh(&pppol2tp_tunnel_list_lock);
        atomic_inc(&pppol2tp_tunnel_count);
 
        /* Bump the reference count. The tunnel context is deleted
@@ -1599,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
        sk->sk_user_data = session;
 
        /* Add session to the tunnel's hash list */
-       write_lock(&tunnel->hlist_lock);
+       write_lock_bh(&tunnel->hlist_lock);
        hlist_add_head(&session->hlist,
                       pppol2tp_session_id_hash(tunnel,
                                                session->tunnel_addr.s_session));
-       write_unlock(&tunnel->hlist_lock);
+       write_unlock_bh(&tunnel->hlist_lock);
 
        atomic_inc(&pppol2tp_session_count);
 
@@ -2205,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
        int next = 0;
        int i;
 
-       read_lock(&tunnel->hlist_lock);
+       read_lock_bh(&tunnel->hlist_lock);
        for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) {
                hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) {
                        if (curr == NULL) {
@@ -2223,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str
                }
        }
 out:
-       read_unlock(&tunnel->hlist_lock);
+       read_unlock_bh(&tunnel->hlist_lock);
        if (!found)
                session = NULL;
 
@@ -2234,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
 {
        struct pppol2tp_tunnel *tunnel = NULL;
 
-       read_lock(&pppol2tp_tunnel_list_lock);
+       read_lock_bh(&pppol2tp_tunnel_list_lock);
        if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
                goto out;
        }
        tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
 out:
-       read_unlock(&pppol2tp_tunnel_list_lock);
+       read_unlock_bh(&pppol2tp_tunnel_list_lock);
 
        return tunnel;
 }
index 6179a0a2032c0ec50681d8f02bb5a693baf6b8d4..c72787adeba33bbe31dbbc52d9559551226c1d81 100644 (file)
@@ -1088,7 +1088,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
  *  '-1' on failure
  */
 
-int init_tti(struct s2io_nic *nic, int link)
+static int init_tti(struct s2io_nic *nic, int link)
 {
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        register u64 val64 = 0;
index 77d9dd7ea34f647f77e04d1c30bc20257146de55..567c62757e9d154ec39b5083d1f0f4b28bcf18ad 100644 (file)
@@ -910,7 +910,8 @@ static void de_set_media (struct de_private *de)
        unsigned media = de->media_type;
        u32 macmode = dr32(MacMode);
 
-       BUG_ON(de_is_running(de));
+       if (de_is_running(de))
+               printk(KERN_WARNING "%s: chip is running while changing media!\n", de->dev->name);
 
        if (de->de21040)
                dw32(CSR11, FULL_DUPLEX_MAGIC);
index 15d5c58e57bcf5a170958afd69e9e57b960cc453..e59255a155a91e34719b11e70c9a471d4fd36e6d 100644 (file)
@@ -751,7 +751,7 @@ upload_data( struct net_device  *dev,  unsigned  framelen,  unsigned  frameno,
 }
 
 
-static __inline void
+static inline void
 send_complete( struct net_local  *nl )
 {
 #ifdef CONFIG_SBNI_MULTILINE
index bdc6a1cc21033f44f1c322e38d2c3a626ab31fc5..f0ef7081bdeba69c4213e32e529b0477149ee3aa 100644 (file)
@@ -578,7 +578,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
                goto done;
        }
        if (respcmd != CMD_RET(curcmd) &&
-           respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) {
+           respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
                lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
                spin_unlock_irqrestore(&priv->driver_lock, flags);
                ret = -1;
index e808db98f2f57b09c3815fb7cb07be91386b09eb..93ea212fedd51358f7e893688186895e7f858c58 100644 (file)
@@ -2302,9 +2302,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
+        * - Multicast filter seems to kill broadcast traffic so never use it.
         */
-       if (mc_count)
-               *total_flags |= FIF_ALLMULTI;
+       *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
index 4fac2d414d845401067120dbe72ea3af9a13f9c8..8103d41a1543d04461611fada2d53d684d873962 100644 (file)
@@ -1869,9 +1869,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
+        * - Multicast filter seems to kill broadcast traffic so never use it.
         */
-       if (mc_count)
-               *total_flags |= FIF_ALLMULTI;
+       *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
@@ -2098,6 +2098,7 @@ static struct usb_device_id rt73usb_device_table[] = {
        /* D-Link */
        { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Gemtek */
        { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Gigabyte */
index 91a1bd67ac1d6dd58da1d3db5c0691cdb7ea7525..9a4da0aae02e442e5be76fa84a0907a43e1bf848 100644 (file)
@@ -2269,6 +2269,9 @@ static const struct pid_entry tgid_base_stuff[] = {
        DIR("task",       S_IRUGO|S_IXUGO, task),
        DIR("fd",         S_IRUSR|S_IXUSR, fd),
        DIR("fdinfo",     S_IRUSR|S_IXUSR, fdinfo),
+#ifdef CONFIG_NET
+       DIR("net",        S_IRUGO|S_IXUSR, net),
+#endif
        REG("environ",    S_IRUSR, environ),
        INF("auxv",       S_IRUSR, pid_auxv),
        ONE("status",     S_IRUGO, pid_status),
index 68971e66cd41ca438f7dff0e6047322fca2b5d5f..a36ad3c75cf43bbc0cb9f34d550893d952316ac1 100644 (file)
@@ -377,15 +377,14 @@ static struct dentry_operations proc_dentry_operations =
  * Don't create negative dentries here, return -ENOENT by hand
  * instead.
  */
-struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
+struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
+               struct dentry *dentry)
 {
        struct inode *inode = NULL;
-       struct proc_dir_entry * de;
        int error = -ENOENT;
 
        lock_kernel();
        spin_lock(&proc_subdir_lock);
-       de = PDE(dir);
        if (de) {
                for (de = de->subdir; de ; de = de->next) {
                        if (de->namelen != dentry->d_name.len)
@@ -393,8 +392,6 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam
                        if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
                                unsigned int ino;
 
-                               if (de->shadow_proc)
-                                       de = de->shadow_proc(current, de);
                                ino = de->low_ino;
                                de_get(de);
                                spin_unlock(&proc_subdir_lock);
@@ -417,6 +414,12 @@ out_unlock:
        return ERR_PTR(error);
 }
 
+struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
+               struct nameidata *nd)
+{
+       return proc_lookup_de(PDE(dir), dir, dentry);
+}
+
 /*
  * This returns non-zero if at EOF, so that the /proc
  * root directory can use this and check if it should
@@ -426,10 +429,9 @@ out_unlock:
  * value of the readdir() call, as long as it's non-negative
  * for success..
  */
-int proc_readdir(struct file * filp,
-       void * dirent, filldir_t filldir)
+int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
+               filldir_t filldir)
 {
-       struct proc_dir_entry * de;
        unsigned int ino;
        int i;
        struct inode *inode = filp->f_path.dentry->d_inode;
@@ -438,7 +440,6 @@ int proc_readdir(struct file * filp,
        lock_kernel();
 
        ino = inode->i_ino;
-       de = PDE(inode);
        if (!de) {
                ret = -EINVAL;
                goto out;
@@ -499,6 +500,13 @@ out:       unlock_kernel();
        return ret;     
 }
 
+int proc_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+       struct inode *inode = filp->f_path.dentry->d_inode;
+
+       return proc_readdir_de(PDE(inode), filp, dirent, filldir);
+}
+
 /*
  * These are the generic /proc directory operations. They
  * use the in-memory "struct proc_dir_entry" tree to parse
index 1c81c8f1aeed411d05331e3bcd61c39e43343b4e..bc72f5c8c47d34704cb6a76ef450e1bd6dc84f0d 100644 (file)
@@ -64,6 +64,8 @@ extern const struct file_operations proc_numa_maps_operations;
 extern const struct file_operations proc_smaps_operations;
 extern const struct file_operations proc_clear_refs_operations;
 extern const struct file_operations proc_pagemap_operations;
+extern const struct file_operations proc_net_operations;
+extern const struct inode_operations proc_net_inode_operations;
 
 void free_proc_entry(struct proc_dir_entry *de);
 
@@ -83,3 +85,8 @@ static inline int proc_fd(struct inode *inode)
 {
        return PROC_I(inode)->fd;
 }
+
+struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino,
+               struct dentry *dentry);
+int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent,
+               filldir_t filldir);
index 14e9b5aaf863bce23d6ccb03aa582cb9b6a4c566..4caa5f774fb7975136d04e2baf81826e1c392dba 100644 (file)
@@ -63,6 +63,82 @@ int seq_release_net(struct inode *ino, struct file *f)
 }
 EXPORT_SYMBOL_GPL(seq_release_net);
 
+static struct net *get_proc_task_net(struct inode *dir)
+{
+       struct task_struct *task;
+       struct nsproxy *ns;
+       struct net *net = NULL;
+
+       rcu_read_lock();
+       task = pid_task(proc_pid(dir), PIDTYPE_PID);
+       if (task != NULL) {
+               ns = task_nsproxy(task);
+               if (ns != NULL)
+                       net = get_net(ns->net_ns);
+       }
+       rcu_read_unlock();
+
+       return net;
+}
+
+static struct dentry *proc_tgid_net_lookup(struct inode *dir,
+               struct dentry *dentry, struct nameidata *nd)
+{
+       struct dentry *de;
+       struct net *net;
+
+       de = ERR_PTR(-ENOENT);
+       net = get_proc_task_net(dir);
+       if (net != NULL) {
+               de = proc_lookup_de(net->proc_net, dir, dentry);
+               put_net(net);
+       }
+       return de;
+}
+
+static int proc_tgid_net_getattr(struct vfsmount *mnt, struct dentry *dentry,
+               struct kstat *stat)
+{
+       struct inode *inode = dentry->d_inode;
+       struct net *net;
+
+       net = get_proc_task_net(inode);
+
+       generic_fillattr(inode, stat);
+
+       if (net != NULL) {
+               stat->nlink = net->proc_net->nlink;
+               put_net(net);
+       }
+
+       return 0;
+}
+
+const struct inode_operations proc_net_inode_operations = {
+       .lookup         = proc_tgid_net_lookup,
+       .getattr        = proc_tgid_net_getattr,
+};
+
+static int proc_tgid_net_readdir(struct file *filp, void *dirent,
+               filldir_t filldir)
+{
+       int ret;
+       struct net *net;
+
+       ret = -EINVAL;
+       net = get_proc_task_net(filp->f_path.dentry->d_inode);
+       if (net != NULL) {
+               ret = proc_readdir_de(net->proc_net, filp, dirent, filldir);
+               put_net(net);
+       }
+       return ret;
+}
+
+const struct file_operations proc_net_operations = {
+       .read           = generic_read_dir,
+       .readdir        = proc_tgid_net_readdir,
+};
+
 
 struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops)
@@ -83,14 +159,6 @@ struct net *get_proc_net(const struct inode *inode)
 }
 EXPORT_SYMBOL_GPL(get_proc_net);
 
-static struct proc_dir_entry *shadow_pde;
-
-static struct proc_dir_entry *proc_net_shadow(struct task_struct *task,
-                                               struct proc_dir_entry *de)
-{
-       return task->nsproxy->net_ns->proc_net;
-}
-
 struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
                struct proc_dir_entry *parent)
 {
@@ -104,45 +172,39 @@ EXPORT_SYMBOL_GPL(proc_net_mkdir);
 
 static __net_init int proc_net_ns_init(struct net *net)
 {
-       struct proc_dir_entry *root, *netd, *net_statd;
+       struct proc_dir_entry *netd, *net_statd;
        int err;
 
        err = -ENOMEM;
-       root = kzalloc(sizeof(*root), GFP_KERNEL);
-       if (!root)
+       netd = kzalloc(sizeof(*netd), GFP_KERNEL);
+       if (!netd)
                goto out;
 
-       err = -EEXIST;
-       netd = proc_net_mkdir(net, "net", root);
-       if (!netd)
-               goto free_root;
+       netd->data = net;
+       netd->nlink = 2;
+       netd->name = "net";
+       netd->namelen = 3;
+       netd->parent = &proc_root;
 
        err = -EEXIST;
        net_statd = proc_net_mkdir(net, "stat", netd);
        if (!net_statd)
                goto free_net;
 
-       root->data = net;
-
-       net->proc_net_root = root;
        net->proc_net = netd;
        net->proc_net_stat = net_statd;
-       err = 0;
+       return 0;
 
+free_net:
+       kfree(netd);
 out:
        return err;
-free_net:
-       remove_proc_entry("net", root);
-free_root:
-       kfree(root);
-       goto out;
 }
 
 static __net_exit void proc_net_ns_exit(struct net *net)
 {
        remove_proc_entry("stat", net->proc_net);
-       remove_proc_entry("net", net->proc_net_root);
-       kfree(net->proc_net_root);
+       kfree(net->proc_net);
 }
 
 static struct pernet_operations __net_initdata proc_net_ns_ops = {
@@ -152,8 +214,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = {
 
 int __init proc_net_init(void)
 {
-       shadow_pde = proc_mkdir("net", NULL);
-       shadow_pde->shadow_proc = proc_net_shadow;
+       proc_symlink("net", NULL, "self/net");
 
        return register_pernet_subsys(&proc_net_ns_ops);
 }
index fcbe8b640ffba57f04a35c986728bf850717bb6c..c8d216357865dda3e22bd503df478055b3d888b9 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _LINUX_ETHTOOL_H
 #define _LINUX_ETHTOOL_H
 
+#include <linux/types.h>
 
 /* This should work for both 32 and 64 bit userland. */
 struct ethtool_cmd {
index 02a42d875cf74810305e87b3a9e222a088308ae9..e1451760c9cd3dfc991c707d2b4d90b7062b5fb2 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _NFNETLINK_COMPAT_H
 #define _NFNETLINK_COMPAT_H
-#ifndef __KERNEL
+#ifndef __KERNEL__
 /* Old nfnetlink macros for userspace */
 
 /* nfnetlink groups: Up to 32 maximum */
index d9a9e718ad19f84395ee9736c04ddedbd7e4acb0..9b6c935f69cf6d1986677b968bb17c2ca000e4b0 100644 (file)
@@ -50,8 +50,6 @@ typedef       int (read_proc_t)(char *page, char **start, off_t off,
 typedef        int (write_proc_t)(struct file *file, const char __user *buffer,
                           unsigned long count, void *data);
 typedef int (get_info_t)(char *, char **, off_t, int);
-typedef struct proc_dir_entry *(shadow_proc_t)(struct task_struct *task,
-                                               struct proc_dir_entry *pde);
 
 struct proc_dir_entry {
        unsigned int low_ino;
@@ -82,7 +80,6 @@ struct proc_dir_entry {
        int pde_users;  /* number of callers into module in progress */
        spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
        struct completion *pde_unload_completion;
-       shadow_proc_t *shadow_proc;
 };
 
 struct kcore_list {
index 771d17783c1889d7d89d7875bdfb28a350e9d4e7..750648df13f4785cee631985648966a602daf58b 100644 (file)
@@ -170,7 +170,7 @@ static inline int skb_frags_no(struct sk_buff *skb)
 int bt_err(__u16 code);
 
 extern int hci_sock_init(void);
-extern int hci_sock_cleanup(void);
+extern void hci_sock_cleanup(void);
 
 extern int bt_sysfs_init(void);
 extern void bt_sysfs_cleanup(void);
index 32c385dd9e06a94ab6cf77988537d02cc47835ad..0788c23d2828e222408050e7a2c84342d6a984cc 100644 (file)
@@ -169,17 +169,17 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb,
 void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow);
 struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance);
 
-static __inline __u32 irttp_get_saddr(struct tsap_cb *self)
+static inline __u32 irttp_get_saddr(struct tsap_cb *self)
 {
        return irlmp_get_saddr(self->lsap);
 }
 
-static __inline __u32 irttp_get_daddr(struct tsap_cb *self)
+static inline __u32 irttp_get_daddr(struct tsap_cb *self)
 {
        return irlmp_get_daddr(self->lsap);
 }
 
-static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self)
+static inline __u32 irttp_get_max_seg_size(struct tsap_cb *self)
 {
        return self->max_seg_size;
 }
index 28738b7d53eb2a0748cecad1076a9726da8d936f..923f2b8b909600b3962035f714308ddc5e8acf9d 100644 (file)
@@ -31,7 +31,6 @@ struct net {
 
        struct proc_dir_entry   *proc_net;
        struct proc_dir_entry   *proc_net_stat;
-       struct proc_dir_entry   *proc_net_root;
 
        struct list_head        sysctl_table_headers;
 
index 49aac6323fbeaf7c4dacbb16c8194d91246977bf..f736e842977f07ce8469bf832fcf2905af36ded1 100644 (file)
@@ -17,7 +17,6 @@ enum nf_ct_ext_id
 struct nf_ct_ext {
        u8 offset[NF_CT_EXT_NUM];
        u8 len;
-       u8 real_len;
        char data[0];
 };
 
index a2992280c3d1ee3a5b908faf793a18b6b4f16e5c..e69244dd8de850ceb4197aa8157a91011511f332 100644 (file)
@@ -174,7 +174,7 @@ struct bnep_session {
 
 void bnep_net_setup(struct net_device *dev);
 int bnep_sock_init(void);
-int bnep_sock_cleanup(void);
+void bnep_sock_cleanup(void);
 
 static inline int bnep_mc_hash(__u8 *addr)
 {
index 81065e548a1f50d4c4a37dd9c4c54f52726d7fdd..201e5b1ce473cd2066d2607a2d5af6f8555c2d6f 100644 (file)
@@ -257,12 +257,10 @@ error:
        return err;
 }
 
-int __exit bnep_sock_cleanup(void)
+void __exit bnep_sock_cleanup(void)
 {
        if (bt_sock_unregister(BTPROTO_BNEP) < 0)
                BT_ERR("Can't unregister BNEP socket");
 
        proto_unregister(&bnep_proto);
-
-       return 0;
 }
index 930b58e7149a77b4af84e4dd4674437b0bf31378..aec6929f5c166fd362df7e38faebb19f91f8a445 100644 (file)
@@ -902,8 +902,6 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-       hci_unregister_sysfs(hdev);
-
        write_lock_bh(&hci_dev_list_lock);
        list_del(&hdev->list);
        write_unlock_bh(&hci_dev_list_lock);
@@ -915,6 +913,8 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        hci_notify(hdev, HCI_DEV_UNREG);
 
+       hci_unregister_sysfs(hdev);
+
        __hci_dev_put(hdev);
 
        return 0;
index 14991323c273a15793823107e25d79af5403f58e..b5d4019d3572c59eefe328a22085645d6132b136 100644 (file)
@@ -734,7 +734,7 @@ error:
        return err;
 }
 
-int __exit hci_sock_cleanup(void)
+void __exit hci_sock_cleanup(void)
 {
        if (bt_sock_unregister(BTPROTO_HCI) < 0)
                BT_ERR("HCI socket unregistration failed");
@@ -742,6 +742,4 @@ int __exit hci_sock_cleanup(void)
        hci_unregister_notifier(&hci_sock_nblock);
 
        proto_unregister(&hci_sk_proto);
-
-       return 0;
 }
index ed750f9ceb07caed9ed5479740e664c6a319bc8f..01578f544ad604a5ee7270c426fee64872588b22 100644 (file)
@@ -1035,6 +1035,13 @@ static void tcp_cwnd_validate(struct sock *sk)
  * introducing MSS oddities to segment boundaries. In rare cases where
  * mss_now != mss_cache, we will request caller to create a small skb
  * per input skb which could be mostly avoided here (if desired).
+ *
+ * We explicitly want to create a request for splitting write queue tail
+ * to a small skb for Nagle purposes while avoiding unnecessary modulos,
+ * thus all the complexity (cwnd_len is always MSS multiple which we
+ * return whenever allowed by the other factors). Basically we need the
+ * modulo only when the receiver window alone is the limiting factor or
+ * when we would be allowed to send the split-due-to-Nagle skb fully.
  */
 static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb,
                                        unsigned int mss_now, unsigned int cwnd)
@@ -1048,10 +1055,11 @@ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb,
        if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
                return cwnd_len;
 
-       if (skb == tcp_write_queue_tail(sk) && cwnd_len <= skb->len)
+       needed = min(skb->len, window);
+
+       if (skb == tcp_write_queue_tail(sk) && cwnd_len <= needed)
                return cwnd_len;
 
-       needed = min(skb->len, window);
        return needed - needed % mss_now;
 }
 
index e06bf0028bb18eaea80e40fb633d4aac495a038f..684ec9c1ad38b7545502fd08213360bd2c7a9b0c 100644 (file)
@@ -381,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
        if (nf_ct_expect_count >= nf_ct_expect_max) {
                if (net_ratelimit())
                        printk(KERN_WARNING
-                              "nf_conntrack: expectation table full");
+                              "nf_conntrack: expectation table full\n");
                ret = -EMFILE;
                goto out;
        }
index 8b9be1e978cda3dc00c01050d69e495ac8c610ad..2bd9963b5b3ea4cf26d4abde679a72e8b28421a7 100644 (file)
 static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM];
 static DEFINE_MUTEX(nf_ct_ext_type_mutex);
 
-/* Horrible trick to figure out smallest amount worth kmallocing. */
-#define CACHE(x) (x) + 0 *
-enum {
-       NF_CT_EXT_MIN_SIZE =
-#include <linux/kmalloc_sizes.h>
-       1 };
-#undef CACHE
-
 void __nf_ct_ext_destroy(struct nf_conn *ct)
 {
        unsigned int i;
@@ -53,7 +45,7 @@ EXPORT_SYMBOL(__nf_ct_ext_destroy);
 static void *
 nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
 {
-       unsigned int off, len, real_len;
+       unsigned int off, len;
        struct nf_ct_ext_type *t;
 
        rcu_read_lock();
@@ -61,16 +53,14 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp)
        BUG_ON(t == NULL);
        off = ALIGN(sizeof(struct nf_ct_ext), t->align);
        len = off + t->len;
-       real_len = t->alloc_size;
        rcu_read_unlock();
 
-       *ext = kzalloc(real_len, gfp);
+       *ext = kzalloc(t->alloc_size, gfp);
        if (!*ext)
                return NULL;
 
        (*ext)->offset[id] = off;
        (*ext)->len = len;
-       (*ext)->real_len = real_len;
 
        return (void *)(*ext) + off;
 }
@@ -95,7 +85,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
        newlen = newoff + t->len;
        rcu_read_unlock();
 
-       if (newlen >= ct->ext->real_len) {
+       if (newlen >= ksize(ct->ext)) {
                new = kmalloc(newlen, gfp);
                if (!new)
                        return NULL;
@@ -114,7 +104,6 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp)
                        rcu_read_unlock();
                }
                kfree(ct->ext);
-               new->real_len = newlen;
                ct->ext = new;
        }
 
@@ -156,8 +145,6 @@ static void update_alloc_size(struct nf_ct_ext_type *type)
                        t1->alloc_size = ALIGN(t1->alloc_size, t2->align)
                                         + t2->len;
                }
-               if (t1->alloc_size < NF_CT_EXT_MIN_SIZE)
-                       t1->alloc_size = NF_CT_EXT_MIN_SIZE;
        }
 }
 
index bfc2928c19120f4c5994ae616066b1f030ba2a01..ddc80ea114cda13509f5828b2c8f5590a6d7f3e3 100644 (file)
@@ -51,7 +51,7 @@ int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh)
                return -EINVAL;
 
        mutex_lock(&queue_handler_mutex);
-       if (queue_handler[pf] != qh) {
+       if (queue_handler[pf] && queue_handler[pf] != qh) {
                mutex_unlock(&queue_handler_mutex);
                return -EINVAL;
        }
index 7efa40d47393727447fd1bdbf88d579914e5cfc4..bf3f19b21fe49eb0399ac66b09940bd085fb17ca 100644 (file)
@@ -556,7 +556,7 @@ nfulnl_log_packet(unsigned int pf,
        /* FIXME: do we want to make the size calculation conditional based on
         * what is actually present?  way more branches and checks, but more
         * memory efficient... */
-       size =    NLMSG_ALIGN(sizeof(struct nfgenmsg))
+       size =    NLMSG_SPACE(sizeof(struct nfgenmsg))
                + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
                + nla_total_size(sizeof(u_int32_t))     /* ifindex */
                + nla_total_size(sizeof(u_int32_t))     /* ifindex */
@@ -702,20 +702,30 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
        struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
        u_int16_t group_num = ntohs(nfmsg->res_id);
        struct nfulnl_instance *inst;
+       struct nfulnl_msg_config_cmd *cmd = NULL;
        int ret = 0;
 
+       if (nfula[NFULA_CFG_CMD]) {
+               u_int8_t pf = nfmsg->nfgen_family;
+               cmd = nla_data(nfula[NFULA_CFG_CMD]);
+
+               /* Commands without queue context */
+               switch (cmd->command) {
+               case NFULNL_CFG_CMD_PF_BIND:
+                       return nf_log_register(pf, &nfulnl_logger);
+               case NFULNL_CFG_CMD_PF_UNBIND:
+                       nf_log_unregister_pf(pf);
+                       return 0;
+               }
+       }
+
        inst = instance_lookup_get(group_num);
        if (inst && inst->peer_pid != NETLINK_CB(skb).pid) {
                ret = -EPERM;
                goto out_put;
        }
 
-       if (nfula[NFULA_CFG_CMD]) {
-               u_int8_t pf = nfmsg->nfgen_family;
-               struct nfulnl_msg_config_cmd *cmd;
-
-               cmd = nla_data(nfula[NFULA_CFG_CMD]);
-
+       if (cmd != NULL) {
                switch (cmd->command) {
                case NFULNL_CFG_CMD_BIND:
                        if (inst) {
@@ -738,14 +748,6 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
                        instance_destroy(inst);
                        goto out;
-               case NFULNL_CFG_CMD_PF_BIND:
-                       ret = nf_log_register(pf, &nfulnl_logger);
-                       break;
-               case NFULNL_CFG_CMD_PF_UNBIND:
-                       /* This is a bug and a feature.  We cannot unregister
-                        * other handlers, like nfnetlink_inst can */
-                       nf_log_unregister_pf(pf);
-                       break;
                default:
                        ret = -ENOTSUPP;
                        break;
index 0043d3a9f87eb5bbb477c96f64d99a60d6320e6a..012cb69108202c6ac1060847a7050a874e12931c 100644 (file)
@@ -224,7 +224,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
        struct net_device *indev;
        struct net_device *outdev;
 
-       size =    NLMSG_ALIGN(sizeof(struct nfgenmsg))
+       size =    NLMSG_SPACE(sizeof(struct nfgenmsg))
                + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
                + nla_total_size(sizeof(u_int32_t))     /* ifindex */
                + nla_total_size(sizeof(u_int32_t))     /* ifindex */
@@ -703,19 +703,12 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                /* Commands without queue context - might sleep */
                switch (cmd->command) {
                case NFQNL_CFG_CMD_PF_BIND:
-                       ret = nf_register_queue_handler(ntohs(cmd->pf),
-                                                       &nfqh);
-                       break;
+                       return nf_register_queue_handler(ntohs(cmd->pf),
+                                                        &nfqh);
                case NFQNL_CFG_CMD_PF_UNBIND:
-                       ret = nf_unregister_queue_handler(ntohs(cmd->pf),
-                                                         &nfqh);
-                       break;
-               default:
-                       break;
+                       return nf_unregister_queue_handler(ntohs(cmd->pf),
+                                                          &nfqh);
                }
-
-               if (ret < 0)
-                       return ret;
        }
 
        rcu_read_lock();
index e9a8794bc3ab6020c27cb6b73c24efd2b79201d1..9fa2e0824708f1acf62ab9c803a38eb4b4b2e408 100644 (file)
@@ -95,8 +95,11 @@ static inline void localtime_2(struct xtm *r, time_t time)
         */
        r->dse = time / 86400;
 
-       /* 1970-01-01 (w=0) was a Thursday (4). */
-       r->weekday = (4 + r->dse) % 7;
+       /*
+        * 1970-01-01 (w=0) was a Thursday (4).
+        * -1 and +1 map Sunday properly onto 7.
+        */
+       r->weekday = (4 + r->dse - 1) % 7 + 1;
 }
 
 static void localtime_3(struct xtm *r, time_t time)
index f19121d4795b25cbb687459741e318ce76091989..a39bf97f8830703cf1a6c5e23367727532e26efb 100644 (file)
@@ -143,7 +143,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
                /* copy the peer address and timestamp */
                if (!continue_call) {
                        if (msg->msg_name && msg->msg_namelen > 0)
-                               memcpy(&msg->msg_name, &call->conn->trans->peer->srx,
+                               memcpy(msg->msg_name,
+                                      &call->conn->trans->peer->srx,
                                       sizeof(call->conn->trans->peer->srx));
                        sock_recv_timestamp(msg, &rx->sk, skb);
                }
index a27511ebc4cb6ae80749a41c6b85239021749fee..ceefda025e2d3d31fbeb64e0b31d7866222c407f 100644 (file)
@@ -209,6 +209,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
 int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
 {
        struct sctp_sockaddr_entry *addr, *temp;
+       int found = 0;
 
        /* We hold the socket lock when calling this function,
         * and that acts as a writer synchronizing lock.
@@ -216,13 +217,14 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr)
        list_for_each_entry_safe(addr, temp, &bp->address_list, list) {
                if (sctp_cmp_addr_exact(&addr->a, del_addr)) {
                        /* Found the exact match. */
+                       found = 1;
                        addr->valid = 0;
                        list_del_rcu(&addr->list);
                        break;
                }
        }
 
-       if (addr && !addr->valid) {
+       if (found) {
                call_rcu(&addr->rcu, sctp_local_addr_free);
                SCTP_DBG_OBJCNT_DEC(addr);
                return 0;
index 87f940587d5fe8d3cd72ff33cf0a995498e4c093..9aa0733aee87b7379a1dbcfd27105331a3ceab53 100644 (file)
@@ -89,6 +89,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
        struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
        struct sctp_sockaddr_entry *addr = NULL;
        struct sctp_sockaddr_entry *temp;
+       int found = 0;
 
        switch (ev) {
        case NETDEV_UP:
@@ -111,13 +112,14 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
                                        &sctp_local_addr_list, list) {
                        if (ipv6_addr_equal(&addr->a.v6.sin6_addr,
                                             &ifa->addr)) {
+                               found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
                                break;
                        }
                }
                spin_unlock_bh(&sctp_local_addr_lock);
-               if (addr && !addr->valid)
+               if (found)
                        call_rcu(&addr->rcu, sctp_local_addr_free);
                break;
        }
index 688546dccd828f0821736a301535049cc3d8ca04..ad0a4069b95be0b78a3c54dc1f4b205d77cde3a2 100644 (file)
@@ -628,6 +628,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
        struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
        struct sctp_sockaddr_entry *addr = NULL;
        struct sctp_sockaddr_entry *temp;
+       int found = 0;
 
        switch (ev) {
        case NETDEV_UP:
@@ -647,13 +648,14 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
                list_for_each_entry_safe(addr, temp,
                                        &sctp_local_addr_list, list) {
                        if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) {
+                               found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
                                break;
                        }
                }
                spin_unlock_bh(&sctp_local_addr_lock);
-               if (addr && !addr->valid)
+               if (found)
                        call_rcu(&addr->rcu, sctp_local_addr_free);
                break;
        }
index e45be4e3f80d733c8f3eb27773651ad1a4d44add..578630e8e00d321a93565ee96c3a43b0d85acefa 100644 (file)
@@ -2375,6 +2375,14 @@ static int sctp_process_param(struct sctp_association *asoc,
                asoc->peer.ipv4_address = 0;
                asoc->peer.ipv6_address = 0;
 
+               /* Assume that peer supports the address family
+                * by which it sends a packet.
+                */
+               if (peer_addr->sa.sa_family == AF_INET6)
+                       asoc->peer.ipv6_address = 1;
+               else if (peer_addr->sa.sa_family == AF_INET)
+                       asoc->peer.ipv4_address = 1;
+
                /* Cycle through address types; avoid divide by 0. */
                sat = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
                if (sat)
index 939892691a260e46f5901581123c723c007d0f5c..d994d822900de2b9662fe70a846c35c44719ed0d 100644 (file)
@@ -2933,17 +2933,39 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
                                    char __user *optval,
                                    int optlen)
 {
+       struct sctp_assoc_value params;
+       struct sctp_sock *sp;
+       struct sctp_association *asoc;
        int val;
+       int assoc_id = 0;
 
-       if (optlen != sizeof(int))
+       if (optlen < sizeof(int))
                return -EINVAL;
-       if (get_user(val, (int __user *)optval))
-               return -EFAULT;
 
-       if (val < 0)
+       if (optlen == sizeof(int)) {
+               printk(KERN_WARNING
+                  "SCTP: Use of int in max_burst socket option deprecated\n");
+               printk(KERN_WARNING
+                  "SCTP: Use struct sctp_assoc_value instead\n");
+               if (copy_from_user(&val, optval, optlen))
+                       return -EFAULT;
+       } else if (optlen == sizeof(struct sctp_assoc_value)) {
+               if (copy_from_user(&params, optval, optlen))
+                       return -EFAULT;
+               val = params.assoc_value;
+               assoc_id = params.assoc_id;
+       } else
                return -EINVAL;
 
-       sctp_sk(sk)->max_burst = val;
+       sp = sctp_sk(sk);
+
+       if (assoc_id != 0) {
+               asoc = sctp_id2assoc(sk, assoc_id);
+               if (!asoc)
+                       return -EINVAL;
+               asoc->max_burst = val;
+       } else
+               sp->max_burst = val;
 
        return 0;
 }
@@ -5005,20 +5027,45 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
                                    char __user *optval,
                                    int __user *optlen)
 {
-       int val;
+       struct sctp_assoc_value params;
+       struct sctp_sock *sp;
+       struct sctp_association *asoc;
 
        if (len < sizeof(int))
                return -EINVAL;
 
-       len = sizeof(int);
+       if (len == sizeof(int)) {
+               printk(KERN_WARNING
+                  "SCTP: Use of int in max_burst socket option deprecated\n");
+               printk(KERN_WARNING
+                  "SCTP: Use struct sctp_assoc_value instead\n");
+               params.assoc_id = 0;
+       } else if (len == sizeof (struct sctp_assoc_value)) {
+               if (copy_from_user(&params, optval, len))
+                       return -EFAULT;
+       } else
+               return -EINVAL;
 
-       val = sctp_sk(sk)->max_burst;
-       if (put_user(len, optlen))
-               return -EFAULT;
-       if (copy_to_user(optval, &val, len))
-               return -EFAULT;
+       sp = sctp_sk(sk);
+
+       if (params.assoc_id != 0) {
+               asoc = sctp_id2assoc(sk, params.assoc_id);
+               if (!asoc)
+                       return -EINVAL;
+               params.assoc_value = asoc->max_burst;
+       } else
+               params.assoc_value = sp->max_burst;
+
+       if (len == sizeof(int)) {
+               if (copy_to_user(optval, &params.assoc_value, len))
+                       return -EFAULT;
+       } else {
+               if (copy_to_user(optval, &params, len))
+                       return -EFAULT;
+       }
+
+       return 0;
 
-       return -ENOTSUPP;
 }
 
 static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,