]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvar...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 23:23:53 +0000 (15:23 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 23:23:53 +0000 (15:23 -0800)
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c: Encourage move to dev_pm_ops by warning on use of legacy methods
  i2c: Factor out runtime suspend checks from PM operations
  i2c: Unregister dummy devices last on adapter removal

127 files changed:
Documentation/DocBook/80211.tmpl
Documentation/filesystems/Locking
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-igep0030.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clockdomain.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/mux34xx.c
arch/arm/mach-omap2/mux44xx.c
arch/arm/mach-omap2/omap_twl.c
arch/arm/mach-omap2/pm_bus.c
arch/arm/mach-omap2/prm2xxx_3xxx.h
arch/arm/mach-omap2/sr_device.c
arch/arm/mach-omap2/wd_timer.c
arch/arm/mm/Kconfig
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/plat/voltage.h
arch/ia64/include/asm/page.h
block/cfq-iosched.c
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/utmutex.c
drivers/md/dm-table.c
drivers/md/md.c
drivers/net/arm/ks8695net.c
drivers/net/bfin_mac.c
drivers/net/bna/bnad_ethtool.c
drivers/net/cassini.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/Makefile
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/es2lan.c
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/lib.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/param.c
drivers/net/e1000e/phy.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/greth.c
drivers/net/greth.h
drivers/net/ixgbe/ixgbe_main.c
drivers/net/macvtap.c
drivers/net/r8169.c
drivers/net/sfc/efx.c
drivers/net/sfc/net_driver.h
drivers/net/tile/tilepro.c
drivers/net/ucc_geth.c
drivers/net/usb/cdc_ncm.c
drivers/net/vxge/vxge-main.c
drivers/net/wireless/ath/ath9k/ar9002_calib.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/p54/txrx.c
drivers/ssb/scan.c
drivers/vhost/vhost.c
fs/block_dev.c
fs/dcache.c
fs/locks.c
fs/nfsd/acl.h [moved from include/linux/nfs4_acl.h with 98% similarity]
fs/nfsd/export.c
fs/nfsd/idmap.h [moved from include/linux/nfsd_idmap.h with 92% similarity]
fs/nfsd/nfs3proc.c
fs/nfsd/nfs4acl.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4idmap.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nfsd/xdr4.h
include/linux/etherdevice.h
include/linux/fs.h
include/linux/netdevice.h
include/linux/nfs4.h
include/linux/nfsd/export.h
include/linux/nl80211.h
include/linux/pci.h
include/linux/skbuff.h
include/linux/sunrpc/cache.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svc_xprt.h
include/linux/sunrpc/svcsock.h
include/linux/sunrpc/xprt.h
include/net/ah.h
include/net/cfg80211.h
include/net/mac80211.h
include/net/netfilter/ipv6/nf_conntrack_ipv6.h
include/net/netfilter/ipv6/nf_defrag_ipv6.h
include/net/red.h
net/ax25/af_ax25.c
net/core/dev.c
net/core/skbuff.c
net/ethernet/eth.c
net/ipv6/ip6_output.c
net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
net/netfilter/nf_conntrack_netlink.c
net/sched/sch_teql.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/svc.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcauth.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c

index 03641a08e2753416fb3d32362771c9fed7ca7ed4..8906648f962b137fdd6ffb811a2c4059d034910b 100644 (file)
 !Finclude/net/mac80211.h ieee80211_ops
 !Finclude/net/mac80211.h ieee80211_alloc_hw
 !Finclude/net/mac80211.h ieee80211_register_hw
-!Finclude/net/mac80211.h ieee80211_get_tx_led_name
-!Finclude/net/mac80211.h ieee80211_get_rx_led_name
-!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
-!Finclude/net/mac80211.h ieee80211_get_radio_led_name
 !Finclude/net/mac80211.h ieee80211_unregister_hw
 !Finclude/net/mac80211.h ieee80211_free_hw
       </chapter>
         </para>
       </partintro>
 
+      <chapter id="led-support">
+        <title>LED support</title>
+        <para>
+         Mac80211 supports various ways of blinking LEDs. Wherever possible,
+         device LEDs should be exposed as LED class devices and hooked up to
+         the appropriate trigger, which will then be triggered appropriately
+         by mac80211.
+        </para>
+!Finclude/net/mac80211.h ieee80211_get_tx_led_name
+!Finclude/net/mac80211.h ieee80211_get_rx_led_name
+!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
+!Finclude/net/mac80211.h ieee80211_get_radio_led_name
+!Finclude/net/mac80211.h ieee80211_tpt_blink
+!Finclude/net/mac80211.h ieee80211_tpt_led_trigger_flags
+!Finclude/net/mac80211.h ieee80211_create_tpt_led_trigger
+      </chapter>
+
       <chapter id="hardware-crypto-offload">
         <title>Hardware crypto acceleration</title>
 !Pinclude/net/mac80211.h Hardware crypto acceleration
index 977d8919cc69c80e9dd3f0e4a4e5327bac608376..ef9349a4b5d1ae9a4bc47eaedce49d3ed071c319 100644 (file)
@@ -343,7 +343,6 @@ prototypes:
        int (*fl_grant)(struct file_lock *, struct file_lock *, int);
        void (*fl_release_private)(struct file_lock *);
        void (*fl_break)(struct file_lock *); /* break_lease callback */
-       int (*fl_mylease)(struct file_lock *, struct file_lock *);
        int (*fl_change)(struct file_lock **, int);
 
 locking rules:
@@ -353,7 +352,6 @@ fl_notify:          yes             no
 fl_grant:              no              no
 fl_release_private:    maybe           no
 fl_break:              yes             no
-fl_mylease:            yes             no
 fl_change              yes             no
 
 --------------------------- buffer_head -----------------------------------
index a70bdf28e2bc2d718666f26a54338a7a147f25cc..07d1b20b11486a6c4c8629e654474e4dd7e5cb56 100644 (file)
@@ -554,6 +554,7 @@ static void __init omap_sfh7741prox_init(void)
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
@@ -576,11 +577,12 @@ static void __init omap_4430sdp_init(void)
        omap4_twl6030_hsmmc_init(mmc);
 
        /* Power on the ULPI PHY */
-       if (gpio_is_valid(OMAP4SDP_MDM_PWR_EN_GPIO)) {
-               /* FIXME: Assumes pad is already muxed for GPIO mode */
-               gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3");
+       status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3");
+       if (status)
+               pr_err("%s: Could not get USBB1 PHY GPIO\n", __func__);
+       else
                gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1);
-       }
+
        usb_ehci_init(&ehci_pdata);
        usb_musb_init(&musb_board_data);
 
index ebaa230e67ed909658238f44483b668ad5d1358b..3be85a1f55f4d7ab5d1a9ca11f6bbc6292ef647d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
+#include <linux/input.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/regulator/fixed.h>
@@ -541,6 +542,37 @@ static struct twl4030_codec_data igep2_codec_data = {
        .audio = &igep2_audio_data,
 };
 
+static int igep2_keymap[] = {
+       KEY(0, 0, KEY_LEFT),
+       KEY(0, 1, KEY_RIGHT),
+       KEY(0, 2, KEY_A),
+       KEY(0, 3, KEY_B),
+       KEY(1, 0, KEY_DOWN),
+       KEY(1, 1, KEY_UP),
+       KEY(1, 2, KEY_E),
+       KEY(1, 3, KEY_F),
+       KEY(2, 0, KEY_ENTER),
+       KEY(2, 1, KEY_I),
+       KEY(2, 2, KEY_J),
+       KEY(2, 3, KEY_K),
+       KEY(3, 0, KEY_M),
+       KEY(3, 1, KEY_N),
+       KEY(3, 2, KEY_O),
+       KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data igep2_keymap_data = {
+       .keymap                 = igep2_keymap,
+       .keymap_size            = ARRAY_SIZE(igep2_keymap),
+};
+
+static struct twl4030_keypad_data igep2_keypad_pdata = {
+       .keymap_data    = &igep2_keymap_data,
+       .rows           = 4,
+       .cols           = 4,
+       .rep            = 1,
+};
+
 static struct twl4030_platform_data igep2_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
@@ -549,6 +581,7 @@ static struct twl4030_platform_data igep2_twldata = {
        .usb            = &igep2_usb_data,
        .codec          = &igep2_codec_data,
        .gpio           = &igep2_twl4030_gpio_pdata,
+       .keypad         = &igep2_keypad_pdata,
        .vmmc1          = &igep2_vmmc1,
        .vpll2          = &igep2_vpll2,
        .vio            = &igep2_vio,
index bcccd68f185685652a24e34718e2a8ca7b065dd1..4dc62a9b9cb24811fae3f0c1fc1149f31e7e0f34 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/interrupt.h>
 
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
 #include <linux/i2c/twl.h>
 #include <linux/mmc/host.h>
 
@@ -43,7 +44,7 @@
 #define IGEP3_GPIO_WIFI_NRESET 139
 #define IGEP3_GPIO_BT_NRESET   137
 
-#define IGEP3_GPIO_USBH_NRESET  115
+#define IGEP3_GPIO_USBH_NRESET  183
 
 
 #if defined(CONFIG_MTD_ONENAND_OMAP2) || \
@@ -103,7 +104,7 @@ static struct platform_device igep3_onenand_device = {
        },
 };
 
-void __init igep3_flash_init(void)
+static void __init igep3_flash_init(void)
 {
        u8 cs = 0;
        u8 onenandcs = GPMC_CS_NUM + 1;
@@ -137,12 +138,11 @@ void __init igep3_flash_init(void)
 }
 
 #else
-void __init igep3_flash_init(void) {}
+static void __init igep3_flash_init(void) {}
 #endif
 
-static struct regulator_consumer_supply igep3_vmmc1_supply = {
-       .supply         = "vmmc",
-};
+static struct regulator_consumer_supply igep3_vmmc1_supply =
+       REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0");
 
 /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
 static struct regulator_init_data igep3_vmmc1 = {
@@ -159,6 +159,52 @@ static struct regulator_init_data igep3_vmmc1 = {
        .consumer_supplies      = &igep3_vmmc1_supply,
 };
 
+static struct regulator_consumer_supply igep3_vio_supply =
+       REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1");
+
+static struct regulator_init_data igep3_vio = {
+       .constraints = {
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .apply_uV               = 1,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &igep3_vio_supply,
+};
+
+static struct regulator_consumer_supply igep3_vmmc2_supply =
+       REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
+
+static struct regulator_init_data igep3_vmmc2 = {
+       .constraints    = {
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL,
+               .always_on              = 1,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &igep3_vmmc2_supply,
+};
+
+static struct fixed_voltage_config igep3_vwlan = {
+       .supply_name            = "vwlan",
+       .microvolts             = 3300000,
+       .gpio                   = -EINVAL,
+       .enabled_at_boot        = 1,
+       .init_data              = &igep3_vmmc2,
+};
+
+static struct platform_device igep3_vwlan_device = {
+       .name   = "reg-fixed-voltage",
+       .id     = 0,
+       .dev    = {
+               .platform_data = &igep3_vwlan,
+       },
+};
+
 static struct omap2_hsmmc_info mmc[] = {
        [0] = {
                .mmc            = 1,
@@ -254,12 +300,6 @@ static int igep3_twl4030_gpio_setup(struct device *dev,
        mmc[0].gpio_cd = gpio + 0;
        omap2_hsmmc_init(mmc);
 
-       /*
-        * link regulators to MMC adapters ... we "know" the
-        * regulators will be set up only *after* we return.
-        */
-       igep3_vmmc1_supply.dev = mmc[0].dev;
-
        /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
        if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
@@ -287,6 +327,10 @@ static struct twl4030_usb_data igep3_twl4030_usb_data = {
        .usb_mode       = T2_USB_MODE_ULPI,
 };
 
+static struct platform_device *igep3_devices[] __initdata = {
+       &igep3_vwlan_device,
+};
+
 static void __init igep3_init_irq(void)
 {
        omap2_init_common_infrastructure();
@@ -303,6 +347,7 @@ static struct twl4030_platform_data igep3_twl4030_pdata = {
        .usb            = &igep3_twl4030_usb_data,
        .gpio           = &igep3_twl4030_gpio_pdata,
        .vmmc1          = &igep3_vmmc1,
+       .vio            = &igep3_vio,
 };
 
 static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = {
@@ -363,8 +408,20 @@ static void __init igep3_wifi_bt_init(void)
 void __init igep3_wifi_bt_init(void) {}
 #endif
 
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+       .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+       .phy_reset = true,
+       .reset_gpio_port[0] = -EINVAL,
+       .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
+       .reset_gpio_port[2] = -EINVAL,
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #endif
@@ -375,9 +432,10 @@ static void __init igep3_init(void)
 
        /* Register I2C busses and drivers */
        igep3_i2c_init();
-
+       platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices));
        omap_serial_init();
        usb_musb_init(&musb_board_data);
+       usb_ehci_init(&ehci_pdata);
 
        igep3_flash_init();
        igep3_leds_init();
@@ -392,6 +450,7 @@ static void __init igep3_init(void)
 
 MACHINE_START(IGEP0030, "IGEP OMAP3 module")
        .boot_params    = 0x80000100,
+       .reserve        = omap_reserve,
        .map_io         = omap3_map_io,
        .init_irq       = igep3_init_irq,
        .init_machine   = igep3_init,
index a4fe8e1ee1bd6ae379c8875f48b6b71832069fa0..46d814ab5656c078e6fad0a013c2ce8c39e312e5 100644 (file)
@@ -207,7 +207,7 @@ static struct omap_dss_device beagle_dvi_device = {
        .driver_name = "generic_dpi_panel",
        .data = &dvi_panel,
        .phy.dpi.data_lines = 24,
-       .reset_gpio = 170,
+       .reset_gpio = -EINVAL,
 };
 
 static struct omap_dss_device beagle_tv_device = {
@@ -279,6 +279,8 @@ static struct gpio_led gpio_leds[];
 static int beagle_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
+       int r;
+
        if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
                mmc[0].gpio_wp = -EINVAL;
        } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
@@ -299,17 +301,63 @@ static int beagle_twl_gpio_setup(struct device *dev,
        /* REVISIT: need ehci-omap hooks for external VBUS
         * power switch and overcurrent detect
         */
+       if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
+               r = gpio_request(gpio + 1, "EHCI_nOC");
+               if (!r) {
+                       r = gpio_direction_input(gpio + 1);
+                       if (r)
+                               gpio_free(gpio + 1);
+               }
+               if (r)
+                       pr_err("%s: unable to configure EHCI_nOC\n", __func__);
+       }
 
-       gpio_request(gpio + 1, "EHCI_nOC");
-       gpio_direction_input(gpio + 1);
-
-       /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+       /*
+        * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
+        * high / others active low)
+        */
        gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
-       gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+       if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+               gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
+       else
+               gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+
+       /* DVI reset GPIO is different between beagle revisions */
+       if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
+               beagle_dvi_device.reset_gpio = 129;
+       else
+               beagle_dvi_device.reset_gpio = 170;
 
        /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
 
+       /*
+        * gpio + 1 on Xm controls the TFP410's enable line (active low)
+        * gpio + 2 control varies depending on the board rev as follows:
+        * P7/P8 revisions(prototype): Camera EN
+        * A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
+        */
+       if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+               r = gpio_request(gpio + 1, "nDVI_PWR_EN");
+               if (!r) {
+                       r = gpio_direction_output(gpio + 1, 0);
+                       if (r)
+                               gpio_free(gpio + 1);
+               }
+               if (r)
+                       pr_err("%s: unable to configure nDVI_PWR_EN\n",
+                               __func__);
+               r = gpio_request(gpio + 2, "DVI_LDO_EN");
+               if (!r) {
+                       r = gpio_direction_output(gpio + 2, 1);
+                       if (r)
+                               gpio_free(gpio + 2);
+               }
+               if (r)
+                       pr_err("%s: unable to configure DVI_LDO_EN\n",
+                               __func__);
+       }
+
        return 0;
 }
 
index 3094e20078448d0b010bca36cfe750c3b2216230..e001a048dc0c8a5b20bc916b675f2b6a81e8c6e9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
@@ -95,7 +96,16 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 static void __init omap4_ehci_init(void)
 {
        int ret;
+       struct clk *phy_ref_clk;
 
+       /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
+       phy_ref_clk = clk_get(NULL, "auxclk3_ck");
+       if (IS_ERR(phy_ref_clk)) {
+               pr_err("Cannot request auxclk3\n");
+               goto error1;
+       }
+       clk_set_rate(phy_ref_clk, 19200000);
+       clk_enable(phy_ref_clk);
 
        /* disable the power to the usb hub prior to init */
        ret = gpio_request(GPIO_HUB_POWER, "hub_power");
index 14d95afa3f0d8d73654b952bfde399fa79160c28..e0e040f34c68f7652e4d2c9e302fa2945f5f08e1 100644 (file)
@@ -192,7 +192,7 @@ static struct platform_device omap_vwlan_device = {
        },
 };
 
-struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
        .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
        /* ZOOM ref clock is 26 MHz */
        .board_ref_clock = 1,
@@ -286,7 +286,7 @@ static int zoom_twl_gpio_setup(struct device *dev,
 }
 
 /* EXTMUTE callback function */
-void zoom2_set_hs_extmute(int mute)
+static void zoom2_set_hs_extmute(int mute)
 {
        gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
 }
index d3ab1c9e50b0ebc86571ea62512c1d56a97b901b..403a4a1d3f9c4d0e4362cd768c2781dc32329ec1 100644 (file)
@@ -3286,7 +3286,7 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "cpefuse_fck",  &cpefuse_fck,   CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK(NULL,       "ts_fck",       &ts_fck,        CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK(NULL,       "usbtll_fck",   &usbtll_fck,    CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
-       CLK("ehci-omap.0",      "usbtll_fck",   &usbtll_fck,    CK_3430ES2 | CK_AM35XX),
+       CLK("ehci-omap.0",      "usbtll_fck",   &usbtll_fck,    CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
        CLK("omap-mcbsp.1",     "prcm_fck",     &core_96m_fck,  CK_3XXX),
        CLK("omap-mcbsp.5",     "prcm_fck",     &core_96m_fck,  CK_3XXX),
        CLK(NULL,       "core_96m_fck", &core_96m_fck,  CK_3XXX),
index de3faa20b46b658eb53daa4d7af90388ad6a5d58..9b459c26fb852d14033e17a0f6b7653a7bad2ccf 100644 (file)
@@ -103,9 +103,7 @@ struct clockdomain {
                const char *name;
                struct powerdomain *ptr;
        } pwrdm;
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
        const u16 clktrctrl_mask;
-#endif
        const u8 flags;
        const u8 dep_bit;
        const u8 prcm_partition;
index 381f4eb923520f125f48bf4420139b9c13a2e502..2c9c912f2c424014d11d8fb53aa5e8eb9ef1afb8 100644 (file)
@@ -978,7 +978,7 @@ static int __init omap2_init_devices(void)
 arch_initcall(omap2_init_devices);
 
 #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
-struct omap_device_pm_latency omap_wdt_latency[] = {
+static struct omap_device_pm_latency omap_wdt_latency[] = {
        [0] = {
                .deactivate_func = omap_device_idle_hwmods,
                .activate_func   = omap_device_enable_hwmods,
index 17bd6394d22453e1fb83a35cade10c4e1ad29ef8..df8d2f2872c6edce5e8d72a2ac668c7f10ebe336 100644 (file)
@@ -893,7 +893,7 @@ static struct omap_mux * __init omap_mux_list_add(
                return NULL;
 
        m = &entry->mux;
-       memcpy(m, src, sizeof(struct omap_mux_entry));
+       entry->mux = *src;
 
 #ifdef CONFIG_OMAP_MUX
        if (omap_mux_copy_names(src, m)) {
index 440c98e9a510950b0c43a0fc878c21950836f183..17f80e4ab162e4f2d4f15f8d99ccfa03496e225b 100644 (file)
@@ -703,7 +703,7 @@ static struct omap_mux __initdata omap3_muxmodes[] = {
  * Signals different on CBC package compared to the superset
  */
 #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC)
-struct omap_mux __initdata omap3_cbc_subset[] = {
+static struct omap_mux __initdata omap3_cbc_subset[] = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
@@ -721,7 +721,7 @@ struct omap_mux __initdata omap3_cbc_subset[] = {
  */
 #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)       \
                && defined(CONFIG_OMAP_PACKAGE_CBC)
-struct omap_ball __initdata omap3_cbc_ball[] = {
+static struct omap_ball __initdata omap3_cbc_ball[] = {
        _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL),
        _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL),
        _OMAP3_BALLENTRY(CAM_D10, "d25", NULL),
index 980f11d45c79adc4fbbc4cb2d670a443dad935fb..c322e7bdaa17f39f79b3be91f9ce0a4fdbb65538 100644 (file)
@@ -544,7 +544,7 @@ static struct omap_mux __initdata omap4_core_muxmodes[] = {
  */
 #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)               \
                && defined(CONFIG_OMAP_PACKAGE_CBL)
-struct omap_ball __initdata omap4_core_cbl_ball[] = {
+static struct omap_ball __initdata omap4_core_cbl_ball[] = {
        _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
        _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
        _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
@@ -1262,7 +1262,7 @@ static struct omap_mux __initdata omap4_es2_core_muxmodes[] = {
  */
 #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)               \
                && defined(CONFIG_OMAP_PACKAGE_CBS)
-struct omap_ball __initdata omap4_core_cbs_ball[] = {
+static struct omap_ball __initdata omap4_core_cbs_ball[] = {
        _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
        _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
        _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
@@ -1546,7 +1546,7 @@ static struct omap_mux __initdata omap4_wkup_muxmodes[] = {
  */
 #if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS)               \
                && defined(CONFIG_OMAP_PACKAGE_CBL)
-struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
+static struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
        _OMAP4_BALLENTRY(SIM_IO, "h4", NULL),
        _OMAP4_BALLENTRY(SIM_CLK, "j2", NULL),
        _OMAP4_BALLENTRY(SIM_RESET, "g2", NULL),
index 15f8c6c1bb0f61cc496304a689cebb72c5a4f5ec..00e1d2b53683373928c6dd33509393ce7e0dcace 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <plat/voltage.h>
 
+#include "pm.h"
+
 #define OMAP3_SRI2C_SLAVE_ADDR         0x12
 #define OMAP3_VDD_MPU_SR_CONTROL_REG   0x00
 #define OMAP3_VDD_CORE_SR_CONTROL_REG  0x01
@@ -60,17 +62,17 @@ static u8 smps_offset;
 
 #define REG_SMPS_OFFSET         0xE0
 
-unsigned long twl4030_vsel_to_uv(const u8 vsel)
+static unsigned long twl4030_vsel_to_uv(const u8 vsel)
 {
        return (((vsel * 125) + 6000)) * 100;
 }
 
-u8 twl4030_uv_to_vsel(unsigned long uv)
+static u8 twl4030_uv_to_vsel(unsigned long uv)
 {
        return DIV_ROUND_UP(uv - 600000, 12500);
 }
 
-unsigned long twl6030_vsel_to_uv(const u8 vsel)
+static unsigned long twl6030_vsel_to_uv(const u8 vsel)
 {
        /*
         * In TWL6030 depending on the value of SMPS_OFFSET
@@ -102,7 +104,7 @@ unsigned long twl6030_vsel_to_uv(const u8 vsel)
                return ((((vsel - 1) * 125) + 6000)) * 100;
 }
 
-u8 twl6030_uv_to_vsel(unsigned long uv)
+static u8 twl6030_uv_to_vsel(unsigned long uv)
 {
        /*
         * In TWL6030 depending on the value of SMPS_OFFSET
index 784989f8f2f5ef79c65b1cec3c5b4cda84d16a07..5acd2ab298b107786bb57433f608f487884377b6 100644 (file)
@@ -20,7 +20,7 @@
 #include <plat/omap-pm.h>
 
 #ifdef CONFIG_PM_RUNTIME
-int omap_pm_runtime_suspend(struct device *dev)
+static int omap_pm_runtime_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        int r, ret = 0;
@@ -37,7 +37,7 @@ int omap_pm_runtime_suspend(struct device *dev)
        return ret;
 };
 
-int omap_pm_runtime_resume(struct device *dev)
+static int omap_pm_runtime_resume(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
        int r;
index 53d44f6e37366a4d9a4a4b550b7b24dd42084845..49654c8d18f53880c4107722aa90f2f3833d9ea8 100644 (file)
 
 
 #ifndef __ASSEMBLER__
-
+/*
+ * Stub omap2xxx/omap3xxx functions so that common files
+ * continue to build when custom builds are used
+ */
+#if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) ||      \
+                                       defined(CONFIG_ARCH_OMAP3))
+static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+}
+static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
+               s16 module, s16 idx)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift)
+{
+       WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+               "not suppose to be used on omap4\n");
+       return 0;
+}
+#else
 /* Power/reset management domain register get/set */
 extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
 extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
@@ -242,6 +302,7 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
 extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
 extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 shift);
 
+#endif /* CONFIG_ARCH_OMAP4 */
 #endif
 
 /*
index 786d685c09a92a7f91a5cd51669e2de71ce782bc..b1e0af18a26a06a6e75924d6cfc5dbcabadf8d8c 100644 (file)
@@ -27,6 +27,7 @@
 #include <plat/voltage.h>
 
 #include "control.h"
+#include "pm.h"
 
 static bool sr_enable_on_init;
 
index b0c4907ab3caa216b8cdfd37a9f35f50ac2eab48..4067669d96c47433889da4e92124426bee89bcaa 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <plat/omap_hwmod.h>
 
+#include "wd_timer.h"
+
 /*
  * In order to avoid any assumptions from bootloader regarding WDT
  * settings, WDT module is reset during init. This enables the watchdog
index fcc1e628e050471d7bfde79e772075dbb0735b97..9d30c6f804b9de6454c9dc7b8bb16974ed487a16 100644 (file)
@@ -644,7 +644,7 @@ config ARM_THUMBEE
 
 config SWP_EMULATE
        bool "Emulate SWP/SWPB instructions"
-       depends on CPU_V7
+       depends on CPU_V7 && !CPU_V6
        select HAVE_PROC_CPU if PROC_FS
        default y if SMP
        help
index 1f98e0b948478dc92abccc71580c66b02223e73e..ccf2660f4151718a01562213753f4d652c6bbff1 100644 (file)
@@ -718,7 +718,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_GPIO_24XX:
        case METHOD_GPIO_44XX:
                set_24xx_gpio_triggering(bank, gpio, trigger);
-               break;
+               return 0;
 #endif
        default:
                goto bad;
@@ -756,8 +756,10 @@ static int gpio_irq_type(unsigned irq, unsigned type)
        spin_lock_irqsave(&bank->lock, flags);
        retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
        if (retval == 0) {
-               irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
-               irq_desc[irq].status |= type;
+               struct irq_desc *d = irq_to_desc(irq);
+
+               d->status &= ~IRQ_TYPE_SENSE_MASK;
+               d->status |= type;
        }
        spin_unlock_irqrestore(&bank->lock, flags);
 
@@ -1671,7 +1673,9 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
 
        for (j = bank->virtual_irq_start;
                     j < bank->virtual_irq_start + bank_width; j++) {
-               lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class);
+               struct irq_desc *d = irq_to_desc(j);
+
+               lockdep_set_class(&d->lock, &gpio_lock_class);
                set_irq_chip_data(j, bank);
                if (bank_is_mpuio(bank))
                        set_irq_chip(j, &mpuio_irq_chip);
index 0ff123399f3b6576f631646bb3fd8320087c7c85..5bd204e55c32552e21d9093a07c34ce7d17b39dc 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
 #define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
 
+#include <linux/err.h>
+
 #define VOLTSCALE_VPFORCEUPDATE                1
 #define VOLTSCALE_VCBYPASS             2
 
@@ -65,9 +67,6 @@ struct voltagedomain {
        char *name;
 };
 
-/* API to get the voltagedomain pointer */
-struct voltagedomain *omap_voltage_domain_lookup(char *name);
-
 /**
  * struct omap_volt_data - Omap voltage specific data.
  * @voltage_nominal:   The possible voltage value in uV
@@ -131,16 +130,26 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
                struct omap_volt_pmic_info *pmic_info);
 void omap_change_voltscale_method(struct voltagedomain *voltdm,
                int voltscale_method);
+/* API to get the voltagedomain pointer */
+struct voltagedomain *omap_voltage_domain_lookup(char *name);
+
 int omap_voltage_late_init(void);
 #else
 static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
-               struct omap_volt_pmic_info *pmic_info) {}
+               struct omap_volt_pmic_info *pmic_info)
+{
+       return -EINVAL;
+}
 static inline  void omap_change_voltscale_method(struct voltagedomain *voltdm,
                int voltscale_method) {}
 static inline int omap_voltage_late_init(void)
 {
        return -EINVAL;
 }
+static inline struct voltagedomain *omap_voltage_domain_lookup(char *name)
+{
+       return ERR_PTR(-EINVAL);
+}
 #endif
 
 #endif
index 41b6d31110fd697384dfacd959213f8792d23209..961a16f43e6b9d2f7e1c845a4fedf493f28b57ca 100644 (file)
@@ -189,6 +189,7 @@ get_order (unsigned long size)
 # define pgprot_val(x) ((x).pgprot)
 
 # define __pte(x)      ((pte_t) { (x) } )
+# define __pmd(x)      ((pmd_t) { (x) } )
 # define __pgprot(x)   ((pgprot_t) { (x) } )
 
 #else /* !STRICT_MM_TYPECHECKS */
index 8427697c5437c2961633d1a7b7c10465a96f1fa2..501ffdf0399c9b848ac5379531b5aac8b0172a35 100644 (file)
@@ -598,8 +598,8 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg)
        return cfq_target_latency * cfqg->weight / st->total_weight;
 }
 
-static inline void
-cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+static inline unsigned
+cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
        unsigned slice = cfq_prio_to_slice(cfqd, cfqq);
        if (cfqd->cfq_latency) {
@@ -625,6 +625,14 @@ cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
                                    low_slice);
                }
        }
+       return slice;
+}
+
+static inline void
+cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+       unsigned slice = cfq_scaled_group_slice(cfqd, cfqq);
+
        cfqq->slice_start = jiffies;
        cfqq->slice_end = jiffies + slice;
        cfqq->allocated_slice = slice;
@@ -1661,8 +1669,11 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
        /*
         * store what was left of this slice, if the queue idled/timed out
         */
-       if (timed_out && !cfq_cfqq_slice_new(cfqq)) {
-               cfqq->slice_resid = cfqq->slice_end - jiffies;
+       if (timed_out) {
+               if (cfq_cfqq_slice_new(cfqq))
+                       cfqq->slice_resid = cfq_scaled_group_slice(cfqd, cfqq);
+               else
+                       cfqq->slice_resid = cfqq->slice_end - jiffies;
                cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid);
        }
 
@@ -3284,9 +3295,18 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
  */
 static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+       struct cfq_queue *old_cfqq = cfqd->active_queue;
+
        cfq_log_cfqq(cfqd, cfqq, "preempt");
        cfq_slice_expired(cfqd, 1);
 
+       /*
+        * workload type is changed, don't save slice, otherwise preempt
+        * doesn't happen
+        */
+       if (cfqq_type(old_cfqq) != cfqq_type(cfqq))
+               cfqq->cfqg->saved_workload_slice = 0;
+
        /*
         * Put the new queue at the front of the of the current list,
         * so we know that it will be selected next.
index 9bb69c59bb12978fb0c33d239f6014007253d28f..0e4dba0d0325329da4c4ebb508c4978c1094190f 100644 (file)
@@ -228,8 +228,10 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_present;
  */
 ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock;     /* For GPE data structs and registers */
 ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock;        /* For ACPI H/W except GPE registers */
+ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */
 #define acpi_gbl_gpe_lock      &_acpi_gbl_gpe_lock
 #define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock
+#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
 
 /*****************************************************************************
  *
index 8e31bb5a973ae2483129781eb756089554d7b694..38bba66fcce554a62ed63b3f5afd76d7d18186ba 100644 (file)
@@ -293,8 +293,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
  *
  ******************************************************************************/
 static u8 acpi_ev_global_lock_pending;
-static spinlock_t _acpi_ev_global_lock_pending_lock;
-#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
 
 static u32 acpi_ev_global_lock_handler(void *context)
 {
index d9efa495b4330049a1fa57fde968938c6cb18f0b..199528ff7f1d2edde7b17d832940117b33449a16 100644 (file)
@@ -85,6 +85,7 @@ acpi_status acpi_ut_mutex_initialize(void)
 
        spin_lock_init(acpi_gbl_gpe_lock);
        spin_lock_init(acpi_gbl_hardware_lock);
+       spin_lock_init(acpi_ev_global_lock_pending_lock);
 
        /* Mutex for _OSI support */
        status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
index dffa0ac7c4f0e135ec410bcc0e30dff9a443a78d..38e4eb1bb9656ba565150a48d68594836f51c4f9 100644 (file)
@@ -350,6 +350,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
        if (!d->dm_dev.bdev)
                return;
 
+       bd_unlink_disk_holder(d->dm_dev.bdev, dm_disk(md));
        blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL);
        d->dm_dev.bdev = NULL;
 }
index cf8594c5ea21a481577705b17b95da1186bfb044..b76cfc89e1b57ce5557d7d4d931132c6f4efcc82 100644 (file)
@@ -1912,6 +1912,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
                MD_BUG();
                return;
        }
+       bd_unlink_disk_holder(rdev->bdev, rdev->mddev->gendisk);
        list_del_rcu(&rdev->same_set);
        printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
        rdev->mddev = NULL;
index 54c6d849cf25683cf4d2831c2c7b5d50605ec452..62d6f88cbab57deb4fb7141745f700ad68efceb4 100644 (file)
@@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value)
 }
 
 /**
- *     ks8695_get_settings - Get device-specific settings.
+ *     ks8695_wan_get_settings - Get device-specific settings.
  *     @ndev: The network device to read settings from
  *     @cmd: The ethtool structure to read into
  */
 static int
-ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
 {
        struct ks8695_priv *ksp = netdev_priv(ndev);
        u32 ctrl;
@@ -870,69 +870,50 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
                          SUPPORTED_TP | SUPPORTED_MII);
        cmd->transceiver = XCVR_INTERNAL;
 
-       /* Port specific extras */
-       switch (ksp->dtype) {
-       case KS8695_DTYPE_HPNA:
-               cmd->phy_address = 0;
-               /* not supported for HPNA */
-               cmd->autoneg = AUTONEG_DISABLE;
+       cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
+       cmd->port = PORT_MII;
+       cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
+       cmd->phy_address = 0;
 
-               /* BUG: Erm, dtype hpna implies no phy regs */
-               /*
-               ctrl = readl(KS8695_MISC_VA + KS8695_HMC);
-               cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10;
-               cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF;
-               */
-               return -EOPNOTSUPP;
-       case KS8695_DTYPE_WAN:
-               cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
-               cmd->port = PORT_MII;
-               cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
-               cmd->phy_address = 0;
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+       if ((ctrl & WMC_WAND) == 0) {
+               /* auto-negotiation is enabled */
+               cmd->advertising |= ADVERTISED_Autoneg;
+               if (ctrl & WMC_WANA100F)
+                       cmd->advertising |= ADVERTISED_100baseT_Full;
+               if (ctrl & WMC_WANA100H)
+                       cmd->advertising |= ADVERTISED_100baseT_Half;
+               if (ctrl & WMC_WANA10F)
+                       cmd->advertising |= ADVERTISED_10baseT_Full;
+               if (ctrl & WMC_WANA10H)
+                       cmd->advertising |= ADVERTISED_10baseT_Half;
+               if (ctrl & WMC_WANAP)
+                       cmd->advertising |= ADVERTISED_Pause;
+               cmd->autoneg = AUTONEG_ENABLE;
+
+               cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
+               cmd->duplex = (ctrl & WMC_WDS) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
+       } else {
+               /* auto-negotiation is disabled */
+               cmd->autoneg = AUTONEG_DISABLE;
 
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-               if ((ctrl & WMC_WAND) == 0) {
-                       /* auto-negotiation is enabled */
-                       cmd->advertising |= ADVERTISED_Autoneg;
-                       if (ctrl & WMC_WANA100F)
-                               cmd->advertising |= ADVERTISED_100baseT_Full;
-                       if (ctrl & WMC_WANA100H)
-                               cmd->advertising |= ADVERTISED_100baseT_Half;
-                       if (ctrl & WMC_WANA10F)
-                               cmd->advertising |= ADVERTISED_10baseT_Full;
-                       if (ctrl & WMC_WANA10H)
-                               cmd->advertising |= ADVERTISED_10baseT_Half;
-                       if (ctrl & WMC_WANAP)
-                               cmd->advertising |= ADVERTISED_Pause;
-                       cmd->autoneg = AUTONEG_ENABLE;
-
-                       cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
-                       cmd->duplex = (ctrl & WMC_WDS) ?
-                               DUPLEX_FULL : DUPLEX_HALF;
-               } else {
-                       /* auto-negotiation is disabled */
-                       cmd->autoneg = AUTONEG_DISABLE;
-
-                       cmd->speed = (ctrl & WMC_WANF100) ?
-                               SPEED_100 : SPEED_10;
-                       cmd->duplex = (ctrl & WMC_WANFF) ?
-                               DUPLEX_FULL : DUPLEX_HALF;
-               }
-               break;
-       case KS8695_DTYPE_LAN:
-               return -EOPNOTSUPP;
+               cmd->speed = (ctrl & WMC_WANF100) ?
+                       SPEED_100 : SPEED_10;
+               cmd->duplex = (ctrl & WMC_WANFF) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
        }
 
        return 0;
 }
 
 /**
- *     ks8695_set_settings - Set device-specific settings.
+ *     ks8695_wan_set_settings - Set device-specific settings.
  *     @ndev: The network device to configure
  *     @cmd: The settings to configure
  */
 static int
-ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
+ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
 {
        struct ks8695_priv *ksp = netdev_priv(ndev);
        u32 ctrl;
@@ -956,171 +937,85 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
                                ADVERTISED_100baseT_Full)) == 0)
                        return -EINVAL;
 
-               switch (ksp->dtype) {
-               case KS8695_DTYPE_HPNA:
-                       /* HPNA does not support auto-negotiation. */
-                       return -EINVAL;
-               case KS8695_DTYPE_WAN:
-                       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-                       ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
-                                 WMC_WANA10F | WMC_WANA10H);
-                       if (cmd->advertising & ADVERTISED_100baseT_Full)
-                               ctrl |= WMC_WANA100F;
-                       if (cmd->advertising & ADVERTISED_100baseT_Half)
-                               ctrl |= WMC_WANA100H;
-                       if (cmd->advertising & ADVERTISED_10baseT_Full)
-                               ctrl |= WMC_WANA10F;
-                       if (cmd->advertising & ADVERTISED_10baseT_Half)
-                               ctrl |= WMC_WANA10H;
-
-                       /* force a re-negotiation */
-                       ctrl |= WMC_WANR;
-                       writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-                       break;
-               case KS8695_DTYPE_LAN:
-                       return -EOPNOTSUPP;
-               }
+               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
 
+               ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
+                         WMC_WANA10F | WMC_WANA10H);
+               if (cmd->advertising & ADVERTISED_100baseT_Full)
+                       ctrl |= WMC_WANA100F;
+               if (cmd->advertising & ADVERTISED_100baseT_Half)
+                       ctrl |= WMC_WANA100H;
+               if (cmd->advertising & ADVERTISED_10baseT_Full)
+                       ctrl |= WMC_WANA10F;
+               if (cmd->advertising & ADVERTISED_10baseT_Half)
+                       ctrl |= WMC_WANA10H;
+
+               /* force a re-negotiation */
+               ctrl |= WMC_WANR;
+               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
        } else {
-               switch (ksp->dtype) {
-               case KS8695_DTYPE_HPNA:
-                       /* BUG: dtype_hpna implies no phy registers */
-                       /*
-                       ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC);
-
-                       ctrl &= ~(HMC_HSS | HMC_HDS);
-                       if (cmd->speed == SPEED_100)
-                               ctrl |= HMC_HSS;
-                       if (cmd->duplex == DUPLEX_FULL)
-                               ctrl |= HMC_HDS;
-
-                       __raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC);
-                       */
-                       return -EOPNOTSUPP;
-               case KS8695_DTYPE_WAN:
-                       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-                       /* disable auto-negotiation */
-                       ctrl |= WMC_WAND;
-                       ctrl &= ~(WMC_WANF100 | WMC_WANFF);
-
-                       if (cmd->speed == SPEED_100)
-                               ctrl |= WMC_WANF100;
-                       if (cmd->duplex == DUPLEX_FULL)
-                               ctrl |= WMC_WANFF;
-
-                       writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-                       break;
-               case KS8695_DTYPE_LAN:
-                       return -EOPNOTSUPP;
-               }
+               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
+
+               /* disable auto-negotiation */
+               ctrl |= WMC_WAND;
+               ctrl &= ~(WMC_WANF100 | WMC_WANFF);
+
+               if (cmd->speed == SPEED_100)
+                       ctrl |= WMC_WANF100;
+               if (cmd->duplex == DUPLEX_FULL)
+                       ctrl |= WMC_WANFF;
+
+               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
        }
 
        return 0;
 }
 
 /**
- *     ks8695_nwayreset - Restart the autonegotiation on the port.
+ *     ks8695_wan_nwayreset - Restart the autonegotiation on the port.
  *     @ndev: The network device to restart autoneotiation on
  */
 static int
-ks8695_nwayreset(struct net_device *ndev)
+ks8695_wan_nwayreset(struct net_device *ndev)
 {
        struct ks8695_priv *ksp = netdev_priv(ndev);
        u32 ctrl;
 
-       switch (ksp->dtype) {
-       case KS8695_DTYPE_HPNA:
-               /* No phy means no autonegotiation on hpna */
-               return -EINVAL;
-       case KS8695_DTYPE_WAN:
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-               if ((ctrl & WMC_WAND) == 0)
-                       writel(ctrl | WMC_WANR,
-                              ksp->phyiface_regs + KS8695_WMC);
-               else
-                       /* auto-negotiation not enabled */
-                       return -EINVAL;
-               break;
-       case KS8695_DTYPE_LAN:
-               return -EOPNOTSUPP;
-       }
-
-       return 0;
-}
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
 
-/**
- *     ks8695_get_link - Retrieve link status of network interface
- *     @ndev: The network interface to retrive the link status of.
- */
-static u32
-ks8695_get_link(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
+       if ((ctrl & WMC_WAND) == 0)
+               writel(ctrl | WMC_WANR,
+                      ksp->phyiface_regs + KS8695_WMC);
+       else
+               /* auto-negotiation not enabled */
+               return -EINVAL;
 
-       switch (ksp->dtype) {
-       case KS8695_DTYPE_HPNA:
-               /* HPNA always has link */
-               return 1;
-       case KS8695_DTYPE_WAN:
-               /* WAN we can read the PHY for */
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-               return ctrl & WMC_WLS;
-       case KS8695_DTYPE_LAN:
-               return -EOPNOTSUPP;
-       }
        return 0;
 }
 
 /**
- *     ks8695_get_pause - Retrieve network pause/flow-control advertising
+ *     ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
  *     @ndev: The device to retrieve settings from
  *     @param: The structure to fill out with the information
  */
 static void
-ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
+ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
 {
        struct ks8695_priv *ksp = netdev_priv(ndev);
        u32 ctrl;
 
-       switch (ksp->dtype) {
-       case KS8695_DTYPE_HPNA:
-               /* No phy link on hpna to configure */
-               return;
-       case KS8695_DTYPE_WAN:
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-               /* advertise Pause */
-               param->autoneg = (ctrl & WMC_WANAP);
+       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
 
-               /* current Rx Flow-control */
-               ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-               param->rx_pause = (ctrl & DRXC_RFCE);
+       /* advertise Pause */
+       param->autoneg = (ctrl & WMC_WANAP);
 
-               /* current Tx Flow-control */
-               ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-               param->tx_pause = (ctrl & DTXC_TFCE);
-               break;
-       case KS8695_DTYPE_LAN:
-               /* The LAN's "phy" is a direct-attached switch */
-               return;
-       }
-}
+       /* current Rx Flow-control */
+       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
+       param->rx_pause = (ctrl & DRXC_RFCE);
 
-/**
- *     ks8695_set_pause - Configure pause/flow-control
- *     @ndev: The device to configure
- *     @param: The pause parameters to set
- *
- *     TODO: Implement this
- */
-static int
-ks8695_set_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
-{
-       return -EOPNOTSUPP;
+       /* current Tx Flow-control */
+       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
+       param->tx_pause = (ctrl & DTXC_TFCE);
 }
 
 /**
@@ -1140,12 +1035,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
 static const struct ethtool_ops ks8695_ethtool_ops = {
        .get_msglevel   = ks8695_get_msglevel,
        .set_msglevel   = ks8695_set_msglevel,
-       .get_settings   = ks8695_get_settings,
-       .set_settings   = ks8695_set_settings,
-       .nway_reset     = ks8695_nwayreset,
-       .get_link       = ks8695_get_link,
-       .get_pauseparam = ks8695_get_pause,
-       .set_pauseparam = ks8695_set_pause,
+       .get_drvinfo    = ks8695_get_drvinfo,
+};
+
+static const struct ethtool_ops ks8695_wan_ethtool_ops = {
+       .get_msglevel   = ks8695_get_msglevel,
+       .set_msglevel   = ks8695_set_msglevel,
+       .get_settings   = ks8695_wan_get_settings,
+       .set_settings   = ks8695_wan_set_settings,
+       .nway_reset     = ks8695_wan_nwayreset,
+       .get_link       = ethtool_op_get_link,
+       .get_pauseparam = ks8695_wan_get_pause,
        .get_drvinfo    = ks8695_get_drvinfo,
 };
 
@@ -1541,7 +1441,6 @@ ks8695_probe(struct platform_device *pdev)
 
        /* driver system setup */
        ndev->netdev_ops = &ks8695_netdev_ops;
-       SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
        ndev->watchdog_timeo     = msecs_to_jiffies(watchdog);
 
        netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
@@ -1608,12 +1507,15 @@ ks8695_probe(struct platform_device *pdev)
        if (ksp->phyiface_regs && ksp->link_irq == -1) {
                ks8695_init_switch(ksp);
                ksp->dtype = KS8695_DTYPE_LAN;
+               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
        } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
                ks8695_init_wan_phy(ksp);
                ksp->dtype = KS8695_DTYPE_WAN;
+               SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
        } else {
                /* No initialisation since HPNA does not have a PHY */
                ksp->dtype = KS8695_DTYPE_HPNA;
+               SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
        }
 
        /* And bring up the net_device with the net core */
index 0b9fc5173aef1478355e9cadbcb635f1fdca594d..22abfb39d8131f4f9685fd4a914c0aa2873b525a 100644 (file)
@@ -1284,19 +1284,12 @@ static void bfin_mac_multicast_hash(struct net_device *dev)
 {
        u32 emac_hashhi, emac_hashlo;
        struct netdev_hw_addr *ha;
-       char *addrs;
        u32 crc;
 
        emac_hashhi = emac_hashlo = 0;
 
        netdev_for_each_mc_addr(ha, dev) {
-               addrs = ha->addr;
-
-               /* skip non-multicast addresses */
-               if (!(*addrs & 1))
-                       continue;
-
-               crc = ether_crc(ETH_ALEN, addrs);
+               crc = ether_crc(ETH_ALEN, ha->addr);
                crc >>= 26;
 
                if (crc & 0x20)
index 99be5ae91991f84554faf98d682f31c75cbf3b0e..142d6047da2795c879b3b2d54c862ad7d30a7e86 100644 (file)
@@ -275,7 +275,6 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 
        ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL);
        if (ioc_attr) {
-               memset(ioc_attr, 0, sizeof(*ioc_attr));
                spin_lock_irqsave(&bnad->bna_lock, flags);
                bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr);
                spin_unlock_irqrestore(&bnad->bna_lock, flags);
index 7206ab2cbbf8e16526775de5ec4d2f9bb5789f60..3437613f0454e97d00676766f6f7058abb5bbc5c 100644 (file)
@@ -3203,7 +3203,7 @@ static int cas_get_vpd_info(struct cas *cp, unsigned char *dev_addr,
        int phy_type = CAS_PHY_MII_MDIO0; /* default phy type */
        int mac_off  = 0;
 
-#if defined(CONFIG_OF)
+#if defined(CONFIG_SPARC)
        const unsigned char *addr;
 #endif
 
@@ -3354,7 +3354,7 @@ use_random_mac_addr:
        if (found & VPD_FOUND_MAC)
                goto done;
 
-#if defined(CONFIG_OF)
+#if defined(CONFIG_SPARC)
        addr = of_get_property(cp->of_node, "local-mac-address", NULL);
        if (addr != NULL) {
                memcpy(dev_addr, addr, 6);
@@ -5031,7 +5031,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
        cp->msg_enable = (cassini_debug < 0) ? CAS_DEF_MSG_ENABLE :
          cassini_debug;
 
-#if defined(CONFIG_OF)
+#if defined(CONFIG_SPARC)
        cp->of_node = pci_device_to_OF_node(pdev);
 #endif
 
index de69c54301c13fe78652c50e07ccfe9eefad441b..bfab14092d2c87b30f3e7bf3d1b72efd542b1d48 100644 (file)
@@ -3478,9 +3478,17 @@ static irqreturn_t e1000_intr(int irq, void *data)
        struct e1000_hw *hw = &adapter->hw;
        u32 icr = er32(ICR);
 
-       if (unlikely((!icr) || test_bit(__E1000_DOWN, &adapter->flags)))
+       if (unlikely((!icr)))
                return IRQ_NONE;  /* Not our interrupt */
 
+       /*
+        * we might have caused the interrupt, but the above
+        * read cleared it, and just in case the driver is
+        * down there is nothing to do so return handled
+        */
+       if (unlikely(test_bit(__E1000_DOWN, &adapter->flags)))
+               return IRQ_HANDLED;
+
        if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
                hw->get_link_status = 1;
                /* guard against interrupt when we're going down */
index 1397da118f0d310a45e67d18fd754d48d222191a..89a69035e538f2ef024e2c6e747a1b762744a118 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -1310,7 +1310,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
                 * apply workaround for hardware errata documented in errata
                 * docs Fixes issue where some error prone or unreliable PCIe
                 * completions are occurring, particularly with ASPM enabled.
-                * Without fix, issue can cause tx timeouts.
+                * Without fix, issue can cause Tx timeouts.
                 */
                reg = er32(GCR2);
                reg |= 1;
index 360c91369f35f7e3bd94818116777ba1c499c2f2..28519acacd2d28f4eea74fd0fe4239c9d6ff1aa7 100644 (file)
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel PRO/1000 Linux driver
-# Copyright(c) 1999 - 2008 Intel Corporation.
+# Copyright(c) 1999 - 2011 Intel Corporation.
 #
 # This program is free software; you can redistribute it and/or modify it
 # under the terms and conditions of the GNU General Public License,
index 7245dc2e0b7cc0d1d73aa84fa36378cc94f3db59..13149983d07ec993bca6487e2a16484349d6cf46 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index 5255be75374659a959e13fce4e91c217221db036..e610e1369053154abf27e8665d60ca1392a2d0ff 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index e45a61c8930a792b7333ca881fd291254de94058..2fefa820302b8c0b028c1a2945df0903dba0216c 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index f8ed03dab9b173bd5228537661ffd3d5250de784..fa08b6336cfb0796ae901076d25460f52600bb7a 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index e774380c7cecc6d645d543d253cbe05027646b39..bc0860a598c91673c86f012801bc178dccb72396 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -102,7 +102,7 @@ enum e1e_registers {
        E1000_RDTR     = 0x02820, /* Rx Delay Timer - RW */
        E1000_RXDCTL_BASE = 0x02828, /* Rx Descriptor Control - RW */
 #define E1000_RXDCTL(_n)   (E1000_RXDCTL_BASE + (_n << 8))
-       E1000_RADV     = 0x0282C, /* RX Interrupt Absolute Delay Timer - RW */
+       E1000_RADV     = 0x0282C, /* Rx Interrupt Absolute Delay Timer - RW */
 
 /* Convenience macros
  *
index 5bb65b7382db024c80c54b6b2d05f3f76e3cff41..fb46974cfec1afd122edea3f3aa8a4058b8d1928 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
index ff2872153b211dfdc447c9a82b133ce44479aa85..68aa1749bf66f027cb58a8bfba17dbfb34101043 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -533,7 +533,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
                        mac->autoneg_failed = 1;
                        return 0;
                }
-               e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
+               e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
 
                /* Disable auto-negotiation in the TXCW register */
                ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
@@ -556,7 +556,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
                 * and disable forced link in the Device Control register
                 * in an attempt to auto-negotiate with our link partner.
                 */
-               e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
+               e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
                ew32(TXCW, mac->txcw);
                ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
@@ -598,7 +598,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                        mac->autoneg_failed = 1;
                        return 0;
                }
-               e_dbg("NOT RXing /C/, disable AutoNeg and force link.\n");
+               e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
 
                /* Disable auto-negotiation in the TXCW register */
                ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
@@ -621,7 +621,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                 * and disable forced link in the Device Control register
                 * in an attempt to auto-negotiate with our link partner.
                 */
-               e_dbg("RXing /C/, enable AutoNeg and stop forcing link.\n");
+               e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
                ew32(TXCW, mac->txcw);
                ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
 
@@ -800,9 +800,9 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
         *      1:  Rx flow control is enabled (we can receive pause frames,
-        *        but not send pause frames).
+        *          but not send pause frames).
         *      2:  Tx flow control is enabled (we can send pause frames but we
-        *        do not support receiving pause frames).
+        *          do not support receiving pause frames).
         *      3:  Both Rx and Tx flow control (symmetric) are enabled.
         */
        switch (hw->fc.current_mode) {
@@ -1031,9 +1031,9 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
         *      1:  Rx flow control is enabled (we can receive pause
-        *        frames but not send pause frames).
+        *          frames but not send pause frames).
         *      2:  Tx flow control is enabled (we can send pause frames
-        *        frames but we do not receive pause frames).
+        *          frames but we do not receive pause frames).
         *      3:  Both Rx and Tx flow control (symmetric) is enabled.
         *  other:  No other values should be possible at this point.
         */
@@ -1189,7 +1189,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                        } else {
                                hw->fc.current_mode = e1000_fc_rx_pause;
                                e_dbg("Flow Control = "
-                                        "RX PAUSE frames only.\r\n");
+                                     "Rx PAUSE frames only.\r\n");
                        }
                }
                /*
index fa5b6045254732910a877f25c8f474a67cfea0e8..1c18f26b0812ac962708c68711abe58167c0eee0 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -77,17 +77,17 @@ struct e1000_reg_info {
        char *name;
 };
 
-#define E1000_RDFH     0x02410 /* Rx Data FIFO Head - RW */
-#define E1000_RDFT     0x02418 /* Rx Data FIFO Tail - RW */
-#define E1000_RDFHS    0x02420 /* Rx Data FIFO Head Saved - RW */
-#define E1000_RDFTS    0x02428 /* Rx Data FIFO Tail Saved - RW */
-#define E1000_RDFPC    0x02430 /* Rx Data FIFO Packet Count - RW */
+#define E1000_RDFH     0x02410 /* Rx Data FIFO Head - RW */
+#define E1000_RDFT     0x02418 /* Rx Data FIFO Tail - RW */
+#define E1000_RDFHS    0x02420 /* Rx Data FIFO Head Saved - RW */
+#define E1000_RDFTS    0x02428 /* Rx Data FIFO Tail Saved - RW */
+#define E1000_RDFPC    0x02430 /* Rx Data FIFO Packet Count - RW */
 
-#define E1000_TDFH     0x03410 /* Tx Data FIFO Head - RW */
-#define E1000_TDFT     0x03418 /* Tx Data FIFO Tail - RW */
-#define E1000_TDFHS    0x03420 /* Tx Data FIFO Head Saved - RW */
-#define E1000_TDFTS    0x03428 /* Tx Data FIFO Tail Saved - RW */
-#define E1000_TDFPC    0x03430 /* Tx Data FIFO Packet Count - RW */
+#define E1000_TDFH     0x03410 /* Tx Data FIFO Head - RW */
+#define E1000_TDFT     0x03418 /* Tx Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420 /* Tx Data FIFO Head Saved - RW */
+#define E1000_TDFTS    0x03428 /* Tx Data FIFO Tail Saved - RW */
+#define E1000_TDFPC    0x03430 /* Tx Data FIFO Packet Count - RW */
 
 static const struct e1000_reg_info e1000_reg_info_tbl[] = {
 
@@ -99,7 +99,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = {
        /* Interrupt Registers */
        {E1000_ICR, "ICR"},
 
-       /* RX Registers */
+       /* Rx Registers */
        {E1000_RCTL, "RCTL"},
        {E1000_RDLEN, "RDLEN"},
        {E1000_RDH, "RDH"},
@@ -115,7 +115,7 @@ static const struct e1000_reg_info e1000_reg_info_tbl[] = {
        {E1000_RDFTS, "RDFTS"},
        {E1000_RDFPC, "RDFPC"},
 
-       /* TX Registers */
+       /* Tx Registers */
        {E1000_TCTL, "TCTL"},
        {E1000_TDBAL, "TDBAL"},
        {E1000_TDBAH, "TDBAH"},
@@ -160,7 +160,7 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
                break;
        default:
                printk(KERN_INFO "%-15s %08x\n",
-                       reginfo->name, __er32(hw, reginfo->ofs));
+                      reginfo->name, __er32(hw, reginfo->ofs));
                return;
        }
 
@@ -171,9 +171,8 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
        printk(KERN_CONT "\n");
 }
 
-
 /*
- * e1000e_dump - Print registers, tx-ring and rx-ring
+ * e1000e_dump - Print registers, Tx-ring and Rx-ring
  */
 static void e1000e_dump(struct e1000_adapter *adapter)
 {
@@ -182,12 +181,20 @@ static void e1000e_dump(struct e1000_adapter *adapter)
        struct e1000_reg_info *reginfo;
        struct e1000_ring *tx_ring = adapter->tx_ring;
        struct e1000_tx_desc *tx_desc;
-       struct my_u0 { u64 a; u64 b; } *u0;
+       struct my_u0 {
+               u64 a;
+               u64 b;
+       } *u0;
        struct e1000_buffer *buffer_info;
        struct e1000_ring *rx_ring = adapter->rx_ring;
        union e1000_rx_desc_packet_split *rx_desc_ps;
        struct e1000_rx_desc *rx_desc;
-       struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1;
+       struct my_u1 {
+               u64 a;
+               u64 b;
+               u64 c;
+               u64 d;
+       } *u1;
        u32 staterr;
        int i = 0;
 
@@ -198,12 +205,10 @@ static void e1000e_dump(struct e1000_adapter *adapter)
        if (netdev) {
                dev_info(&adapter->pdev->dev, "Net device Info\n");
                printk(KERN_INFO "Device Name     state            "
-                       "trans_start      last_rx\n");
+                      "trans_start      last_rx\n");
                printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
-                       netdev->name,
-                       netdev->state,
-                       netdev->trans_start,
-                       netdev->last_rx);
+                      netdev->name, netdev->state, netdev->trans_start,
+                      netdev->last_rx);
        }
 
        /* Print Registers */
@@ -214,26 +219,26 @@ static void e1000e_dump(struct e1000_adapter *adapter)
                e1000_regdump(hw, reginfo);
        }
 
-       /* Print TX Ring Summary */
+       /* Print Tx Ring Summary */
        if (!netdev || !netif_running(netdev))
                goto exit;
 
-       dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
+       dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
        printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
-               " leng ntw timestamp\n");
+              " leng ntw timestamp\n");
        buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
        printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
-               0, tx_ring->next_to_use, tx_ring->next_to_clean,
-               (unsigned long long)buffer_info->dma,
-               buffer_info->length,
-               buffer_info->next_to_watch,
-               (unsigned long long)buffer_info->time_stamp);
+              0, tx_ring->next_to_use, tx_ring->next_to_clean,
+              (unsigned long long)buffer_info->dma,
+              buffer_info->length,
+              buffer_info->next_to_watch,
+              (unsigned long long)buffer_info->time_stamp);
 
-       /* Print TX Rings */
+       /* Print Tx Ring */
        if (!netif_msg_tx_done(adapter))
                goto rx_ring_summary;
 
-       dev_info(&adapter->pdev->dev, "TX Rings Dump\n");
+       dev_info(&adapter->pdev->dev, "Tx Ring Dump\n");
 
        /* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
         *
@@ -263,22 +268,22 @@ static void e1000e_dump(struct e1000_adapter *adapter)
         *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
         */
        printk(KERN_INFO "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]"
-               " [bi->dma       ] leng  ntw timestamp        bi->skb "
-               "<-- Legacy format\n");
+              " [bi->dma       ] leng  ntw timestamp        bi->skb "
+              "<-- Legacy format\n");
        printk(KERN_INFO "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
-               " [bi->dma       ] leng  ntw timestamp        bi->skb "
-               "<-- Ext Context format\n");
+              " [bi->dma       ] leng  ntw timestamp        bi->skb "
+              "<-- Ext Context format\n");
        printk(KERN_INFO "Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen]"
-               " [bi->dma       ] leng  ntw timestamp        bi->skb "
-               "<-- Ext Data format\n");
+              " [bi->dma       ] leng  ntw timestamp        bi->skb "
+              "<-- Ext Data format\n");
        for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
                tx_desc = E1000_TX_DESC(*tx_ring, i);
                buffer_info = &tx_ring->buffer_info[i];
                u0 = (struct my_u0 *)tx_desc;
                printk(KERN_INFO "T%c[0x%03X]    %016llX %016llX %016llX "
-                       "%04X  %3X %016llX %p",
-                      (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
-                       ((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
+                      "%04X  %3X %016llX %p",
+                      (!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' :
+                       ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')), i,
                       (unsigned long long)le64_to_cpu(u0->a),
                       (unsigned long long)le64_to_cpu(u0->b),
                       (unsigned long long)buffer_info->dma,
@@ -296,22 +301,22 @@ static void e1000e_dump(struct e1000_adapter *adapter)
 
                if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
                        print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
-                                       16, 1, phys_to_virt(buffer_info->dma),
-                                       buffer_info->length, true);
+                                      16, 1, phys_to_virt(buffer_info->dma),
+                                      buffer_info->length, true);
        }
 
-       /* Print RX Rings Summary */
+       /* Print Rx Ring Summary */
 rx_ring_summary:
-       dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
+       dev_info(&adapter->pdev->dev, "Rx Ring Summary\n");
        printk(KERN_INFO "Queue [NTU] [NTC]\n");
        printk(KERN_INFO " %5d %5X %5X\n", 0,
-               rx_ring->next_to_use, rx_ring->next_to_clean);
+              rx_ring->next_to_use, rx_ring->next_to_clean);
 
-       /* Print RX Rings */
+       /* Print Rx Ring */
        if (!netif_msg_rx_status(adapter))
                goto exit;
 
-       dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
+       dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
        switch (adapter->rx_ps_pages) {
        case 1:
        case 2:
@@ -329,7 +334,7 @@ rx_ring_summary:
                 *    +-----------------------------------------------------+
                 */
                printk(KERN_INFO "R  [desc]      [buffer 0 63:0 ] "
-                       "[buffer 1 63:0 ] "
+                      "[buffer 1 63:0 ] "
                       "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma       ] "
                       "[bi->skb] <-- Ext Pkt Split format\n");
                /* [Extended] Receive Descriptor (Write-Back) Format
@@ -344,7 +349,7 @@ rx_ring_summary:
                 *   63       48 47    32 31            20 19               0
                 */
                printk(KERN_INFO "RWB[desc]      [ck ipid mrqhsh] "
-                       "[vl   l0 ee  es] "
+                      "[vl   l0 ee  es] "
                       "[ l3  l2  l1 hs] [reserved      ] ---------------- "
                       "[bi->skb] <-- Ext Rx Write-Back format\n");
                for (i = 0; i < rx_ring->count; i++) {
@@ -352,26 +357,26 @@ rx_ring_summary:
                        rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
                        u1 = (struct my_u1 *)rx_desc_ps;
                        staterr =
-                               le32_to_cpu(rx_desc_ps->wb.middle.status_error);
+                           le32_to_cpu(rx_desc_ps->wb.middle.status_error);
                        if (staterr & E1000_RXD_STAT_DD) {
                                /* Descriptor Done */
                                printk(KERN_INFO "RWB[0x%03X]     %016llX "
-                                       "%016llX %016llX %016llX "
-                                       "---------------- %p", i,
-                                       (unsigned long long)le64_to_cpu(u1->a),
-                                       (unsigned long long)le64_to_cpu(u1->b),
-                                       (unsigned long long)le64_to_cpu(u1->c),
-                                       (unsigned long long)le64_to_cpu(u1->d),
-                                       buffer_info->skb);
+                                      "%016llX %016llX %016llX "
+                                      "---------------- %p", i,
+                                      (unsigned long long)le64_to_cpu(u1->a),
+                                      (unsigned long long)le64_to_cpu(u1->b),
+                                      (unsigned long long)le64_to_cpu(u1->c),
+                                      (unsigned long long)le64_to_cpu(u1->d),
+                                      buffer_info->skb);
                        } else {
                                printk(KERN_INFO "R  [0x%03X]     %016llX "
-                                       "%016llX %016llX %016llX %016llX %p", i,
-                                       (unsigned long long)le64_to_cpu(u1->a),
-                                       (unsigned long long)le64_to_cpu(u1->b),
-                                       (unsigned long long)le64_to_cpu(u1->c),
-                                       (unsigned long long)le64_to_cpu(u1->d),
-                                       (unsigned long long)buffer_info->dma,
-                                       buffer_info->skb);
+                                      "%016llX %016llX %016llX %016llX %p", i,
+                                      (unsigned long long)le64_to_cpu(u1->a),
+                                      (unsigned long long)le64_to_cpu(u1->b),
+                                      (unsigned long long)le64_to_cpu(u1->c),
+                                      (unsigned long long)le64_to_cpu(u1->d),
+                                      (unsigned long long)buffer_info->dma,
+                                      buffer_info->skb);
 
                                if (netif_msg_pktdata(adapter))
                                        print_hex_dump(KERN_INFO, "",
@@ -400,18 +405,18 @@ rx_ring_summary:
                 * 63       48 47    40 39      32 31         16 15      0
                 */
                printk(KERN_INFO "Rl[desc]     [address 63:0  ] "
-                       "[vl er S cks ln] [bi->dma       ] [bi->skb] "
-                       "<-- Legacy format\n");
+                      "[vl er S cks ln] [bi->dma       ] [bi->skb] "
+                      "<-- Legacy format\n");
                for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
                        rx_desc = E1000_RX_DESC(*rx_ring, i);
                        buffer_info = &rx_ring->buffer_info[i];
                        u0 = (struct my_u0 *)rx_desc;
                        printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
-                               "%016llX %p", i,
-                               (unsigned long long)le64_to_cpu(u0->a),
-                               (unsigned long long)le64_to_cpu(u0->b),
-                               (unsigned long long)buffer_info->dma,
-                               buffer_info->skb);
+                              "%016llX %p", i,
+                              (unsigned long long)le64_to_cpu(u0->a),
+                              (unsigned long long)le64_to_cpu(u0->b),
+                              (unsigned long long)buffer_info->dma,
+                              buffer_info->skb);
                        if (i == rx_ring->next_to_use)
                                printk(KERN_CONT " NTU\n");
                        else if (i == rx_ring->next_to_clean)
@@ -421,9 +426,10 @@ rx_ring_summary:
 
                        if (netif_msg_pktdata(adapter))
                                print_hex_dump(KERN_INFO, "",
-                                       DUMP_PREFIX_ADDRESS,
-                                       16, 1, phys_to_virt(buffer_info->dma),
-                                       adapter->rx_buffer_len, true);
+                                              DUMP_PREFIX_ADDRESS,
+                                              16, 1,
+                                              phys_to_virt(buffer_info->dma),
+                                              adapter->rx_buffer_len, true);
                }
        }
 
@@ -450,8 +456,7 @@ static int e1000_desc_unused(struct e1000_ring *ring)
  * @skb: pointer to sk_buff to be indicated to stack
  **/
 static void e1000_receive_skb(struct e1000_adapter *adapter,
-                             struct net_device *netdev,
-                             struct sk_buff *skb,
+                             struct net_device *netdev, struct sk_buff *skb,
                              u8 status, __le16 vlan)
 {
        skb->protocol = eth_type_trans(skb, netdev);
@@ -464,7 +469,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
 }
 
 /**
- * e1000_rx_checksum - Receive Checksum Offload for 82543
+ * e1000_rx_checksum - Receive Checksum Offload
  * @adapter:     board private structure
  * @status_err:  receive descriptor status and error fields
  * @csum:      receive descriptor csum field
@@ -548,7 +553,7 @@ map_skb:
                                                  adapter->rx_buffer_len,
                                                  DMA_FROM_DEVICE);
                if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
-                       dev_err(&pdev->dev, "RX DMA map failed\n");
+                       dev_err(&pdev->dev, "Rx DMA map failed\n");
                        adapter->rx_dma_failed++;
                        break;
                }
@@ -601,7 +606,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                        ps_page = &buffer_info->ps_pages[j];
                        if (j >= adapter->rx_ps_pages) {
                                /* all unused desc entries get hw null ptr */
-                               rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
+                               rx_desc->read.buffer_addr[j + 1] =
+                                   ~cpu_to_le64(0);
                                continue;
                        }
                        if (!ps_page->page) {
@@ -617,7 +623,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                                if (dma_mapping_error(&pdev->dev,
                                                      ps_page->dma)) {
                                        dev_err(&adapter->pdev->dev,
-                                         "RX DMA page map failed\n");
+                                               "Rx DMA page map failed\n");
                                        adapter->rx_dma_failed++;
                                        goto no_buffers;
                                }
@@ -627,8 +633,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                         * didn't change because each write-back
                         * erases this info.
                         */
-                       rx_desc->read.buffer_addr[j+1] =
-                            cpu_to_le64(ps_page->dma);
+                       rx_desc->read.buffer_addr[j + 1] =
+                           cpu_to_le64(ps_page->dma);
                }
 
                skb = netdev_alloc_skb_ip_align(netdev,
@@ -644,7 +650,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                                                  adapter->rx_ps_bsize0,
                                                  DMA_FROM_DEVICE);
                if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
-                       dev_err(&pdev->dev, "RX DMA map failed\n");
+                       dev_err(&pdev->dev, "Rx DMA map failed\n");
                        adapter->rx_dma_failed++;
                        /* cleanup skb */
                        dev_kfree_skb_any(skb);
@@ -662,7 +668,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                         * such as IA-64).
                         */
                        wmb();
-                       writel(i<<1, adapter->hw.hw_addr + rx_ring->tail);
+                       writel(i << 1, adapter->hw.hw_addr + rx_ring->tail);
                }
 
                i++;
@@ -1106,11 +1112,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                cleaned = 1;
                cleaned_count++;
                dma_unmap_single(&pdev->dev, buffer_info->dma,
-                                adapter->rx_ps_bsize0,
-                                DMA_FROM_DEVICE);
+                                adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
                buffer_info->dma = 0;
 
-               /* see !EOP comment in other rx routine */
+               /* see !EOP comment in other Rx routine */
                if (!(staterr & E1000_RXD_STAT_EOP))
                        adapter->flags2 |= FLAG2_IS_DISCARDING;
 
@@ -2610,7 +2615,7 @@ static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
 }
 
 /**
- * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
+ * e1000_configure_tx - Configure Transmit Unit after Reset
  * @adapter: board private structure
  *
  * Configure the Tx unit of the MAC after a reset.
@@ -2663,7 +2668,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
                 * hthresh = 1 ==> prefetch when one or more available
                 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
                 * BEWARE: this seems to work but should be considered first if
-                * there are tx hangs or other tx related bugs
+                * there are Tx hangs or other Tx related bugs
                 */
                txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
                ew32(TXDCTL(0), txdctl);
@@ -2877,7 +2882,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
        if (adapter->rx_ps_pages) {
                /* this is a 32 byte descriptor */
                rdlen = rx_ring->count *
-                       sizeof(union e1000_rx_desc_packet_split);
+                   sizeof(union e1000_rx_desc_packet_split);
                adapter->clean_rx = e1000_clean_rx_irq_ps;
                adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
        } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
@@ -2900,7 +2905,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                /*
                 * set the writeback threshold (only takes effect if the RDTR
                 * is set). set GRAN=1 and write back up to 0x4 worth, and
-                * enable prefetching of 0x20 rx descriptors
+                * enable prefetching of 0x20 Rx descriptors
                 * granularity = 01
                 * wthresh = 04,
                 * hthresh = 04,
@@ -2981,12 +2986,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                         * excessive C-state transition latencies result in
                         * dropped transactions.
                         */
-                       pm_qos_update_request(
-                               &adapter->netdev->pm_qos_req, 55);
+                       pm_qos_update_request(&adapter->netdev->pm_qos_req, 55);
                } else {
-                       pm_qos_update_request(
-                               &adapter->netdev->pm_qos_req,
-                               PM_QOS_DEFAULT_VALUE);
+                       pm_qos_update_request(&adapter->netdev->pm_qos_req,
+                                             PM_QOS_DEFAULT_VALUE);
                }
        }
 
@@ -3152,7 +3155,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
                /* lower 16 bits has Rx packet buffer allocation size in KB */
                pba &= 0xffff;
                /*
-                * the Tx fifo also stores 16 bytes of information about the tx
+                * the Tx fifo also stores 16 bytes of information about the Tx
                 * but don't include ethernet FCS because hardware appends it
                 */
                min_tx_space = (adapter->max_frame_size +
@@ -3175,7 +3178,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
                        pba -= min_tx_space - tx_space;
 
                        /*
-                        * if short on Rx space, Rx wins and must trump tx
+                        * if short on Rx space, Rx wins and must trump Tx
                         * adjustment or use Early Receive if available
                         */
                        if ((pba < min_rx_space) &&
@@ -4039,11 +4042,11 @@ static void e1000_print_link_info(struct e1000_adapter *adapter)
               adapter->netdev->name,
               adapter->link_speed,
               (adapter->link_duplex == FULL_DUPLEX) ?
-                               "Full Duplex" : "Half Duplex",
+              "Full Duplex" : "Half Duplex",
               ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
-                               "RX/TX" :
-              ((ctrl & E1000_CTRL_RFCE) ? "RX" :
-              ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
+              "Rx/Tx" :
+              ((ctrl & E1000_CTRL_RFCE) ? "Rx" :
+               ((ctrl & E1000_CTRL_TFCE) ? "Tx" : "None")));
 }
 
 static bool e1000e_has_link(struct e1000_adapter *adapter)
@@ -4338,7 +4341,7 @@ link_up:
        /* Force detection of hung controller every watchdog period */
        adapter->detect_tx_hung = 1;
 
-       /* flush partial descriptors to memory before detecting tx hang */
+       /* flush partial descriptors to memory before detecting Tx hang */
        if (adapter->flags2 & FLAG2_DMA_BURST) {
                ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
                ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
@@ -4529,7 +4532,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                buffer_info->next_to_watch = i;
                buffer_info->dma = dma_map_single(&pdev->dev,
                                                  skb->data + offset,
-                                                 size, DMA_TO_DEVICE);
+                                                 size, DMA_TO_DEVICE);
                buffer_info->mapped_as_page = false;
                if (dma_mapping_error(&pdev->dev, buffer_info->dma))
                        goto dma_error;
@@ -4576,7 +4579,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                }
        }
 
-       segs = skb_shinfo(skb)->gso_segs ?: 1;
+       segs = skb_shinfo(skb)->gso_segs ? : 1;
        /* multiply data chunks by size of headers */
        bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
 
@@ -4588,13 +4591,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
        return count;
 
 dma_error:
-       dev_err(&pdev->dev, "TX DMA map failed\n");
+       dev_err(&pdev->dev, "Tx DMA map failed\n");
        buffer_info->dma = 0;
        if (count)
                count--;
 
        while (count--) {
-               if (i==0)
+               if (i == 0)
                        i += tx_ring->count;
                i--;
                buffer_info = &tx_ring->buffer_info[i];
@@ -6193,7 +6196,7 @@ static int __init e1000_init_module(void)
        int ret;
        pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
                e1000e_driver_version);
-       pr_info("Copyright (c) 1999 - 2010 Intel Corporation.\n");
+       pr_info("Copyright(c) 1999 - 2011 Intel Corporation.\n");
        ret = pci_register_driver(&e1000_driver);
 
        return ret;
index a9612b0e4bca89938117c6febffbc4ab07098b1b..4dd9b63273f62eac9917d69df9a613dd3fa14e61 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -62,10 +62,9 @@ MODULE_PARM_DESC(copybreak,
        module_param_array_named(X, X, int, &num_##X, 0);       \
        MODULE_PARM_DESC(X, desc);
 
-
 /*
  * Transmit Interrupt Delay in units of 1.024 microseconds
- * Tx interrupt delay needs to typically be set to something non zero
+ * Tx interrupt delay needs to typically be set to something non-zero
  *
  * Valid Range: 0-65535
  */
@@ -112,6 +111,7 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define DEFAULT_ITR 3
 #define MAX_ITR 100000
 #define MIN_ITR 100
+
 /* IntMode (Interrupt Mode)
  *
  * Valid Range: 0 - 2
index 00f89e8a9fa02a5288543e4806b45fd15a3b9c88..6bea051b134b5e7e48f0c85feb9a4879d956974b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2010 Intel Corporation.
+  Copyright(c) 1999 - 2011 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -640,7 +640,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
        s32 ret_val;
        u16 phy_data;
 
-       /* Enable CRS on TX. This must be set for half-duplex operation. */
+       /* Enable CRS on Tx. This must be set for half-duplex operation. */
        ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data);
        if (ret_val)
                goto out;
index 6de4675016b5303e186d3c2350c8a81b0c98ae7c..119aa2000c24a7e7091c517588ab64b175e50c39 100644 (file)
@@ -434,7 +434,6 @@ static void gfar_init_mac(struct net_device *ndev)
 static struct net_device_stats *gfar_get_stats(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
-       struct netdev_queue *txq;
        unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0;
        unsigned long tx_packets = 0, tx_bytes = 0;
        int i = 0;
@@ -450,9 +449,8 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev)
        dev->stats.rx_dropped = rx_dropped;
 
        for (i = 0; i < priv->num_tx_queues; i++) {
-               txq = netdev_get_tx_queue(dev, i);
-               tx_bytes += txq->tx_bytes;
-               tx_packets += txq->tx_packets;
+               tx_bytes += priv->tx_queue[i]->stats.tx_bytes;
+               tx_packets += priv->tx_queue[i]->stats.tx_packets;
        }
 
        dev->stats.tx_bytes = tx_bytes;
@@ -2109,8 +2107,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        /* Update transmit stats */
-       txq->tx_bytes += skb->len;
-       txq->tx_packets ++;
+       tx_queue->stats.tx_bytes += skb->len;
+       tx_queue->stats.tx_packets++;
 
        txbdp = txbdp_start = tx_queue->cur_tx;
        lstatus = txbdp->lstatus;
index 68984eb88ae03ed519ca9ce8dfdcaa2df7f827a8..54de4135e932b9dd2d92eedd32cf0338a20f3011 100644 (file)
@@ -907,12 +907,21 @@ enum {
        MQ_MG_MODE
 };
 
+/*
+ * Per TX queue stats
+ */
+struct tx_q_stats {
+       unsigned long tx_packets;
+       unsigned long tx_bytes;
+};
+
 /**
  *     struct gfar_priv_tx_q - per tx queue structure
  *     @txlock: per queue tx spin lock
  *     @tx_skbuff:skb pointers
  *     @skb_curtx: to be used skb pointer
  *     @skb_dirtytx:the last used skb pointer
+ *     @stats: bytes/packets stats
  *     @qindex: index of this queue
  *     @dev: back pointer to the dev structure
  *     @grp: back pointer to the group to which this queue belongs
@@ -934,6 +943,7 @@ struct gfar_priv_tx_q {
        struct  txbd8 *tx_bd_base;
        struct  txbd8 *cur_tx;
        struct  txbd8 *dirty_tx;
+       struct tx_q_stats stats;
        struct  net_device *dev;
        struct gfar_priv_grp *grp;
        u16     skb_curtx;
index 27d6960ce09ea7a8d7f12ef970f9de5c769ebd37..fdb0333f5cb60145bdeb2ec9940b85a319d14cad 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC.
  *
- * 2005-2009 (c) Aeroflex Gaisler AB
+ * 2005-2010 (c) Aeroflex Gaisler AB
  *
  * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs
  * available in the GRLIB VHDL IP core library.
@@ -356,6 +356,8 @@ static int greth_open(struct net_device *dev)
                dev_dbg(&dev->dev, " starting queue\n");
        netif_start_queue(dev);
 
+       GRETH_REGSAVE(greth->regs->status, 0xFF);
+
        napi_enable(&greth->napi);
 
        greth_enable_irqs(greth);
@@ -371,7 +373,9 @@ static int greth_close(struct net_device *dev)
 
        napi_disable(&greth->napi);
 
+       greth_disable_irqs(greth);
        greth_disable_tx(greth);
+       greth_disable_rx(greth);
 
        netif_stop_queue(dev);
 
@@ -388,12 +392,20 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct greth_private *greth = netdev_priv(dev);
        struct greth_bd *bdp;
        int err = NETDEV_TX_OK;
-       u32 status, dma_addr;
+       u32 status, dma_addr, ctrl;
+       unsigned long flags;
 
-       bdp = greth->tx_bd_base + greth->tx_next;
+       /* Clean TX Ring */
+       greth_clean_tx(greth->netdev);
 
        if (unlikely(greth->tx_free <= 0)) {
+               spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
+               ctrl = GRETH_REGLOAD(greth->regs->control);
+               /* Enable TX IRQ only if not already in poll() routine */
+               if (ctrl & GRETH_RXI)
+                       GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
                netif_stop_queue(dev);
+               spin_unlock_irqrestore(&greth->devlock, flags);
                return NETDEV_TX_BUSY;
        }
 
@@ -406,13 +418,14 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
                goto out;
        }
 
+       bdp = greth->tx_bd_base + greth->tx_next;
        dma_addr = greth_read_bd(&bdp->addr);
 
        memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
 
        dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
 
-       status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN);
+       status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN);
 
        /* Wrap around descriptor ring */
        if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
@@ -422,22 +435,11 @@ greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        greth->tx_next = NEXT_TX(greth->tx_next);
        greth->tx_free--;
 
-       /* No more descriptors */
-       if (unlikely(greth->tx_free == 0)) {
-
-               /* Free transmitted descriptors */
-               greth_clean_tx(dev);
-
-               /* If nothing was cleaned, stop queue & wait for irq */
-               if (unlikely(greth->tx_free == 0)) {
-                       status |= GRETH_BD_IE;
-                       netif_stop_queue(dev);
-               }
-       }
-
        /* Write descriptor control word and enable transmission */
        greth_write_bd(&bdp->stat, status);
+       spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
        greth_enable_tx(greth);
+       spin_unlock_irqrestore(&greth->devlock, flags);
 
 out:
        dev_kfree_skb(skb);
@@ -450,13 +452,23 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
 {
        struct greth_private *greth = netdev_priv(dev);
        struct greth_bd *bdp;
-       u32 status = 0, dma_addr;
+       u32 status = 0, dma_addr, ctrl;
        int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
+       unsigned long flags;
 
        nr_frags = skb_shinfo(skb)->nr_frags;
 
+       /* Clean TX Ring */
+       greth_clean_tx_gbit(dev);
+
        if (greth->tx_free < nr_frags + 1) {
+               spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
+               ctrl = GRETH_REGLOAD(greth->regs->control);
+               /* Enable TX IRQ only if not already in poll() routine */
+               if (ctrl & GRETH_RXI)
+                       GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
                netif_stop_queue(dev);
+               spin_unlock_irqrestore(&greth->devlock, flags);
                err = NETDEV_TX_BUSY;
                goto out;
        }
@@ -499,7 +511,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
                greth->tx_skbuff[curr_tx] = NULL;
                bdp = greth->tx_bd_base + curr_tx;
 
-               status = GRETH_TXBD_CSALL;
+               status = GRETH_TXBD_CSALL | GRETH_BD_EN;
                status |= frag->size & GRETH_BD_LEN;
 
                /* Wrap around descriptor ring */
@@ -509,14 +521,8 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
                /* More fragments left */
                if (i < nr_frags - 1)
                        status |= GRETH_TXBD_MORE;
-
-               /* ... last fragment, check if out of descriptors  */
-               else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) {
-
-                       /* Enable interrupts and stop queue */
-                       status |= GRETH_BD_IE;
-                       netif_stop_queue(dev);
-               }
+               else
+                       status |= GRETH_BD_IE; /* enable IRQ on last fragment */
 
                greth_write_bd(&bdp->stat, status);
 
@@ -536,26 +542,29 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
 
        wmb();
 
-       /* Enable the descriptors that we configured ...  */
-       for (i = 0; i < nr_frags + 1; i++) {
-               bdp = greth->tx_bd_base + greth->tx_next;
-               greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
-               greth->tx_next = NEXT_TX(greth->tx_next);
-               greth->tx_free--;
-       }
+       /* Enable the descriptor chain by enabling the first descriptor */
+       bdp = greth->tx_bd_base + greth->tx_next;
+       greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
+       greth->tx_next = curr_tx;
+       greth->tx_free -= nr_frags + 1;
 
+       wmb();
+
+       spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
        greth_enable_tx(greth);
+       spin_unlock_irqrestore(&greth->devlock, flags);
 
        return NETDEV_TX_OK;
 
 frag_map_error:
-       /* Unmap SKB mappings that succeeded */
+       /* Unmap SKB mappings that succeeded and disable descriptor */
        for (i = 0; greth->tx_next + i != curr_tx; i++) {
                bdp = greth->tx_bd_base + greth->tx_next + i;
                dma_unmap_single(greth->dev,
                                 greth_read_bd(&bdp->addr),
                                 greth_read_bd(&bdp->stat) & GRETH_BD_LEN,
                                 DMA_TO_DEVICE);
+               greth_write_bd(&bdp->stat, 0);
        }
 map_error:
        if (net_ratelimit())
@@ -565,12 +574,11 @@ out:
        return err;
 }
 
-
 static irqreturn_t greth_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct greth_private *greth;
-       u32 status;
+       u32 status, ctrl;
        irqreturn_t retval = IRQ_NONE;
 
        greth = netdev_priv(dev);
@@ -580,13 +588,15 @@ static irqreturn_t greth_interrupt(int irq, void *dev_id)
        /* Get the interrupt events that caused us to be here. */
        status = GRETH_REGLOAD(greth->regs->status);
 
-       /* Handle rx and tx interrupts through poll */
-       if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
-
-               /* Clear interrupt status */
-               GRETH_REGORIN(greth->regs->status,
-                             status & (GRETH_INT_RX | GRETH_INT_TX));
+       /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be
+        * set regardless of whether IRQ is enabled or not. Especially
+        * important when shared IRQ.
+        */
+       ctrl = GRETH_REGLOAD(greth->regs->control);
 
+       /* Handle rx and tx interrupts through poll */
+       if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) ||
+           ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) {
                retval = IRQ_HANDLED;
 
                /* Disable interrupts and schedule poll() */
@@ -610,6 +620,8 @@ static void greth_clean_tx(struct net_device *dev)
 
        while (1) {
                bdp = greth->tx_bd_base + greth->tx_last;
+               GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
+               mb();
                stat = greth_read_bd(&bdp->stat);
 
                if (unlikely(stat & GRETH_BD_EN))
@@ -670,7 +682,10 @@ static void greth_clean_tx_gbit(struct net_device *dev)
 
                /* We only clean fully completed SKBs */
                bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
-               stat = bdp_last_frag->stat;
+
+               GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
+               mb();
+               stat = greth_read_bd(&bdp_last_frag->stat);
 
                if (stat & GRETH_BD_EN)
                        break;
@@ -702,21 +717,9 @@ static void greth_clean_tx_gbit(struct net_device *dev)
                greth->tx_free += nr_frags+1;
                dev_kfree_skb(skb);
        }
-       if (greth->tx_free > (MAX_SKB_FRAGS + 1)) {
-               netif_wake_queue(dev);
-       }
-}
 
-static int greth_pending_packets(struct greth_private *greth)
-{
-       struct greth_bd *bdp;
-       u32 status;
-       bdp = greth->rx_bd_base + greth->rx_cur;
-       status = greth_read_bd(&bdp->stat);
-       if (status & GRETH_BD_EN)
-               return 0;
-       else
-               return 1;
+       if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1)))
+               netif_wake_queue(dev);
 }
 
 static int greth_rx(struct net_device *dev, int limit)
@@ -727,20 +730,24 @@ static int greth_rx(struct net_device *dev, int limit)
        int pkt_len;
        int bad, count;
        u32 status, dma_addr;
+       unsigned long flags;
 
        greth = netdev_priv(dev);
 
        for (count = 0; count < limit; ++count) {
 
                bdp = greth->rx_bd_base + greth->rx_cur;
+               GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
+               mb();
                status = greth_read_bd(&bdp->stat);
-               dma_addr = greth_read_bd(&bdp->addr);
-               bad = 0;
 
                if (unlikely(status & GRETH_BD_EN)) {
                        break;
                }
 
+               dma_addr = greth_read_bd(&bdp->addr);
+               bad = 0;
+
                /* Check status for errors. */
                if (unlikely(status & GRETH_RXBD_STATUS)) {
                        if (status & GRETH_RXBD_ERR_FT) {
@@ -802,7 +809,9 @@ static int greth_rx(struct net_device *dev, int limit)
 
                dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
 
+               spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */
                greth_enable_rx(greth);
+               spin_unlock_irqrestore(&greth->devlock, flags);
 
                greth->rx_cur = NEXT_RX(greth->rx_cur);
        }
@@ -836,6 +845,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
        int pkt_len;
        int bad, count = 0;
        u32 status, dma_addr;
+       unsigned long flags;
 
        greth = netdev_priv(dev);
 
@@ -843,6 +853,8 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
 
                bdp = greth->rx_bd_base + greth->rx_cur;
                skb = greth->rx_skbuff[greth->rx_cur];
+               GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
+               mb();
                status = greth_read_bd(&bdp->stat);
                bad = 0;
 
@@ -865,10 +877,9 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
                        }
                }
 
-               /* Allocate new skb to replace current */
-               newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN);
-
-               if (!bad && newskb) {
+               /* Allocate new skb to replace current, not needed if the
+                * current skb can be reused */
+               if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) {
                        skb_reserve(newskb, NET_IP_ALIGN);
 
                        dma_addr = dma_map_single(greth->dev,
@@ -905,11 +916,22 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
                                if (net_ratelimit())
                                        dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
                                dev_kfree_skb(newskb);
+                               /* reusing current skb, so it is a drop */
                                dev->stats.rx_dropped++;
                        }
+               } else if (bad) {
+                       /* Bad Frame transfer, the skb is reused */
+                       dev->stats.rx_dropped++;
                } else {
+                       /* Failed Allocating a new skb. This is rather stupid
+                        * but the current "filled" skb is reused, as if
+                        * transfer failure. One could argue that RX descriptor
+                        * table handling should be divided into cleaning and
+                        * filling as the TX part of the driver
+                        */
                        if (net_ratelimit())
                                dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
+                       /* reusing current skb, so it is a drop */
                        dev->stats.rx_dropped++;
                }
 
@@ -920,7 +942,9 @@ static int greth_rx_gbit(struct net_device *dev, int limit)
 
                wmb();
                greth_write_bd(&bdp->stat, status);
+               spin_lock_irqsave(&greth->devlock, flags);
                greth_enable_rx(greth);
+               spin_unlock_irqrestore(&greth->devlock, flags);
                greth->rx_cur = NEXT_RX(greth->rx_cur);
        }
 
@@ -932,15 +956,18 @@ static int greth_poll(struct napi_struct *napi, int budget)
 {
        struct greth_private *greth;
        int work_done = 0;
+       unsigned long flags;
+       u32 mask, ctrl;
        greth = container_of(napi, struct greth_private, napi);
 
-       if (greth->gbit_mac) {
-               greth_clean_tx_gbit(greth->netdev);
-       } else {
-               greth_clean_tx(greth->netdev);
+restart_txrx_poll:
+       if (netif_queue_stopped(greth->netdev)) {
+               if (greth->gbit_mac)
+                       greth_clean_tx_gbit(greth->netdev);
+               else
+                       greth_clean_tx(greth->netdev);
        }
 
-restart_poll:
        if (greth->gbit_mac) {
                work_done += greth_rx_gbit(greth->netdev, budget - work_done);
        } else {
@@ -949,15 +976,29 @@ restart_poll:
 
        if (work_done < budget) {
 
-               napi_complete(napi);
+               spin_lock_irqsave(&greth->devlock, flags);
+
+               ctrl = GRETH_REGLOAD(greth->regs->control);
+               if (netif_queue_stopped(greth->netdev)) {
+                       GRETH_REGSAVE(greth->regs->control,
+                                       ctrl | GRETH_TXI | GRETH_RXI);
+                       mask = GRETH_INT_RX | GRETH_INT_RE |
+                              GRETH_INT_TX | GRETH_INT_TE;
+               } else {
+                       GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI);
+                       mask = GRETH_INT_RX | GRETH_INT_RE;
+               }
 
-               if (greth_pending_packets(greth)) {
-                       napi_reschedule(napi);
-                       goto restart_poll;
+               if (GRETH_REGLOAD(greth->regs->status) & mask) {
+                       GRETH_REGSAVE(greth->regs->control, ctrl);
+                       spin_unlock_irqrestore(&greth->devlock, flags);
+                       goto restart_txrx_poll;
+               } else {
+                       __napi_complete(napi);
+                       spin_unlock_irqrestore(&greth->devlock, flags);
                }
        }
 
-       greth_enable_irqs(greth);
        return work_done;
 }
 
@@ -1152,11 +1193,11 @@ static const struct ethtool_ops greth_ethtool_ops = {
 };
 
 static struct net_device_ops greth_netdev_ops = {
-       .ndo_open = greth_open,
-       .ndo_stop = greth_close,
-       .ndo_start_xmit = greth_start_xmit,
-       .ndo_set_mac_address = greth_set_mac_add,
-       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_open               = greth_open,
+       .ndo_stop               = greth_close,
+       .ndo_start_xmit         = greth_start_xmit,
+       .ndo_set_mac_address    = greth_set_mac_add,
+       .ndo_validate_addr      = eth_validate_addr,
 };
 
 static inline int wait_for_mdio(struct greth_private *greth)
@@ -1217,29 +1258,26 @@ static void greth_link_change(struct net_device *dev)
        struct greth_private *greth = netdev_priv(dev);
        struct phy_device *phydev = greth->phy;
        unsigned long flags;
-
        int status_change = 0;
+       u32 ctrl;
 
        spin_lock_irqsave(&greth->devlock, flags);
 
        if (phydev->link) {
 
                if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) {
-
-                       GRETH_REGANDIN(greth->regs->control,
-                                      ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB));
+                       ctrl = GRETH_REGLOAD(greth->regs->control) &
+                              ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB);
 
                        if (phydev->duplex)
-                               GRETH_REGORIN(greth->regs->control, GRETH_CTRL_FD);
-
-                       if (phydev->speed == SPEED_100) {
-
-                               GRETH_REGORIN(greth->regs->control, GRETH_CTRL_SP);
-                       }
+                               ctrl |= GRETH_CTRL_FD;
 
+                       if (phydev->speed == SPEED_100)
+                               ctrl |= GRETH_CTRL_SP;
                        else if (phydev->speed == SPEED_1000)
-                               GRETH_REGORIN(greth->regs->control, GRETH_CTRL_GB);
+                               ctrl |= GRETH_CTRL_GB;
 
+                       GRETH_REGSAVE(greth->regs->control, ctrl);
                        greth->speed = phydev->speed;
                        greth->duplex = phydev->duplex;
                        status_change = 1;
@@ -1600,6 +1638,9 @@ static struct of_device_id greth_of_match[] = {
        {
         .name = "GAISLER_ETHMAC",
         },
+       {
+        .name = "01_01d",
+        },
        {},
 };
 
index 03ad903cd676a1dd8f65e55a491aa8cb45c8956e..be0f2062bd14df7cc12753beddcf809867082de7 100644 (file)
@@ -23,6 +23,7 @@
 #define GRETH_BD_LEN 0x7FF
 
 #define GRETH_TXEN 0x1
+#define GRETH_INT_TE 0x2
 #define GRETH_INT_TX 0x8
 #define GRETH_TXI 0x4
 #define GRETH_TXBD_STATUS 0x0001C000
@@ -35,6 +36,7 @@
 #define GRETH_TXBD_ERR_UE 0x4000
 #define GRETH_TXBD_ERR_AL 0x8000
 
+#define GRETH_INT_RE         0x1
 #define GRETH_INT_RX         0x4
 #define GRETH_RXEN           0x2
 #define GRETH_RXI            0x8
index a060610a42dbddf22429d7762c57a6f1d3723d3f..602078b848920a44f0c8e8398e6d3151f417fd4d 100644 (file)
@@ -6667,8 +6667,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                          struct ixgbe_adapter *adapter,
                          struct ixgbe_ring *tx_ring)
 {
-       struct net_device *netdev = tx_ring->netdev;
-       struct netdev_queue *txq;
        unsigned int first;
        unsigned int tx_flags = 0;
        u8 hdr_len = 0;
@@ -6765,9 +6763,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                /* add the ATR filter if ATR is on */
                if (test_bit(__IXGBE_TX_FDIR_INIT_DONE, &tx_ring->state))
                        ixgbe_atr(tx_ring, skb, tx_flags, protocol);
-               txq = netdev_get_tx_queue(netdev, tx_ring->queue_index);
-               txq->tx_bytes += skb->len;
-               txq->tx_packets++;
                ixgbe_tx_queue(tx_ring, tx_flags, count, skb->len, hdr_len);
                ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
 
@@ -6925,8 +6920,6 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        int i;
 
-       /* accurate rx/tx bytes/packets stats */
-       dev_txq_stats_fold(netdev, stats);
        rcu_read_lock();
        for (i = 0; i < adapter->num_rx_queues; i++) {
                struct ixgbe_ring *ring = ACCESS_ONCE(adapter->rx_ring[i]);
@@ -6943,6 +6936,22 @@ static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev,
                        stats->rx_bytes   += bytes;
                }
        }
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct ixgbe_ring *ring = ACCESS_ONCE(adapter->tx_ring[i]);
+               u64 bytes, packets;
+               unsigned int start;
+
+               if (ring) {
+                       do {
+                               start = u64_stats_fetch_begin_bh(&ring->syncp);
+                               packets = ring->stats.packets;
+                               bytes   = ring->stats.bytes;
+                       } while (u64_stats_fetch_retry_bh(&ring->syncp, start));
+                       stats->tx_packets += packets;
+                       stats->tx_bytes   += bytes;
+               }
+       }
        rcu_read_unlock();
        /* following stats updated by ixgbe_watchdog_task() */
        stats->multicast        = netdev->stats.multicast;
index 21845affea1303ed80a952d38b78d24c39281e28..5933621ac3ffa73f7c3a19db049b5bbc813560be 100644 (file)
@@ -585,7 +585,7 @@ err:
        rcu_read_lock_bh();
        vlan = rcu_dereference(q->vlan);
        if (vlan)
-               netdev_get_tx_queue(vlan->dev, 0)->tx_dropped++;
+               vlan->dev->stats.tx_dropped++;
        rcu_read_unlock_bh();
 
        return err;
index bb8645ab247cc3e586932c9f5f8143ce381a50d1..bde7d61f193063b91ffb7fb02c0a1db787ca7d78 100644 (file)
@@ -554,6 +554,8 @@ struct rtl8169_private {
        struct mii_if_info mii;
        struct rtl8169_counters counters;
        u32 saved_wolopts;
+
+       const struct firmware *fw;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -1766,6 +1768,29 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
        }
 }
 
+static void rtl_release_firmware(struct rtl8169_private *tp)
+{
+       release_firmware(tp->fw);
+       tp->fw = NULL;
+}
+
+static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name)
+{
+       const struct firmware **fw = &tp->fw;
+       int rc = !*fw;
+
+       if (rc) {
+               rc = request_firmware(fw, fw_name, &tp->pci_dev->dev);
+               if (rc < 0)
+                       goto out;
+       }
+
+       /* TODO: release firmware once rtl_phy_write_fw signals failures. */
+       rtl_phy_write_fw(tp, *fw);
+out:
+       return rc;
+}
+
 static void rtl8169s_hw_phy_config(struct rtl8169_private *tp)
 {
        static const struct phy_reg phy_reg_init[] = {
@@ -2139,7 +2164,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
                { 0x0d, 0xf880 }
        };
        void __iomem *ioaddr = tp->mmio_addr;
-       const struct firmware *fw;
 
        rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
@@ -2203,11 +2227,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
 
        rtl_writephy(tp, 0x1f, 0x0005);
        rtl_writephy(tp, 0x05, 0x001b);
-       if (rtl_readphy(tp, 0x06) == 0xbf00 &&
-           request_firmware(&fw, FIRMWARE_8168D_1, &tp->pci_dev->dev) == 0) {
-               rtl_phy_write_fw(tp, fw);
-               release_firmware(fw);
-       } else {
+       if ((rtl_readphy(tp, 0x06) != 0xbf00) ||
+           (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) {
                netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
        }
 
@@ -2257,7 +2278,6 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
                { 0x0d, 0xf880 }
        };
        void __iomem *ioaddr = tp->mmio_addr;
-       const struct firmware *fw;
 
        rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
 
@@ -2312,11 +2332,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
 
        rtl_writephy(tp, 0x1f, 0x0005);
        rtl_writephy(tp, 0x05, 0x001b);
-       if (rtl_readphy(tp, 0x06) == 0xb300 &&
-           request_firmware(&fw, FIRMWARE_8168D_2, &tp->pci_dev->dev) == 0) {
-               rtl_phy_write_fw(tp, fw);
-               release_firmware(fw);
-       } else {
+       if ((rtl_readphy(tp, 0x06) != 0xb300) ||
+           (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) {
                netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
        }
 
@@ -3200,6 +3217,8 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 
        cancel_delayed_work_sync(&tp->task);
 
+       rtl_release_firmware(tp);
+
        unregister_netdev(dev);
 
        if (pci_dev_run_wake(pdev))
index 711449c6e675ed7dee9cee2343b4a3bbb01ba7d2..002bac7438434f8eb240a891815e1223b55b7c5c 100644 (file)
@@ -1153,6 +1153,9 @@ static int efx_wanted_channels(void)
        int count;
        int cpu;
 
+       if (rss_cpus)
+               return rss_cpus;
+
        if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) {
                printk(KERN_WARNING
                       "sfc: RSS disabled due to allocation failure\n");
@@ -1266,27 +1269,18 @@ static void efx_remove_interrupts(struct efx_nic *efx)
        efx->legacy_irq = 0;
 }
 
-struct efx_tx_queue *
-efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
-{
-       unsigned tx_channel_offset =
-               separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
-       EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels ||
-                           type >= EFX_TXQ_TYPES);
-       return &efx->channel[tx_channel_offset + index]->tx_queue[type];
-}
-
 static void efx_set_channels(struct efx_nic *efx)
 {
        struct efx_channel *channel;
        struct efx_tx_queue *tx_queue;
-       unsigned tx_channel_offset =
+
+       efx->tx_channel_offset =
                separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
 
        /* Channel pointers were set in efx_init_struct() but we now
         * need to clear them for TX queues in any RX-only channels. */
        efx_for_each_channel(channel, efx) {
-               if (channel->channel - tx_channel_offset >=
+               if (channel->channel - efx->tx_channel_offset >=
                    efx->n_tx_channels) {
                        efx_for_each_channel_tx_queue(tx_queue, channel)
                                tx_queue->channel = NULL;
index bdce66ddf93aa95ed27e78fc888d218b8266eef5..28df8665256a2167a5081fe4a69e3903ac22b1b5 100644 (file)
@@ -735,6 +735,7 @@ struct efx_nic {
        unsigned next_buffer_table;
        unsigned n_channels;
        unsigned n_rx_channels;
+       unsigned tx_channel_offset;
        unsigned n_tx_channels;
        unsigned int rx_buffer_len;
        unsigned int rx_buffer_order;
@@ -929,8 +930,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
             _channel = (_channel->channel + 1 < (_efx)->n_channels) ?  \
                     (_efx)->channel[_channel->channel + 1] : NULL)
 
-extern struct efx_tx_queue *
-efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type);
+static inline struct efx_tx_queue *
+efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
+{
+       EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels ||
+                           type >= EFX_TXQ_TYPES);
+       return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type];
+}
 
 static inline struct efx_tx_queue *
 efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
index 0e6bac5ec65b8a3c67f5460d06e512bbdeeac778..7cb301da747440dd9d14d8e68aced335450b2be0 100644 (file)
 MODULE_AUTHOR("Tilera");
 MODULE_LICENSE("GPL");
 
-
-#define IS_MULTICAST(mac_addr) \
-       (((u8 *)(mac_addr))[0] & 0x01)
-
-#define IS_BROADCAST(mac_addr) \
-       (((u16 *)(mac_addr))[0] == 0xffff)
-
-
 /*
  * Queue of incoming packets for a specific cpu and device.
  *
@@ -795,7 +787,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
                /*
                 * FIXME: Implement HW multicast filter.
                 */
-               if (!IS_MULTICAST(buf) && !IS_BROADCAST(buf)) {
+               if (is_unicast_ether_addr(buf)) {
                        /* Filter packets not for our address. */
                        const u8 *mine = dev->dev_addr;
                        filter = compare_ether_addr(mine, buf);
index 73a3e0d93237c97127e4eff1f31c52b4915f1119..715e7b47e7e987ff47c502c229686911cae17bc5 100644 (file)
@@ -2032,7 +2032,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
                        netdev_for_each_mc_addr(ha, dev) {
                                /* Only support group multicast for now.
                                 */
-                               if (!(ha->addr[0] & 1))
+                               if (!is_multicast_ether_addr(ha->addr))
                                        continue;
 
                                /* Ask CPM to run CRC and set bit in
index 593c104ab19997eacf5bc35b238d4676293d71c2..d776c4a8d3c1bda74b9699156d5b9690eed74863 100644 (file)
@@ -1021,13 +1021,15 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
                    (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) {
                        pr_debug("invalid frame detected (ignored)"
                                "offset[%u]=%u, length=%u, skb=%p\n",
-                                                       x, offset, temp, skb);
+                                                       x, offset, temp, skb_in);
                        if (!x)
                                goto error;
                        break;
 
                } else {
                        skb = skb_clone(skb_in, GFP_ATOMIC);
+                       if (!skb)
+                               goto error;
                        skb->len = temp;
                        skb->data = ((u8 *)skb_in->data) + offset;
                        skb_set_tail_pointer(skb, temp);
index 1ac9b568f1b0cfcc62e1fd7f7f1c32f0749849f5..c81a6512c683d4dee03d0b515895ce2846ebf4ec 100644 (file)
@@ -4120,6 +4120,7 @@ int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override)
               "hotplug event.\n");
 
 out:
+       release_firmware(fw);
        return ret;
 }
 
index 01880aa13e369af80b9e4059b7e60dc3c8907860..ea2e7d714bdad0888e070dc61faf5acfba26ff15 100644 (file)
@@ -954,6 +954,9 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah)
                                &adc_dc_cal_multi_sample;
                }
                ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+
+               if (AR_SREV_9287(ah))
+                       ah->supp_cals &= ~ADC_GAIN_CAL;
        }
 }
 
index 088f141f20064fffaf21849978d1efb5b51ac47c..749a93608664916f4c737bb15fa1d58fa03e204a 100644 (file)
@@ -226,6 +226,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
            eep->baseEepHeader.pwdclkind == 0)
                ah->need_an_top2_fixup = 1;
 
+       if ((common->bus_ops->ath_bus_type == ATH_USB) &&
+           (AR_SREV_9280(ah)))
+               eep->modalHeader[0].xpaBiasLvl = 0;
+
        return 0;
 }
 
index a099b3e87ed3c4477c6fcb24514cd43a7529054c..1ce506f231107a22893f9da8aba0faa8dde5e686 100644 (file)
@@ -433,6 +433,7 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
                        enum htc_endpoint_id ep_id, bool txok);
 
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_ani_work(struct work_struct *work);;
index 845b4c938d166090efc045ea11083e1cf0ce0789..f4d576bc3ccdbce3bef81d4702a756e9b900a34d 100644 (file)
@@ -301,6 +301,16 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
 
        priv->nstations++;
 
+       /*
+        * Set chainmask etc. on the target.
+        */
+       ret = ath9k_htc_update_cap_target(priv);
+       if (ret)
+               ath_dbg(common, ATH_DBG_CONFIG,
+                       "Failed to update capability in target\n");
+
+       priv->ah->is_monitoring = true;
+
        return 0;
 
 err_vif:
@@ -328,6 +338,7 @@ static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
        }
 
        priv->nstations--;
+       priv->ah->is_monitoring = false;
 
        return 0;
 }
@@ -419,7 +430,7 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
        return 0;
 }
 
-static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
 {
        struct ath9k_htc_cap_target tcap;
        int ret;
@@ -1186,6 +1197,20 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
                }
        }
 
+       /*
+        * Monitor interface should be added before
+        * IEEE80211_CONF_CHANGE_CHANNEL is handled.
+        */
+       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+               if (conf->flags & IEEE80211_CONF_MONITOR) {
+                       if (ath9k_htc_add_monitor_interface(priv))
+                               ath_err(common, "Failed to set monitor mode\n");
+                       else
+                               ath_dbg(common, ATH_DBG_CONFIG,
+                                       "HW opmode set to Monitor mode\n");
+               }
+       }
+
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
                struct ieee80211_channel *curchan = hw->conf.channel;
                int pos = curchan->hw_value;
@@ -1221,16 +1246,6 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
                ath_update_txpow(priv);
        }
 
-       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-               if (conf->flags & IEEE80211_CONF_MONITOR) {
-                       if (ath9k_htc_add_monitor_interface(priv))
-                               ath_err(common, "Failed to set monitor mode\n");
-                       else
-                               ath_dbg(common, ATH_DBG_CONFIG,
-                                       "HW opmode set to Monitor mode\n");
-               }
-       }
-
        if (changed & IEEE80211_CONF_CHANGE_IDLE) {
                mutex_lock(&priv->htc_pm_lock);
                if (!priv->ps_idle) {
index fde978665e07c63328e675823eb6d53f65fbf7c7..1afb8bb85756ee55e5a2a82d5f1f825279c803ea 100644 (file)
@@ -436,9 +436,10 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah)
 
 static int ath9k_hw_post_init(struct ath_hw *ah)
 {
+       struct ath_common *common = ath9k_hw_common(ah);
        int ecode;
 
-       if (!AR_SREV_9271(ah)) {
+       if (common->bus_ops->ath_bus_type != ATH_USB) {
                if (!ath9k_hw_chip_test(ah))
                        return -ENODEV;
        }
@@ -1213,7 +1214,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
        ah->txchainmask = common->tx_chainmask;
        ah->rxchainmask = common->rx_chainmask;
 
-       if (!ah->chip_fullsleep) {
+       if ((common->bus_ops->ath_bus_type != ATH_USB) && !ah->chip_fullsleep) {
                ath9k_hw_abortpcurecv(ah);
                if (!ath9k_hw_stopdmarecv(ah)) {
                        ath_dbg(common, ATH_DBG_XMIT,
index bd8a4134edebcae378d89fa9add3c2ae7f4dea9f..2176edede39b78db45e337e313c860802b92f66b 100644 (file)
@@ -518,22 +518,21 @@ static int prism2_config(struct pcmcia_device *link)
        hw_priv->link = link;
 
        /*
-        * Make sure the IRQ handler cannot proceed until at least
-        * dev->base_addr is initialized.
+        * We enable IRQ here, but IRQ handler will not proceed
+        * until dev->base_addr is set below. This protect us from
+        * receive interrupts when driver is not initialized.
         */
-       spin_lock_irqsave(&local->irq_init_lock, flags);
-
        ret = pcmcia_request_irq(link, prism2_interrupt);
        if (ret)
-               goto failed_unlock;
+               goto failed;
 
        ret = pcmcia_enable_device(link);
        if (ret)
-               goto failed_unlock;
+               goto failed;
 
+       spin_lock_irqsave(&local->irq_init_lock, flags);
        dev->irq = link->irq;
        dev->base_addr = link->resource[0]->start;
-
        spin_unlock_irqrestore(&local->irq_init_lock, flags);
 
        local->shutdown = 0;
@@ -546,8 +545,6 @@ static int prism2_config(struct pcmcia_device *link)
 
        return ret;
 
- failed_unlock:
-       spin_unlock_irqrestore(&local->irq_init_lock, flags);
  failed:
        kfree(hw_priv);
        prism2_release((u_long)link);
index 8d6ed5f6f46f4a423e31943dc70b70fd3727569f..ae438ed80c2fa73dcafc17577c54194f6cc054fb 100644 (file)
@@ -1973,6 +1973,13 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
 
        inta = ipw_read32(priv, IPW_INTA_RW);
        inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
+
+       if (inta == 0xFFFFFFFF) {
+               /* Hardware disappeared */
+               IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");
+               /* Only handle the cached INTA values */
+               inta = 0;
+       }
        inta &= (IPW_INTA_MASK_ALL & inta_mask);
 
        /* Add any cached INTA values that need to be handled */
index 76b2318a7dc776a460c335133289953cff8806fc..f618b9623e5a6d38753a8ee010fb61f4f8777820 100644 (file)
@@ -618,7 +618,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
        else
                *burst_possible = false;
 
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+       if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
                *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
 
        if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
index 5a0985d4ce1590b4e32efb5ded52861aabda451d..29884c00c4d53a4da03150e79987e6ed66fc6331 100644 (file)
@@ -420,6 +420,16 @@ int ssb_bus_scan(struct ssb_bus *bus,
                        bus->pcicore.dev = dev;
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
                        break;
+               case SSB_DEV_ETHERNET:
+                       if (bus->bustype == SSB_BUSTYPE_PCI) {
+                               if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
+                                   (bus->host_pci->device & 0xFF00) == 0x4300) {
+                                       /* This is a dangling ethernet core on a
+                                        * wireless device. Ignore it. */
+                                       continue;
+                               }
+                       }
+                       break;
                default:
                        break;
                }
index 38244f59cdd91e76acc63f7fb4d7b66a5a730fbf..ade0568c07a4e9ff3ab2fc56e9dc527ca58bdf72 100644 (file)
@@ -97,22 +97,26 @@ void vhost_poll_stop(struct vhost_poll *poll)
        remove_wait_queue(poll->wqh, &poll->wait);
 }
 
+static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
+                               unsigned seq)
+{
+       int left;
+       spin_lock_irq(&dev->work_lock);
+       left = seq - work->done_seq;
+       spin_unlock_irq(&dev->work_lock);
+       return left <= 0;
+}
+
 static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
 {
        unsigned seq;
-       int left;
        int flushing;
 
        spin_lock_irq(&dev->work_lock);
        seq = work->queue_seq;
        work->flushing++;
        spin_unlock_irq(&dev->work_lock);
-       wait_event(work->done, ({
-                  spin_lock_irq(&dev->work_lock);
-                  left = seq - work->done_seq <= 0;
-                  spin_unlock_irq(&dev->work_lock);
-                  left;
-       }));
+       wait_event(work->done, vhost_work_seq_done(dev, work, seq));
        spin_lock_irq(&dev->work_lock);
        flushing = --work->flushing;
        spin_unlock_irq(&dev->work_lock);
index fe3f59c14a02bb523aaaffc4f668b785fed06f01..333a7bb4cb9c0865543bc210c6df2613662950c9 100644 (file)
@@ -432,6 +432,9 @@ static void init_once(void *foo)
        mutex_init(&bdev->bd_mutex);
        INIT_LIST_HEAD(&bdev->bd_inodes);
        INIT_LIST_HEAD(&bdev->bd_list);
+#ifdef CONFIG_SYSFS
+       INIT_LIST_HEAD(&bdev->bd_holder_disks);
+#endif
        inode_init_once(&ei->vfs_inode);
        /* Initialize mutex for freeze. */
        mutex_init(&bdev->bd_fsfreeze_mutex);
@@ -779,6 +782,23 @@ static struct block_device *bd_start_claiming(struct block_device *bdev,
 }
 
 #ifdef CONFIG_SYSFS
+struct bd_holder_disk {
+       struct list_head        list;
+       struct gendisk          *disk;
+       int                     refcnt;
+};
+
+static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev,
+                                                 struct gendisk *disk)
+{
+       struct bd_holder_disk *holder;
+
+       list_for_each_entry(holder, &bdev->bd_holder_disks, list)
+               if (holder->disk == disk)
+                       return holder;
+       return NULL;
+}
+
 static int add_symlink(struct kobject *from, struct kobject *to)
 {
        return sysfs_create_link(from, to, kobject_name(to));
@@ -794,6 +814,8 @@ static void del_symlink(struct kobject *from, struct kobject *to)
  * @bdev: the claimed slave bdev
  * @disk: the holding disk
  *
+ * DON'T USE THIS UNLESS YOU'RE ALREADY USING IT.
+ *
  * This functions creates the following sysfs symlinks.
  *
  * - from "slaves" directory of the holder @disk to the claimed @bdev
@@ -817,47 +839,83 @@ static void del_symlink(struct kobject *from, struct kobject *to)
  */
 int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk)
 {
+       struct bd_holder_disk *holder;
        int ret = 0;
 
        mutex_lock(&bdev->bd_mutex);
 
-       WARN_ON_ONCE(!bdev->bd_holder || bdev->bd_holder_disk);
+       WARN_ON_ONCE(!bdev->bd_holder);
 
        /* FIXME: remove the following once add_disk() handles errors */
        if (WARN_ON(!disk->slave_dir || !bdev->bd_part->holder_dir))
                goto out_unlock;
 
-       ret = add_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
-       if (ret)
+       holder = bd_find_holder_disk(bdev, disk);
+       if (holder) {
+               holder->refcnt++;
                goto out_unlock;
+       }
 
-       ret = add_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
-       if (ret) {
-               del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+       holder = kzalloc(sizeof(*holder), GFP_KERNEL);
+       if (!holder) {
+               ret = -ENOMEM;
                goto out_unlock;
        }
 
-       bdev->bd_holder_disk = disk;
+       INIT_LIST_HEAD(&holder->list);
+       holder->disk = disk;
+       holder->refcnt = 1;
+
+       ret = add_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+       if (ret)
+               goto out_free;
+
+       ret = add_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
+       if (ret)
+               goto out_del;
+
+       list_add(&holder->list, &bdev->bd_holder_disks);
+       goto out_unlock;
+
+out_del:
+       del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+out_free:
+       kfree(holder);
 out_unlock:
        mutex_unlock(&bdev->bd_mutex);
        return ret;
 }
 EXPORT_SYMBOL_GPL(bd_link_disk_holder);
 
-static void bd_unlink_disk_holder(struct block_device *bdev)
+/**
+ * bd_unlink_disk_holder - destroy symlinks created by bd_link_disk_holder()
+ * @bdev: the calimed slave bdev
+ * @disk: the holding disk
+ *
+ * DON'T USE THIS UNLESS YOU'RE ALREADY USING IT.
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk)
 {
-       struct gendisk *disk = bdev->bd_holder_disk;
+       struct bd_holder_disk *holder;
 
-       bdev->bd_holder_disk = NULL;
-       if (!disk)
-               return;
+       mutex_lock(&bdev->bd_mutex);
 
-       del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
-       del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj);
+       holder = bd_find_holder_disk(bdev, disk);
+
+       if (!WARN_ON_ONCE(holder == NULL) && !--holder->refcnt) {
+               del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj);
+               del_symlink(bdev->bd_part->holder_dir,
+                           &disk_to_dev(disk)->kobj);
+               list_del_init(&holder->list);
+               kfree(holder);
+       }
+
+       mutex_unlock(&bdev->bd_mutex);
 }
-#else
-static inline void bd_unlink_disk_holder(struct block_device *bdev)
-{ }
+EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
 #endif
 
 /**
@@ -1380,7 +1438,6 @@ int blkdev_put(struct block_device *bdev, fmode_t mode)
                 * unblock evpoll if it was a write holder.
                 */
                if (bdev_free) {
-                       bd_unlink_disk_holder(bdev);
                        if (bdev->bd_write_holder) {
                                disk_unblock_events(bdev->bd_disk);
                                bdev->bd_write_holder = false;
index 0c6d5c549d840008b4dfff4e45e1aa6cbdcb88f8..274a2225038073ae92664113e31f0b2fc18040ab 100644 (file)
@@ -1357,8 +1357,8 @@ EXPORT_SYMBOL(d_alloc_name);
 
 void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
 {
-       BUG_ON(dentry->d_op);
-       BUG_ON(dentry->d_flags & (DCACHE_OP_HASH        |
+       WARN_ON_ONCE(dentry->d_op);
+       WARN_ON_ONCE(dentry->d_flags & (DCACHE_OP_HASH  |
                                DCACHE_OP_COMPARE       |
                                DCACHE_OP_REVALIDATE    |
                                DCACHE_OP_DELETE ));
index 08415b2a6d36f321bf67b5a697c4db676cb15f78..0f3998291f78e4fa08b5d3c102f6d8dcc120247a 100644 (file)
@@ -444,15 +444,9 @@ static void lease_release_private_callback(struct file_lock *fl)
        fl->fl_file->f_owner.signum = 0;
 }
 
-static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try)
-{
-       return fl->fl_file == try->fl_file;
-}
-
 static const struct lock_manager_operations lease_manager_ops = {
        .fl_break = lease_break_callback,
        .fl_release_private = lease_release_private_callback,
-       .fl_mylease = lease_mylease_callback,
        .fl_change = lease_modify,
 };
 
@@ -1405,7 +1399,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
        for (before = &inode->i_flock;
                        ((fl = *before) != NULL) && IS_LEASE(fl);
                        before = &fl->fl_next) {
-               if (lease->fl_lmops->fl_mylease(fl, lease))
+               if (fl->fl_file == filp)
                        my_before = before;
                else if (fl->fl_type == (F_INPROGRESS | F_UNLCK))
                        /*
similarity index 98%
rename from include/linux/nfs4_acl.h
rename to fs/nfsd/acl.h
index c9c05a78e9bb32438f866b9d99564cf87ff02287..34e5c40af5ef60d44673f992bfd186acab2e1d26 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  include/linux/nfs4_acl.c
- *
  *  Common NFSv4 ACL handling definitions.
  *
  *  Copyright (c) 2002 The Regents of the University of Michigan.
index c0fcb7ab7f6db42b9793dd2b59f853f92728db35..8b31e5f8795de8fb520e5f1a0676b60c93530c01 100644 (file)
@@ -1,4 +1,3 @@
-#define MSNFS  /* HACK HACK */
 /*
  * NFS exporting and validation.
  *
@@ -1444,9 +1443,6 @@ static struct flags {
        { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
        { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
        { NFSEXP_V4ROOT, {"v4root", ""}},
-#ifdef MSNFS
-       { NFSEXP_MSNFS, {"msnfs", ""}},
-#endif
        { 0, {"", ""}}
 };
 
similarity index 92%
rename from include/linux/nfsd_idmap.h
rename to fs/nfsd/idmap.h
index d4a2ac18bd4cfba2a6713aa6a492660264b94782..2f3be1321534375b65cac5705806edda29c6088d 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  include/linux/nfsd_idmap.h
- *
  *  Mapping of UID to name and vice versa.
  *
  *  Copyright (c) 2002, 2003 The Regents of the University of
@@ -56,8 +54,8 @@ static inline void nfsd_idmap_shutdown(void)
 }
 #endif
 
-int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
-int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
+__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
+__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
 int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *);
 int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *);
 
index 5b7e3021e06b874e6d4e802dae08164b39906485..2247fc91d5e9728e0796d45bb63c8784fb2da96e 100644 (file)
@@ -151,10 +151,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
        __be32  nfserr;
        u32     max_blocksize = svc_max_payload(rqstp);
 
-       dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
+       dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n",
                                SVCFH_fmt(&argp->fh),
                                (unsigned long) argp->count,
-                               (unsigned long) argp->offset);
+                               (unsigned long long) argp->offset);
 
        /* Obtain buffer pointer for payload.
         * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)
@@ -191,10 +191,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
        __be32  nfserr;
        unsigned long cnt = argp->len;
 
-       dprintk("nfsd: WRITE(3)    %s %d bytes at %ld%s\n",
+       dprintk("nfsd: WRITE(3)    %s %d bytes at %Lu%s\n",
                                SVCFH_fmt(&argp->fh),
                                argp->len,
-                               (unsigned long) argp->offset,
+                               (unsigned long long) argp->offset,
                                argp->stable? " stable" : "");
 
        fh_copy(&resp->fh, &argp->fh);
index e48052615159c24689989b5ebe0a803e0946755f..ad88f1c0a4c3f5d5f05173aafba65f143e6ec0f2 100644 (file)
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/nfs_fs.h>
-#include <linux/nfs4_acl.h>
+#include "acl.h"
 
 
 /* mode bit translations: */
index 21a63da305ffaf23e65b57a9a90ad5a5ea81a84c..3be975e189195daa59e76b5abb70d630d48361b7 100644 (file)
@@ -628,10 +628,8 @@ static int max_cb_time(void)
        return max(nfsd4_lease/10, (time_t)1) * HZ;
 }
 
-/* Reference counting, callback cleanup, etc., all look racy as heck.
- * And why is cl_cb_set an atomic? */
 
-int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
+static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
 {
        struct rpc_timeout      timeparms = {
                .to_initval     = max_cb_time(),
@@ -641,6 +639,7 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
                .net            = &init_net,
                .address        = (struct sockaddr *) &conn->cb_addr,
                .addrsize       = conn->cb_addrlen,
+               .saddress       = (struct sockaddr *) &conn->cb_saddr,
                .timeout        = &timeparms,
                .program        = &cb_program,
                .version        = 0,
@@ -657,6 +656,10 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
                args.protocol = XPRT_TRANSPORT_TCP;
                clp->cl_cb_ident = conn->cb_ident;
        } else {
+               if (!conn->cb_xprt)
+                       return -EINVAL;
+               clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+               clp->cl_cb_session = ses;
                args.bc_xprt = conn->cb_xprt;
                args.prognumber = clp->cl_cb_session->se_cb_prog;
                args.protocol = XPRT_TRANSPORT_BC_TCP;
@@ -679,14 +682,20 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason)
                (int)clp->cl_name.len, clp->cl_name.data, reason);
 }
 
+static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
+{
+       clp->cl_cb_state = NFSD4_CB_DOWN;
+       warn_no_callback_path(clp, reason);
+}
+
 static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
 {
        struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
 
        if (task->tk_status)
-               warn_no_callback_path(clp, task->tk_status);
+               nfsd4_mark_cb_down(clp, task->tk_status);
        else
-               atomic_set(&clp->cl_cb_set, 1);
+               clp->cl_cb_state = NFSD4_CB_UP;
 }
 
 static const struct rpc_call_ops nfsd4_cb_probe_ops = {
@@ -709,6 +718,11 @@ int set_callback_cred(void)
 
 static struct workqueue_struct *callback_wq;
 
+static void run_nfsd4_cb(struct nfsd4_callback *cb)
+{
+       queue_work(callback_wq, &cb->cb_work);
+}
+
 static void do_probe_callback(struct nfs4_client *clp)
 {
        struct nfsd4_callback *cb = &clp->cl_cb_null;
@@ -723,7 +737,7 @@ static void do_probe_callback(struct nfs4_client *clp)
 
        cb->cb_ops = &nfsd4_cb_probe_ops;
 
-       queue_work(callback_wq, &cb->cb_work);
+       run_nfsd4_cb(cb);
 }
 
 /*
@@ -732,14 +746,21 @@ static void do_probe_callback(struct nfs4_client *clp)
  */
 void nfsd4_probe_callback(struct nfs4_client *clp)
 {
+       /* XXX: atomicity?  Also, should we be using cl_cb_flags? */
+       clp->cl_cb_state = NFSD4_CB_UNKNOWN;
        set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags);
        do_probe_callback(clp);
 }
 
-void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
+void nfsd4_probe_callback_sync(struct nfs4_client *clp)
 {
-       BUG_ON(atomic_read(&clp->cl_cb_set));
+       nfsd4_probe_callback(clp);
+       flush_workqueue(callback_wq);
+}
 
+void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
+{
+       clp->cl_cb_state = NFSD4_CB_UNKNOWN;
        spin_lock(&clp->cl_lock);
        memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
        spin_unlock(&clp->cl_lock);
@@ -750,24 +771,14 @@ void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
  * If the slot is available, then mark it busy.  Otherwise, set the
  * thread for sleeping on the callback RPC wait queue.
  */
-static int nfsd41_cb_setup_sequence(struct nfs4_client *clp,
-               struct rpc_task *task)
+static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
 {
-       u32 *ptr = (u32 *)clp->cl_cb_session->se_sessionid.data;
-       int status = 0;
-
-       dprintk("%s: %u:%u:%u:%u\n", __func__,
-               ptr[0], ptr[1], ptr[2], ptr[3]);
-
        if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
                rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
                dprintk("%s slot is busy\n", __func__);
-               status = -EAGAIN;
-               goto out;
+               return false;
        }
-out:
-       dprintk("%s status=%d\n", __func__, status);
-       return status;
+       return true;
 }
 
 /*
@@ -780,20 +791,19 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
        struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
        struct nfs4_client *clp = dp->dl_client;
        u32 minorversion = clp->cl_minorversion;
-       int status = 0;
 
        cb->cb_minorversion = minorversion;
        if (minorversion) {
-               status = nfsd41_cb_setup_sequence(clp, task);
-               if (status) {
-                       if (status != -EAGAIN) {
-                               /* terminate rpc task */
-                               task->tk_status = status;
-                               task->tk_action = NULL;
-                       }
+               if (!nfsd41_cb_get_slot(clp, task))
                        return;
-               }
        }
+       spin_lock(&clp->cl_lock);
+       if (list_empty(&cb->cb_per_client)) {
+               /* This is the first call, not a restart */
+               cb->cb_done = false;
+               list_add(&cb->cb_per_client, &clp->cl_callbacks);
+       }
+       spin_unlock(&clp->cl_lock);
        rpc_call_start(task);
 }
 
@@ -829,15 +839,18 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
 
        nfsd4_cb_done(task, calldata);
 
-       if (current_rpc_client == NULL) {
-               /* We're shutting down; give up. */
-               /* XXX: err, or is it ok just to fall through
-                * and rpc_restart_call? */
+       if (current_rpc_client != task->tk_client) {
+               /* We're shutting down or changing cl_cb_client; leave
+                * it to nfsd4_process_cb_update to restart the call if
+                * necessary. */
                return;
        }
 
+       if (cb->cb_done)
+               return;
        switch (task->tk_status) {
        case 0:
+               cb->cb_done = true;
                return;
        case -EBADHANDLE:
        case -NFS4ERR_BAD_STATEID:
@@ -846,32 +859,30 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
                break;
        default:
                /* Network partition? */
-               atomic_set(&clp->cl_cb_set, 0);
-               warn_no_callback_path(clp, task->tk_status);
-               if (current_rpc_client != task->tk_client) {
-                       /* queue a callback on the new connection: */
-                       atomic_inc(&dp->dl_count);
-                       nfsd4_cb_recall(dp);
-                       return;
-               }
+               nfsd4_mark_cb_down(clp, task->tk_status);
        }
        if (dp->dl_retries--) {
                rpc_delay(task, 2*HZ);
                task->tk_status = 0;
                rpc_restart_call_prepare(task);
                return;
-       } else {
-               atomic_set(&clp->cl_cb_set, 0);
-               warn_no_callback_path(clp, task->tk_status);
        }
+       nfsd4_mark_cb_down(clp, task->tk_status);
+       cb->cb_done = true;
 }
 
 static void nfsd4_cb_recall_release(void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
+       struct nfs4_client *clp = cb->cb_clp;
        struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
 
-       nfs4_put_delegation(dp);
+       if (cb->cb_done) {
+               spin_lock(&clp->cl_lock);
+               list_del(&cb->cb_per_client);
+               spin_unlock(&clp->cl_lock);
+               nfs4_put_delegation(dp);
+       }
 }
 
 static const struct rpc_call_ops nfsd4_cb_recall_ops = {
@@ -906,16 +917,33 @@ void nfsd4_shutdown_callback(struct nfs4_client *clp)
        flush_workqueue(callback_wq);
 }
 
-void nfsd4_release_cb(struct nfsd4_callback *cb)
+static void nfsd4_release_cb(struct nfsd4_callback *cb)
 {
        if (cb->cb_ops->rpc_release)
                cb->cb_ops->rpc_release(cb);
 }
 
-void nfsd4_process_cb_update(struct nfsd4_callback *cb)
+/* requires cl_lock: */
+static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp)
+{
+       struct nfsd4_session *s;
+       struct nfsd4_conn *c;
+
+       list_for_each_entry(s, &clp->cl_sessions, se_perclnt) {
+               list_for_each_entry(c, &s->se_conns, cn_persession) {
+                       if (c->cn_flags & NFS4_CDFC4_BACK)
+                               return c;
+               }
+       }
+       return NULL;
+}
+
+static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
 {
        struct nfs4_cb_conn conn;
        struct nfs4_client *clp = cb->cb_clp;
+       struct nfsd4_session *ses = NULL;
+       struct nfsd4_conn *c;
        int err;
 
        /*
@@ -926,6 +954,10 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb)
                rpc_shutdown_client(clp->cl_cb_client);
                clp->cl_cb_client = NULL;
        }
+       if (clp->cl_cb_conn.cb_xprt) {
+               svc_xprt_put(clp->cl_cb_conn.cb_xprt);
+               clp->cl_cb_conn.cb_xprt = NULL;
+       }
        if (test_bit(NFSD4_CLIENT_KILL, &clp->cl_cb_flags))
                return;
        spin_lock(&clp->cl_lock);
@@ -936,11 +968,22 @@ void nfsd4_process_cb_update(struct nfsd4_callback *cb)
        BUG_ON(!clp->cl_cb_flags);
        clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags);
        memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn));
+       c = __nfsd4_find_backchannel(clp);
+       if (c) {
+               svc_xprt_get(c->cn_xprt);
+               conn.cb_xprt = c->cn_xprt;
+               ses = c->cn_session;
+       }
        spin_unlock(&clp->cl_lock);
 
-       err = setup_callback_client(clp, &conn);
-       if (err)
+       err = setup_callback_client(clp, &conn, ses);
+       if (err) {
                warn_no_callback_path(clp, err);
+               return;
+       }
+       /* Yay, the callback channel's back! Restart any callbacks: */
+       list_for_each_entry(cb, &clp->cl_callbacks, cb_per_client)
+               run_nfsd4_cb(cb);
 }
 
 void nfsd4_do_callback_rpc(struct work_struct *w)
@@ -965,10 +1008,11 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
 void nfsd4_cb_recall(struct nfs4_delegation *dp)
 {
        struct nfsd4_callback *cb = &dp->dl_recall;
+       struct nfs4_client *clp = dp->dl_client;
 
        dp->dl_retries = 1;
        cb->cb_op = dp;
-       cb->cb_clp = dp->dl_client;
+       cb->cb_clp = clp;
        cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
        cb->cb_msg.rpc_argp = cb;
        cb->cb_msg.rpc_resp = cb;
@@ -977,5 +1021,8 @@ void nfsd4_cb_recall(struct nfs4_delegation *dp)
        cb->cb_ops = &nfsd4_cb_recall_ops;
        dp->dl_retries = 1;
 
-       queue_work(callback_wq, &dp->dl_recall.cb_work);
+       INIT_LIST_HEAD(&cb->cb_per_client);
+       cb->cb_done = true;
+
+       run_nfsd4_cb(&dp->dl_recall);
 }
index f0695e815f0ec9e53a2e9934392ac820d36e442e..6d2c397d458b6c9481998711ad1bb406fd6fd79c 100644 (file)
  */
 
 #include <linux/module.h>
-#include <linux/nfsd_idmap.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include "idmap.h"
+#include "nfsd.h"
 
 /*
  * Cache entry
@@ -514,7 +515,7 @@ rqst_authname(struct svc_rqst *rqstp)
        return clp->name;
 }
 
-static int
+static __be32
 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
                uid_t *id)
 {
@@ -524,15 +525,15 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
        int ret;
 
        if (namelen + 1 > sizeof(key.name))
-               return -EINVAL;
+               return nfserr_badowner;
        memcpy(key.name, name, namelen);
        key.name[namelen] = '\0';
        strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
        ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item);
        if (ret == -ENOENT)
-               ret = -ESRCH; /* nfserr_badname */
+               return nfserr_badowner;
        if (ret)
-               return ret;
+               return nfserrno(ret);
        *id = item->id;
        cache_put(&item->h, &nametoid_cache);
        return 0;
@@ -560,14 +561,14 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
        return ret;
 }
 
-int
+__be32
 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
                __u32 *id)
 {
        return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
 }
 
-int
+__be32
 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
                __u32 *id)
 {
index 0cdfd022bb7b307d344989f493b9873b903dd22d..db52546143d1290ba8f1510a94b8db0054b45200 100644 (file)
@@ -604,9 +604,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        return status;
 }
 
-static __be32
-nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
-             void *arg)
+static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
 {
        struct svc_fh tmp_fh;
        __be32 ret;
@@ -615,13 +613,19 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        ret = exp_pseudoroot(rqstp, &tmp_fh);
        if (ret)
                return ret;
-       if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) {
+       if (tmp_fh.fh_dentry == fh->fh_dentry) {
                fh_put(&tmp_fh);
                return nfserr_noent;
        }
        fh_put(&tmp_fh);
-       return nfsd_lookup(rqstp, &cstate->current_fh,
-                          "..", 2, &cstate->current_fh);
+       return nfsd_lookup(rqstp, fh, "..", 2, fh);
+}
+
+static __be32
+nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             void *arg)
+{
+       return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
 }
 
 static __be32
@@ -769,9 +773,35 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        } else
                secinfo->si_exp = exp;
        dput(dentry);
+       if (cstate->minorversion)
+               /* See rfc 5661 section 2.6.3.1.1.8 */
+               fh_put(&cstate->current_fh);
        return err;
 }
 
+static __be32
+nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+             struct nfsd4_secinfo_no_name *sin)
+{
+       __be32 err;
+
+       switch (sin->sin_style) {
+       case NFS4_SECINFO_STYLE4_CURRENT_FH:
+               break;
+       case NFS4_SECINFO_STYLE4_PARENT:
+               err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
+               if (err)
+                       return err;
+               break;
+       default:
+               return nfserr_inval;
+       }
+       exp_get(cstate->current_fh.fh_export);
+       sin->sin_exp = cstate->current_fh.fh_export;
+       fh_put(&cstate->current_fh);
+       return nfs_ok;
+}
+
 static __be32
 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
              struct nfsd4_setattr *setattr)
@@ -974,8 +1004,8 @@ static const char *nfsd4_op_name(unsigned opnum);
  * Also note, enforced elsewhere:
  *     - SEQUENCE other than as first op results in
  *       NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
- *     - BIND_CONN_TO_SESSION must be the only op in its compound
- *       (Will be enforced in nfsd4_bind_conn_to_session().)
+ *     - BIND_CONN_TO_SESSION must be the only op in its compound.
+ *       (Enforced in nfsd4_bind_conn_to_session().)
  *     - DESTROY_SESSION must be the final operation in a compound, if
  *       sessionid's in SEQUENCE and DESTROY_SESSION are the same.
  *       (Enforced in nfsd4_destroy_session().)
@@ -1126,10 +1156,6 @@ encode_op:
 
                nfsd4_increment_op_stats(op->opnum);
        }
-       if (!rqstp->rq_usedeferral && status == nfserr_dropit) {
-               dprintk("%s Dropit - send NFS4ERR_DELAY\n", __func__);
-               status = nfserr_jukebox;
-       }
 
        resp->cstate.status = status;
        fh_put(&resp->cstate.current_fh);
@@ -1300,6 +1326,11 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
                .op_name = "OP_EXCHANGE_ID",
        },
+       [OP_BIND_CONN_TO_SESSION] = {
+               .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
+               .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
+               .op_name = "OP_BIND_CONN_TO_SESSION",
+       },
        [OP_CREATE_SESSION] = {
                .op_func = (nfsd4op_func)nfsd4_create_session,
                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
@@ -1320,6 +1351,10 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_flags = ALLOWED_WITHOUT_FH,
                .op_name = "OP_RECLAIM_COMPLETE",
        },
+       [OP_SECINFO_NO_NAME] = {
+               .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
+               .op_name = "OP_SECINFO_NO_NAME",
+       },
 };
 
 static const char *nfsd4_op_name(unsigned opnum)
index 7e26caab2a262befd2c74af594d076e0ebb40121..ffb59ef6f82f71a3813139bde209f53bccd54aca 100644 (file)
@@ -302,7 +302,6 @@ purge_old(struct dentry *parent, struct dentry *child)
 {
        int status;
 
-       /* note: we currently use this path only for minorversion 0 */
        if (nfs4_has_reclaimed_state(child->d_name.name, false))
                return 0;
 
index fbd18c3074bbb54aad024e08024b31fac9fc7d53..d98d0213285d8dfa2a4b178c6ae8972318f171fc 100644 (file)
@@ -230,7 +230,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
        dp->dl_client = clp;
        get_nfs4_file(fp);
        dp->dl_file = fp;
-       nfs4_file_get_access(fp, O_RDONLY);
+       dp->dl_vfs_file = find_readable_file(fp);
+       get_file(dp->dl_vfs_file);
        dp->dl_flock = NULL;
        dp->dl_type = type;
        dp->dl_stateid.si_boot = boot_time;
@@ -252,6 +253,7 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
        if (atomic_dec_and_test(&dp->dl_count)) {
                dprintk("NFSD: freeing dp %p\n",dp);
                put_nfs4_file(dp->dl_file);
+               fput(dp->dl_vfs_file);
                kmem_cache_free(deleg_slab, dp);
                num_delegations--;
        }
@@ -265,12 +267,10 @@ nfs4_put_delegation(struct nfs4_delegation *dp)
 static void
 nfs4_close_delegation(struct nfs4_delegation *dp)
 {
-       struct file *filp = find_readable_file(dp->dl_file);
-
        dprintk("NFSD: close_delegation dp %p\n",dp);
+       /* XXX: do we even need this check?: */
        if (dp->dl_flock)
-               vfs_setlease(filp, F_UNLCK, &dp->dl_flock);
-       nfs4_file_put_access(dp->dl_file, O_RDONLY);
+               vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock);
 }
 
 /* Called under the state lock. */
@@ -642,6 +642,7 @@ static void nfsd4_conn_lost(struct svc_xpt_user *u)
                free_conn(c);
        }
        spin_unlock(&clp->cl_lock);
+       nfsd4_probe_callback(clp);
 }
 
 static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
@@ -679,15 +680,12 @@ static int nfsd4_register_conn(struct nfsd4_conn *conn)
        return register_xpt_user(conn->cn_xprt, &conn->cn_xpt_user);
 }
 
-static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
+static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses, u32 dir)
 {
        struct nfsd4_conn *conn;
-       u32 flags = NFS4_CDFC4_FORE;
        int ret;
 
-       if (ses->se_flags & SESSION4_BACK_CHAN)
-               flags |= NFS4_CDFC4_BACK;
-       conn = alloc_conn(rqstp, flags);
+       conn = alloc_conn(rqstp, dir);
        if (!conn)
                return nfserr_jukebox;
        nfsd4_hash_conn(conn, ses);
@@ -698,6 +696,17 @@ static __be32 nfsd4_new_conn(struct svc_rqst *rqstp, struct nfsd4_session *ses)
        return nfs_ok;
 }
 
+static __be32 nfsd4_new_conn_from_crses(struct svc_rqst *rqstp, struct nfsd4_session *ses)
+{
+       u32 dir = NFS4_CDFC4_FORE;
+
+       if (ses->se_flags & SESSION4_BACK_CHAN)
+               dir |= NFS4_CDFC4_BACK;
+
+       return nfsd4_new_conn(rqstp, ses, dir);
+}
+
+/* must be called under client_lock */
 static void nfsd4_del_conns(struct nfsd4_session *s)
 {
        struct nfs4_client *clp = s->se_client;
@@ -749,6 +758,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
         */
        slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
        numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
+       if (numslots < 1)
+               return NULL;
 
        new = alloc_session(slotsize, numslots);
        if (!new) {
@@ -769,25 +780,30 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n
        idx = hash_sessionid(&new->se_sessionid);
        spin_lock(&client_lock);
        list_add(&new->se_hash, &sessionid_hashtbl[idx]);
+       spin_lock(&clp->cl_lock);
        list_add(&new->se_perclnt, &clp->cl_sessions);
+       spin_unlock(&clp->cl_lock);
        spin_unlock(&client_lock);
 
-       status = nfsd4_new_conn(rqstp, new);
+       status = nfsd4_new_conn_from_crses(rqstp, new);
        /* whoops: benny points out, status is ignored! (err, or bogus) */
        if (status) {
                free_session(&new->se_ref);
                return NULL;
        }
-       if (!clp->cl_cb_session && (cses->flags & SESSION4_BACK_CHAN)) {
+       if (cses->flags & SESSION4_BACK_CHAN) {
                struct sockaddr *sa = svc_addr(rqstp);
-
-               clp->cl_cb_session = new;
-               clp->cl_cb_conn.cb_xprt = rqstp->rq_xprt;
-               svc_xprt_get(rqstp->rq_xprt);
+               /*
+                * This is a little silly; with sessions there's no real
+                * use for the callback address.  Use the peer address
+                * as a reasonable default for now, but consider fixing
+                * the rpc client not to require an address in the
+                * future:
+                */
                rpc_copy_addr((struct sockaddr *)&clp->cl_cb_conn.cb_addr, sa);
                clp->cl_cb_conn.cb_addrlen = svc_addr_len(sa);
-               nfsd4_probe_callback(clp);
        }
+       nfsd4_probe_callback(clp);
        return new;
 }
 
@@ -817,7 +833,9 @@ static void
 unhash_session(struct nfsd4_session *ses)
 {
        list_del(&ses->se_hash);
+       spin_lock(&ses->se_client->cl_lock);
        list_del(&ses->se_perclnt);
+       spin_unlock(&ses->se_client->cl_lock);
 }
 
 /* must be called under the client_lock */
@@ -923,8 +941,10 @@ unhash_client_locked(struct nfs4_client *clp)
 
        mark_client_expired(clp);
        list_del(&clp->cl_lru);
+       spin_lock(&clp->cl_lock);
        list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
                list_del_init(&ses->se_hash);
+       spin_unlock(&clp->cl_lock);
 }
 
 static void
@@ -1051,12 +1071,13 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
 
        memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
        atomic_set(&clp->cl_refcount, 0);
-       atomic_set(&clp->cl_cb_set, 0);
+       clp->cl_cb_state = NFSD4_CB_UNKNOWN;
        INIT_LIST_HEAD(&clp->cl_idhash);
        INIT_LIST_HEAD(&clp->cl_strhash);
        INIT_LIST_HEAD(&clp->cl_openowners);
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_lru);
+       INIT_LIST_HEAD(&clp->cl_callbacks);
        spin_lock_init(&clp->cl_lock);
        INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
        clp->cl_time = get_seconds();
@@ -1132,54 +1153,55 @@ find_unconfirmed_client(clientid_t *clid)
        return NULL;
 }
 
-/*
- * Return 1 iff clp's clientid establishment method matches the use_exchange_id
- * parameter. Matching is based on the fact the at least one of the
- * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1
- *
- * FIXME: we need to unify the clientid namespaces for nfsv4.x
- * and correctly deal with client upgrade/downgrade in EXCHANGE_ID
- * and SET_CLIENTID{,_CONFIRM}
- */
-static inline int
-match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id)
+static bool clp_used_exchangeid(struct nfs4_client *clp)
 {
-       bool has_exchange_flags = (clp->cl_exchange_flags != 0);
-       return use_exchange_id == has_exchange_flags;
-}
+       return clp->cl_exchange_flags != 0;
+} 
 
 static struct nfs4_client *
-find_confirmed_client_by_str(const char *dname, unsigned int hashval,
-                            bool use_exchange_id)
+find_confirmed_client_by_str(const char *dname, unsigned int hashval)
 {
        struct nfs4_client *clp;
 
        list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
-               if (same_name(clp->cl_recdir, dname) &&
-                   match_clientid_establishment(clp, use_exchange_id))
+               if (same_name(clp->cl_recdir, dname))
                        return clp;
        }
        return NULL;
 }
 
 static struct nfs4_client *
-find_unconfirmed_client_by_str(const char *dname, unsigned int hashval,
-                              bool use_exchange_id)
+find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
 {
        struct nfs4_client *clp;
 
        list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
-               if (same_name(clp->cl_recdir, dname) &&
-                   match_clientid_establishment(clp, use_exchange_id))
+               if (same_name(clp->cl_recdir, dname))
                        return clp;
        }
        return NULL;
 }
 
+static void rpc_svcaddr2sockaddr(struct sockaddr *sa, unsigned short family, union svc_addr_u *svcaddr)
+{
+       switch (family) {
+       case AF_INET:
+               ((struct sockaddr_in *)sa)->sin_family = AF_INET;
+               ((struct sockaddr_in *)sa)->sin_addr = svcaddr->addr;
+               return;
+       case AF_INET6:
+               ((struct sockaddr_in6 *)sa)->sin6_family = AF_INET6;
+               ((struct sockaddr_in6 *)sa)->sin6_addr = svcaddr->addr6;
+               return;
+       }
+}
+
 static void
-gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid)
+gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, struct svc_rqst *rqstp)
 {
        struct nfs4_cb_conn *conn = &clp->cl_cb_conn;
+       struct sockaddr *sa = svc_addr(rqstp);
+       u32 scopeid = rpc_get_scope_id(sa);
        unsigned short expected_family;
 
        /* Currently, we only support tcp and tcp6 for the callback channel */
@@ -1205,6 +1227,7 @@ gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se, u32 scopeid)
 
        conn->cb_prog = se->se_callback_prog;
        conn->cb_ident = se->se_callback_ident;
+       rpc_svcaddr2sockaddr((struct sockaddr *)&conn->cb_saddr, expected_family, &rqstp->rq_daddr);
        return;
 out_err:
        conn->cb_addr.ss_family = AF_UNSPEC;
@@ -1344,7 +1367,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
        case SP4_NONE:
                break;
        case SP4_SSV:
-               return nfserr_encr_alg_unsupp;
+               return nfserr_serverfault;
        default:
                BUG();                          /* checked by xdr code */
        case SP4_MACH_CRED:
@@ -1361,8 +1384,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
        nfs4_lock_state();
        status = nfs_ok;
 
-       conf = find_confirmed_client_by_str(dname, strhashval, true);
+       conf = find_confirmed_client_by_str(dname, strhashval);
        if (conf) {
+               if (!clp_used_exchangeid(conf)) {
+                       status = nfserr_clid_inuse; /* XXX: ? */
+                       goto out;
+               }
                if (!same_verf(&verf, &conf->cl_verifier)) {
                        /* 18.35.4 case 8 */
                        if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) {
@@ -1403,7 +1430,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
                goto out;
        }
 
-       unconf  = find_unconfirmed_client_by_str(dname, strhashval, true);
+       unconf  = find_unconfirmed_client_by_str(dname, strhashval);
        if (unconf) {
                /*
                 * Possible retry or client restart.  Per 18.35.4 case 4,
@@ -1560,6 +1587,8 @@ nfsd4_create_session(struct svc_rqst *rqstp,
        status = nfs_ok;
        memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
               NFS4_MAX_SESSIONID_LEN);
+       memcpy(&cr_ses->fore_channel, &new->se_fchannel,
+               sizeof(struct nfsd4_channel_attrs));
        cs_slot->sl_seqid++;
        cr_ses->seqid = cs_slot->sl_seqid;
 
@@ -1581,6 +1610,45 @@ static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
        return argp->opcnt == resp->opcnt;
 }
 
+static __be32 nfsd4_map_bcts_dir(u32 *dir)
+{
+       switch (*dir) {
+       case NFS4_CDFC4_FORE:
+       case NFS4_CDFC4_BACK:
+               return nfs_ok;
+       case NFS4_CDFC4_FORE_OR_BOTH:
+       case NFS4_CDFC4_BACK_OR_BOTH:
+               *dir = NFS4_CDFC4_BOTH;
+               return nfs_ok;
+       };
+       return nfserr_inval;
+}
+
+__be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
+                    struct nfsd4_compound_state *cstate,
+                    struct nfsd4_bind_conn_to_session *bcts)
+{
+       __be32 status;
+
+       if (!nfsd4_last_compound_op(rqstp))
+               return nfserr_not_only_op;
+       spin_lock(&client_lock);
+       cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid);
+       /* Sorta weird: we only need the refcnt'ing because new_conn acquires
+        * client_lock iself: */
+       if (cstate->session) {
+               nfsd4_get_session(cstate->session);
+               atomic_inc(&cstate->session->se_client->cl_refcount);
+       }
+       spin_unlock(&client_lock);
+       if (!cstate->session)
+               return nfserr_badsession;
+
+       status = nfsd4_map_bcts_dir(&bcts->dir);
+       nfsd4_new_conn(rqstp, cstate->session, bcts->dir);
+       return nfs_ok;
+}
+
 static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
 {
        if (!session)
@@ -1619,8 +1687,7 @@ nfsd4_destroy_session(struct svc_rqst *r,
        spin_unlock(&client_lock);
 
        nfs4_lock_state();
-       /* wait for callbacks */
-       nfsd4_shutdown_callback(ses->se_client);
+       nfsd4_probe_callback_sync(ses->se_client);
        nfs4_unlock_state();
 
        nfsd4_del_conns(ses);
@@ -1733,8 +1800,12 @@ nfsd4_sequence(struct svc_rqst *rqstp,
 out:
        /* Hold a session reference until done processing the compound. */
        if (cstate->session) {
+               struct nfs4_client *clp = session->se_client;
+
                nfsd4_get_session(cstate->session);
-               atomic_inc(&session->se_client->cl_refcount);
+               atomic_inc(&clp->cl_refcount);
+               if (clp->cl_cb_state == NFSD4_CB_DOWN)
+                       seq->status_flags |= SEQ4_STATUS_CB_PATH_DOWN;
        }
        kfree(conn);
        spin_unlock(&client_lock);
@@ -1775,7 +1846,6 @@ __be32
 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                  struct nfsd4_setclientid *setclid)
 {
-       struct sockaddr         *sa = svc_addr(rqstp);
        struct xdr_netobj       clname = { 
                .len = setclid->se_namelen,
                .data = setclid->se_name,
@@ -1801,10 +1871,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        strhashval = clientstr_hashval(dname);
 
        nfs4_lock_state();
-       conf = find_confirmed_client_by_str(dname, strhashval, false);
+       conf = find_confirmed_client_by_str(dname, strhashval);
        if (conf) {
                /* RFC 3530 14.2.33 CASE 0: */
                status = nfserr_clid_inuse;
+               if (clp_used_exchangeid(conf))
+                       goto out;
                if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) {
                        char addr_str[INET6_ADDRSTRLEN];
                        rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str,
@@ -1819,7 +1891,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
         * has a description of SETCLIENTID request processing consisting
         * of 5 bullet points, labeled as CASE0 - CASE4 below.
         */
-       unconf = find_unconfirmed_client_by_str(dname, strhashval, false);
+       unconf = find_unconfirmed_client_by_str(dname, strhashval);
        status = nfserr_resource;
        if (!conf) {
                /*
@@ -1876,7 +1948,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
         * for consistent minorversion use throughout:
         */
        new->cl_minorversion = 0;
-       gen_callback(new, setclid, rpc_get_scope_id(sa));
+       gen_callback(new, setclid, rqstp);
        add_to_unconfirmed(new, strhashval);
        setclid->se_clientid.cl_boot = new->cl_clientid.cl_boot;
        setclid->se_clientid.cl_id = new->cl_clientid.cl_id;
@@ -1935,7 +2007,6 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
                        status = nfserr_clid_inuse;
                else {
-                       atomic_set(&conf->cl_cb_set, 0);
                        nfsd4_change_callback(conf, &unconf->cl_cb_conn);
                        nfsd4_probe_callback(conf);
                        expire_client(unconf);
@@ -1964,7 +2035,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                        unsigned int hash =
                                clientstr_hashval(unconf->cl_recdir);
                        conf = find_confirmed_client_by_str(unconf->cl_recdir,
-                                                           hash, false);
+                                                           hash);
                        if (conf) {
                                nfsd4_remove_clid_dir(conf);
                                expire_client(conf);
@@ -2300,41 +2371,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
        nfsd4_cb_recall(dp);
 }
 
-/*
- * The file_lock is being reapd.
- *
- * Called by locks_free_lock() with lock_flocks() held.
- */
-static
-void nfsd_release_deleg_cb(struct file_lock *fl)
-{
-       struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
-
-       dprintk("NFSD nfsd_release_deleg_cb: fl %p dp %p dl_count %d\n", fl,dp, atomic_read(&dp->dl_count));
-
-       if (!(fl->fl_flags & FL_LEASE) || !dp)
-               return;
-       dp->dl_flock = NULL;
-}
-
-/*
- * Called from setlease() with lock_flocks() held
- */
-static
-int nfsd_same_client_deleg_cb(struct file_lock *onlist, struct file_lock *try)
-{
-       struct nfs4_delegation *onlistd =
-               (struct nfs4_delegation *)onlist->fl_owner;
-       struct nfs4_delegation *tryd =
-               (struct nfs4_delegation *)try->fl_owner;
-
-       if (onlist->fl_lmops != try->fl_lmops)
-               return 0;
-
-       return onlistd->dl_client == tryd->dl_client;
-}
-
-
 static
 int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
 {
@@ -2346,8 +2382,6 @@ int nfsd_change_deleg_cb(struct file_lock **onlist, int arg)
 
 static const struct lock_manager_operations nfsd_lease_mng_ops = {
        .fl_break = nfsd_break_deleg_cb,
-       .fl_release_private = nfsd_release_deleg_cb,
-       .fl_mylease = nfsd_same_client_deleg_cb,
        .fl_change = nfsd_change_deleg_cb,
 };
 
@@ -2514,8 +2548,6 @@ static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
        if (!fp->fi_fds[oflag]) {
                status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
                        &fp->fi_fds[oflag]);
-               if (status == nfserr_dropit)
-                       status = nfserr_jukebox;
                if (status)
                        return status;
        }
@@ -2596,6 +2628,19 @@ nfs4_set_claim_prev(struct nfsd4_open *open)
        open->op_stateowner->so_client->cl_firststate = 1;
 }
 
+/* Should we give out recallable state?: */
+static bool nfsd4_cb_channel_good(struct nfs4_client *clp)
+{
+       if (clp->cl_cb_state == NFSD4_CB_UP)
+               return true;
+       /*
+        * In the sessions case, since we don't have to establish a
+        * separate connection for callbacks, we assume it's OK
+        * until we hear otherwise:
+        */
+       return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN;
+}
+
 /*
  * Attempt to hand out a delegation.
  */
@@ -2604,10 +2649,11 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
 {
        struct nfs4_delegation *dp;
        struct nfs4_stateowner *sop = stp->st_stateowner;
-       int cb_up = atomic_read(&sop->so_client->cl_cb_set);
+       int cb_up;
        struct file_lock *fl;
        int status, flag = 0;
 
+       cb_up = nfsd4_cb_channel_good(sop->so_client);
        flag = NFS4_OPEN_DELEGATE_NONE;
        open->op_recall = 0;
        switch (open->op_claim_type) {
@@ -2655,7 +2701,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        dp->dl_flock = fl;
 
        /* vfs_setlease checks to see if delegation should be handed out.
-        * the lock_manager callbacks fl_mylease and fl_change are used
+        * the lock_manager callback fl_change is used
         */
        if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) {
                dprintk("NFSD: setlease failed [%d], no delegation\n", status);
@@ -2794,7 +2840,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        renew_client(clp);
        status = nfserr_cb_path_down;
        if (!list_empty(&clp->cl_delegations)
-                       && !atomic_read(&clp->cl_cb_set))
+                       && clp->cl_cb_state != NFSD4_CB_UP)
                goto out;
        status = nfs_ok;
 out:
@@ -3081,9 +3127,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
                if (status)
                        goto out;
                renew_client(dp->dl_client);
-               if (filpp)
+               if (filpp) {
                        *filpp = find_readable_file(dp->dl_file);
-               BUG_ON(!*filpp);
+                       BUG_ON(!*filpp);
+               }
        } else { /* open or lock stateid */
                stp = find_stateid(stateid, flags);
                if (!stp)
@@ -4107,7 +4154,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id)
        unsigned int strhashval = clientstr_hashval(name);
        struct nfs4_client *clp;
 
-       clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id);
+       clp = find_confirmed_client_by_str(name, strhashval);
        return clp ? 1 : 0;
 }
 
index f35a94a0402677d36193c9fcb57992edcc061e9d..956629b9cdc9c841a0f428ad12e9687cec21295f 100644 (file)
 #include <linux/namei.h>
 #include <linux/statfs.h>
 #include <linux/utsname.h>
-#include <linux/nfsd_idmap.h>
-#include <linux/nfs4_acl.h>
 #include <linux/sunrpc/svcauth_gss.h>
 
+#include "idmap.h"
+#include "acl.h"
 #include "xdr4.h"
 #include "vfs.h"
 
+
 #define NFSDDBG_FACILITY               NFSDDBG_XDR
 
 /*
@@ -288,17 +289,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                        len += XDR_QUADLEN(dummy32) << 2;
                        READMEM(buf, dummy32);
                        ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
-                       host_err = 0;
+                       status = nfs_ok;
                        if (ace->whotype != NFS4_ACL_WHO_NAMED)
                                ace->who = 0;
                        else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
-                               host_err = nfsd_map_name_to_gid(argp->rqstp,
+                               status = nfsd_map_name_to_gid(argp->rqstp,
                                                buf, dummy32, &ace->who);
                        else
-                               host_err = nfsd_map_name_to_uid(argp->rqstp,
+                               status = nfsd_map_name_to_uid(argp->rqstp,
                                                buf, dummy32, &ace->who);
-                       if (host_err)
-                               goto out_nfserr;
+                       if (status)
+                               return status;
                }
        } else
                *acl = NULL;
@@ -420,6 +421,21 @@ nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access
        DECODE_TAIL;
 }
 
+static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
+{
+       DECODE_HEAD;
+       u32 dummy;
+
+       READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
+       COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+       READ32(bcts->dir);
+       /* XXX: Perhaps Tom Tucker could help us figure out how we
+        * should be using ctsa_use_conn_in_rdma_mode: */
+       READ32(dummy);
+
+       DECODE_TAIL;
+}
+
 static __be32
 nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 {
@@ -846,6 +862,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
        DECODE_TAIL;
 }
 
+static __be32
+nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
+                    struct nfsd4_secinfo_no_name *sin)
+{
+       DECODE_HEAD;
+
+       READ_BUF(4);
+       READ32(sin->sin_style);
+       DECODE_TAIL;
+}
+
 static __be32
 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
 {
@@ -1005,7 +1032,7 @@ static __be32
 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
                         struct nfsd4_exchange_id *exid)
 {
-       int dummy;
+       int dummy, tmp;
        DECODE_HEAD;
 
        READ_BUF(NFS4_VERIFIER_SIZE);
@@ -1053,15 +1080,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
 
                /* ssp_hash_algs<> */
                READ_BUF(4);
-               READ32(dummy);
-               READ_BUF(dummy);
-               p += XDR_QUADLEN(dummy);
+               READ32(tmp);
+               while (tmp--) {
+                       READ_BUF(4);
+                       READ32(dummy);
+                       READ_BUF(dummy);
+                       p += XDR_QUADLEN(dummy);
+               }
 
                /* ssp_encr_algs<> */
                READ_BUF(4);
-               READ32(dummy);
-               READ_BUF(dummy);
-               p += XDR_QUADLEN(dummy);
+               READ32(tmp);
+               while (tmp--) {
+                       READ_BUF(4);
+                       READ32(dummy);
+                       READ_BUF(dummy);
+                       p += XDR_QUADLEN(dummy);
+               }
 
                /* ssp_window and ssp_num_gss_handles */
                READ_BUF(8);
@@ -1339,7 +1374,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
 
        /* new operations for NFSv4.1 */
        [OP_BACKCHANNEL_CTL]    = (nfsd4_dec)nfsd4_decode_notsupp,
-       [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_notsupp,
+       [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
        [OP_EXCHANGE_ID]        = (nfsd4_dec)nfsd4_decode_exchange_id,
        [OP_CREATE_SESSION]     = (nfsd4_dec)nfsd4_decode_create_session,
        [OP_DESTROY_SESSION]    = (nfsd4_dec)nfsd4_decode_destroy_session,
@@ -1350,7 +1385,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
        [OP_LAYOUTCOMMIT]       = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_LAYOUTGET]          = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_LAYOUTRETURN]       = (nfsd4_dec)nfsd4_decode_notsupp,
-       [OP_SECINFO_NO_NAME]    = (nfsd4_dec)nfsd4_decode_notsupp,
+       [OP_SECINFO_NO_NAME]    = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
        [OP_SEQUENCE]           = (nfsd4_dec)nfsd4_decode_sequence,
        [OP_SET_SSV]            = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_TEST_STATEID]       = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -2309,8 +2344,6 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
        case nfserr_resource:
                nfserr = nfserr_toosmall;
                goto fail;
-       case nfserr_dropit:
-               goto fail;
        case nfserr_noent:
                goto skip_entry;
        default:
@@ -2365,6 +2398,21 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
        return nfserr;
 }
 
+static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
+{
+       __be32 *p;
+
+       if (!nfserr) {
+               RESERVE_SPACE(NFS4_MAX_SESSIONID_LEN + 8);
+               WRITEMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
+               WRITE32(bcts->dir);
+               /* XXX: ? */
+               WRITE32(0);
+               ADJUST_ARGS();
+       }
+       return nfserr;
+}
+
 static __be32
 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
 {
@@ -2826,11 +2874,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
 }
 
 static __be32
-nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
-                    struct nfsd4_secinfo *secinfo)
+nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
+                        __be32 nfserr,struct svc_export *exp)
 {
        int i = 0;
-       struct svc_export *exp = secinfo->si_exp;
        u32 nflavs;
        struct exp_flavor_info *flavs;
        struct exp_flavor_info def_flavs[2];
@@ -2892,6 +2939,20 @@ out:
        return nfserr;
 }
 
+static __be32
+nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
+                    struct nfsd4_secinfo *secinfo)
+{
+       return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp);
+}
+
+static __be32
+nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
+                    struct nfsd4_secinfo_no_name *secinfo)
+{
+       return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp);
+}
+
 /*
  * The SETATTR encode routine is special -- it always encodes a bitmap,
  * regardless of the error status.
@@ -3076,13 +3137,9 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, int nfserr,
        WRITE32(seq->seqid);
        WRITE32(seq->slotid);
        WRITE32(seq->maxslots);
-       /*
-        * FIXME: for now:
-        *   target_maxslots = maxslots
-        *   status_flags = 0
-        */
+       /* For now: target_maxslots = maxslots */
        WRITE32(seq->maxslots);
-       WRITE32(0);
+       WRITE32(seq->status_flags);
 
        ADJUST_ARGS();
        resp->cstate.datap = p; /* DRC cache data pointer */
@@ -3143,7 +3200,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
 
        /* NFSv4.1 operations */
        [OP_BACKCHANNEL_CTL]    = (nfsd4_enc)nfsd4_encode_noop,
-       [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_noop,
+       [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
        [OP_EXCHANGE_ID]        = (nfsd4_enc)nfsd4_encode_exchange_id,
        [OP_CREATE_SESSION]     = (nfsd4_enc)nfsd4_encode_create_session,
        [OP_DESTROY_SESSION]    = (nfsd4_enc)nfsd4_encode_destroy_session,
@@ -3154,7 +3211,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
        [OP_LAYOUTCOMMIT]       = (nfsd4_enc)nfsd4_encode_noop,
        [OP_LAYOUTGET]          = (nfsd4_enc)nfsd4_encode_noop,
        [OP_LAYOUTRETURN]       = (nfsd4_enc)nfsd4_encode_noop,
-       [OP_SECINFO_NO_NAME]    = (nfsd4_enc)nfsd4_encode_noop,
+       [OP_SECINFO_NO_NAME]    = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
        [OP_SEQUENCE]           = (nfsd4_enc)nfsd4_encode_sequence,
        [OP_SET_SSV]            = (nfsd4_enc)nfsd4_encode_noop,
        [OP_TEST_STATEID]       = (nfsd4_enc)nfsd4_encode_noop,
index 4514ebbee4d6246aac28086ecbb90a0568a01d16..33b3e2b06779da530630fbb43800b3587c2728d9 100644 (file)
@@ -8,12 +8,12 @@
 #include <linux/namei.h>
 #include <linux/ctype.h>
 
-#include <linux/nfsd_idmap.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfsd/syscall.h>
 #include <linux/lockd/lockd.h>
 #include <linux/sunrpc/clnt.h>
 
+#include "idmap.h"
 #include "nfsd.h"
 #include "cache.h"
 
@@ -127,6 +127,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
 
 static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
 {
+#ifdef CONFIG_NFSD_DEPRECATED
        static int warned;
        if (file->f_dentry->d_name.name[0] == '.' && !warned) {
                printk(KERN_INFO
@@ -135,6 +136,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size
                       current->comm, file->f_dentry->d_name.name);
                warned = 1;
        }
+#endif
        if (! file->private_data) {
                /* An attempt to read a transaction file without writing
                 * causes a 0-byte write so that the file can return
index 6b641cf2c19ac59a6f65326c40038e2549c6df83..7ecfa2420307c24c1e2331189b2e1ff534928c87 100644 (file)
@@ -158,6 +158,7 @@ void                nfsd_lockd_shutdown(void);
 #define        nfserr_attrnotsupp      cpu_to_be32(NFSERR_ATTRNOTSUPP)
 #define        nfserr_bad_xdr          cpu_to_be32(NFSERR_BAD_XDR)
 #define        nfserr_openmode         cpu_to_be32(NFSERR_OPENMODE)
+#define        nfserr_badowner         cpu_to_be32(NFSERR_BADOWNER)
 #define        nfserr_locks_held       cpu_to_be32(NFSERR_LOCKS_HELD)
 #define        nfserr_op_illegal       cpu_to_be32(NFSERR_OP_ILLEGAL)
 #define        nfserr_grace            cpu_to_be32(NFSERR_GRACE)
index 08e17264784b7f4dd2d5822cbb7c59a52a58f369..e15dc45fc5ec01c09a05d42b8ac600ed39e3892f 100644 (file)
@@ -735,9 +735,9 @@ nfserrno (int errno)
                { nfserr_stale, -ESTALE },
                { nfserr_jukebox, -ETIMEDOUT },
                { nfserr_jukebox, -ERESTARTSYS },
-               { nfserr_dropit, -EAGAIN },
-               { nfserr_dropit, -ENOMEM },
-               { nfserr_badname, -ESRCH },
+               { nfserr_jukebox, -EAGAIN },
+               { nfserr_jukebox, -EWOULDBLOCK },
+               { nfserr_jukebox, -ENOMEM },
                { nfserr_io, -ETXTBSY },
                { nfserr_notsupp, -EOPNOTSUPP },
                { nfserr_toosmall, -ETOOSMALL },
index 2bae1d86f5f241b8d62a61bf9ed8b5a0bcfc9c8e..18743c4d8bca848d493829f6385127f8e89508eb 100644 (file)
@@ -608,7 +608,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
        /* Now call the procedure handler, and encode NFS status. */
        nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
        nfserr = map_new_errors(rqstp->rq_vers, nfserr);
-       if (nfserr == nfserr_dropit) {
+       if (nfserr == nfserr_dropit || rqstp->rq_dropme) {
                dprintk("nfsd: Dropping request; may be revisited later\n");
                nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
                return 0;
index 39adc27b06853c37a40a1e951ff5027625a15b52..3074656ba7bf96cc23c024bc7b9ec35256b5cd80 100644 (file)
@@ -68,10 +68,12 @@ typedef struct {
 struct nfsd4_callback {
        void *cb_op;
        struct nfs4_client *cb_clp;
+       struct list_head cb_per_client;
        u32 cb_minorversion;
        struct rpc_message cb_msg;
        const struct rpc_call_ops *cb_ops;
        struct work_struct cb_work;
+       bool cb_done;
 };
 
 struct nfs4_delegation {
@@ -81,6 +83,7 @@ struct nfs4_delegation {
        atomic_t                dl_count;       /* ref count */
        struct nfs4_client      *dl_client;
        struct nfs4_file        *dl_file;
+       struct file             *dl_vfs_file;
        struct file_lock        *dl_flock;
        u32                     dl_type;
        time_t                  dl_time;
@@ -95,6 +98,7 @@ struct nfs4_delegation {
 struct nfs4_cb_conn {
        /* SETCLIENTID info */
        struct sockaddr_storage cb_addr;
+       struct sockaddr_storage cb_saddr;
        size_t                  cb_addrlen;
        u32                     cb_prog; /* used only in 4.0 case;
                                            per-session otherwise */
@@ -146,6 +150,11 @@ struct nfsd4_create_session {
        u32                             gid;
 };
 
+struct nfsd4_bind_conn_to_session {
+       struct nfs4_sessionid           sessionid;
+       u32                             dir;
+};
+
 /* The single slot clientid cache structure */
 struct nfsd4_clid_slot {
        u32                             sl_seqid;
@@ -235,9 +244,13 @@ struct nfs4_client {
        unsigned long           cl_cb_flags;
        struct rpc_clnt         *cl_cb_client;
        u32                     cl_cb_ident;
-       atomic_t                cl_cb_set;
+#define NFSD4_CB_UP            0
+#define NFSD4_CB_UNKNOWN       1
+#define NFSD4_CB_DOWN          2
+       int                     cl_cb_state;
        struct nfsd4_callback   cl_cb_null;
        struct nfsd4_session    *cl_cb_session;
+       struct list_head        cl_callbacks; /* list of in-progress callbacks */
 
        /* for all client information that callback code might need: */
        spinlock_t              cl_lock;
@@ -454,6 +467,7 @@ extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
 extern void nfs4_free_stateowner(struct kref *kref);
 extern int set_callback_cred(void);
 extern void nfsd4_probe_callback(struct nfs4_client *clp);
+extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
 extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
 extern void nfsd4_do_callback_rpc(struct work_struct *);
 extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
index 230b79fbf0051be98df5bc5067a2f6f8f18b3b8a..a3c7f701395a4f7fc3ffc02305b9b5e628de8704 100644 (file)
@@ -1,4 +1,3 @@
-#define MSNFS  /* HACK HACK */
 /*
  * File operations used by nfsd. Some of these have been ripped from
  * other parts of the kernel because they weren't exported, others
@@ -35,8 +34,8 @@
 #endif /* CONFIG_NFSD_V3 */
 
 #ifdef CONFIG_NFSD_V4
-#include <linux/nfs4_acl.h>
-#include <linux/nfsd_idmap.h>
+#include "acl.h"
+#include "idmap.h"
 #endif /* CONFIG_NFSD_V4 */
 
 #include "nfsd.h"
@@ -273,6 +272,13 @@ out:
        return err;
 }
 
+static int nfsd_break_lease(struct inode *inode)
+{
+       if (!S_ISREG(inode->i_mode))
+               return 0;
+       return break_lease(inode, O_WRONLY | O_NONBLOCK);
+}
+
 /*
  * Commit metadata changes to stable storage.
  */
@@ -375,16 +381,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
                                goto out;
                }
 
-               /*
-                * If we are changing the size of the file, then
-                * we need to break all leases.
-                */
-               host_err = break_lease(inode, O_WRONLY | O_NONBLOCK);
-               if (host_err == -EWOULDBLOCK)
-                       host_err = -ETIMEDOUT;
-               if (host_err) /* ENOMEM or EWOULDBLOCK */
-                       goto out_nfserr;
-
                host_err = get_write_access(inode);
                if (host_err)
                        goto out_nfserr;
@@ -425,7 +421,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 
        err = nfserr_notsync;
        if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
+               host_err = nfsd_break_lease(inode);
+               if (host_err)
+                       goto out_nfserr;
                fh_lock(fhp);
+
                host_err = notify_change(dentry, iap);
                err = nfserrno(host_err);
                fh_unlock(fhp);
@@ -752,8 +752,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
         */
        if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
                host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
-       if (host_err == -EWOULDBLOCK)
-               host_err = -ETIMEDOUT;
        if (host_err) /* NOMEM or WOULDBLOCK */
                goto out_nfserr;
 
@@ -874,15 +872,6 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
        return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
 }
 
-static inline int svc_msnfs(struct svc_fh *ffhp)
-{
-#ifdef MSNFS
-       return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS);
-#else
-       return 0;
-#endif
-}
-
 static __be32
 nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
               loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
@@ -895,9 +884,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        err = nfserr_perm;
        inode = file->f_path.dentry->d_inode;
 
-       if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
-               goto out;
-
        if (file->f_op->splice_read && rqstp->rq_splice_ok) {
                struct splice_desc sd = {
                        .len            = 0,
@@ -922,7 +908,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                fsnotify_access(file);
        } else 
                err = nfserrno(host_err);
-out:
        return err;
 }
 
@@ -987,14 +972,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     stable = *stablep;
        int                     use_wgather;
 
-#ifdef MSNFS
-       err = nfserr_perm;
-
-       if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
-               (!lock_may_write(file->f_path.dentry->d_inode, offset, *cnt)))
-               goto out;
-#endif
-
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
        exp   = fhp->fh_export;
@@ -1045,7 +1022,6 @@ out_nfserr:
                err = 0;
        else
                err = nfserrno(host_err);
-out:
        return err;
 }
 
@@ -1665,6 +1641,12 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                err = nfserrno(host_err);
                goto out_dput;
        }
+       err = nfserr_noent;
+       if (!dold->d_inode)
+               goto out_drop_write;
+       host_err = nfsd_break_lease(dold->d_inode);
+       if (host_err)
+               goto out_drop_write;
        host_err = vfs_link(dold, dirp, dnew);
        if (!host_err) {
                err = nfserrno(commit_metadata(ffhp));
@@ -1676,6 +1658,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
                else
                        err = nfserrno(host_err);
        }
+out_drop_write:
        mnt_drop_write(tfhp->fh_export->ex_path.mnt);
 out_dput:
        dput(dnew);
@@ -1750,12 +1733,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if (ndentry == trap)
                goto out_dput_new;
 
-       if (svc_msnfs(ffhp) &&
-               ((odentry->d_count > 1) || (ndentry->d_count > 1))) {
-                       host_err = -EPERM;
-                       goto out_dput_new;
-       }
-
        host_err = -EXDEV;
        if (ffhp->fh_export->ex_path.mnt != tfhp->fh_export->ex_path.mnt)
                goto out_dput_new;
@@ -1763,15 +1740,17 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
        if (host_err)
                goto out_dput_new;
 
+       host_err = nfsd_break_lease(odentry->d_inode);
+       if (host_err)
+               goto out_drop_write;
        host_err = vfs_rename(fdir, odentry, tdir, ndentry);
        if (!host_err) {
                host_err = commit_metadata(tfhp);
                if (!host_err)
                        host_err = commit_metadata(ffhp);
        }
-
+out_drop_write:
        mnt_drop_write(ffhp->fh_export->ex_path.mnt);
-
  out_dput_new:
        dput(ndentry);
  out_dput_old:
@@ -1834,18 +1813,14 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        if (host_err)
                goto out_nfserr;
 
-       if (type != S_IFDIR) { /* It's UNLINK */
-#ifdef MSNFS
-               if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
-                       (rdentry->d_count > 1)) {
-                       host_err = -EPERM;
-               } else
-#endif
+       host_err = nfsd_break_lease(rdentry->d_inode);
+       if (host_err)
+               goto out_put;
+       if (type != S_IFDIR)
                host_err = vfs_unlink(dirp, rdentry);
-       } else { /* It's RMDIR */
+       else
                host_err = vfs_rmdir(dirp, rdentry);
-       }
-
+out_put:
        dput(rdentry);
 
        if (!host_err)
index 60fce3dc5cb5d9f90d22b9f9c91ddc7ddeb9ff1d..366401e1a536430f5314e2fe1496a777fd0dc31b 100644 (file)
@@ -311,6 +311,11 @@ struct nfsd4_secinfo {
        struct svc_export *si_exp;                      /* response */
 };
 
+struct nfsd4_secinfo_no_name {
+       u32 sin_style;                                  /* request */
+       struct svc_export *sin_exp;                     /* response */
+};
+
 struct nfsd4_setattr {
        stateid_t       sa_stateid;         /* request */
        u32             sa_bmval[3];        /* request */
@@ -373,8 +378,8 @@ struct nfsd4_sequence {
        u32                     cachethis;              /* request */
 #if 0
        u32                     target_maxslots;        /* response */
-       u32                     status_flags;           /* response */
 #endif /* not yet */
+       u32                     status_flags;           /* response */
 };
 
 struct nfsd4_destroy_session {
@@ -422,6 +427,7 @@ struct nfsd4_op {
 
                /* NFSv4.1 */
                struct nfsd4_exchange_id        exchange_id;
+               struct nfsd4_bind_conn_to_session bind_conn_to_session;
                struct nfsd4_create_session     create_session;
                struct nfsd4_destroy_session    destroy_session;
                struct nfsd4_sequence           sequence;
@@ -518,6 +524,7 @@ extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
                struct nfsd4_sequence *seq);
 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
+extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *);
 extern __be32 nfsd4_create_session(struct svc_rqst *,
                struct nfsd4_compound_state *,
                struct nfsd4_create_session *);
index bec8b82889bfa7217952cdbb6a76f2a2fe8af041..ab68f785fd196fb73ef062a67b9ad195d84bcd13 100644 (file)
@@ -98,6 +98,17 @@ static inline int is_broadcast_ether_addr(const u8 *addr)
        return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
 }
 
+/**
+ * is_unicast_ether_addr - Determine if the Ethernet address is unicast
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is a unicast address.
+ */
+static inline int is_unicast_ether_addr(const u8 *addr)
+{
+       return !is_multicast_ether_addr(addr);
+}
+
 /**
  * is_valid_ether_addr - Determine if the given Ethernet address is valid
  * @addr: Pointer to a six-byte array containing the Ethernet address
index 3984f2358d1f56d98de234203ddec0cc9f20b538..08824e0ef381b3117c79f69a09a35891e8bd49fe 100644 (file)
@@ -666,7 +666,7 @@ struct block_device {
        int                     bd_holders;
        bool                    bd_write_holder;
 #ifdef CONFIG_SYSFS
-       struct gendisk *        bd_holder_disk; /* for sysfs slave linkng */
+       struct list_head        bd_holder_disks;
 #endif
        struct block_device *   bd_contains;
        unsigned                bd_block_size;
@@ -1066,7 +1066,6 @@ struct lock_manager_operations {
        int (*fl_grant)(struct file_lock *, struct file_lock *, int);
        void (*fl_release_private)(struct file_lock *);
        void (*fl_break)(struct file_lock *);
-       int (*fl_mylease)(struct file_lock *, struct file_lock *);
        int (*fl_change)(struct file_lock **, int);
 };
 
@@ -2058,12 +2057,18 @@ extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode,
 extern int blkdev_put(struct block_device *bdev, fmode_t mode);
 #ifdef CONFIG_SYSFS
 extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk);
+extern void bd_unlink_disk_holder(struct block_device *bdev,
+                                 struct gendisk *disk);
 #else
 static inline int bd_link_disk_holder(struct block_device *bdev,
                                      struct gendisk *disk)
 {
        return 0;
 }
+static inline void bd_unlink_disk_holder(struct block_device *bdev,
+                                        struct gendisk *disk)
+{
+}
 #endif
 #endif
 
index be4957cf6511964c32b9ce87de0494308b952827..d971346b0340da50ae229f0dda8244f66c0eab2b 100644 (file)
@@ -520,9 +520,6 @@ struct netdev_queue {
         * please use this field instead of dev->trans_start
         */
        unsigned long           trans_start;
-       u64                     tx_bytes;
-       u64                     tx_packets;
-       u64                     tx_dropped;
 } ____cacheline_aligned_in_smp;
 
 static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
@@ -2265,8 +2262,6 @@ extern void               dev_load(struct net *net, const char *name);
 extern void            dev_mcast_init(void);
 extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
                                               struct rtnl_link_stats64 *storage);
-extern void            dev_txq_stats_fold(const struct net_device *dev,
-                                          struct rtnl_link_stats64 *stats);
 
 extern int             netdev_max_backlog;
 extern int             netdev_tstamp_prequeue;
index 9b46300b4305957f210d447bee436d3b9ae7ad06..134716e5e3509f9c56e11334137a9aefb41c4a21 100644 (file)
@@ -65,6 +65,9 @@
 
 #define NFS4_CDFC4_FORE        0x1
 #define NFS4_CDFC4_BACK 0x2
+#define NFS4_CDFC4_BOTH 0x3
+#define NFS4_CDFC4_FORE_OR_BOTH 0x3
+#define NFS4_CDFC4_BACK_OR_BOTH 0x7
 
 #define NFS4_SET_TO_SERVER_TIME        0
 #define NFS4_SET_TO_CLIENT_TIME        1
 #define SEQ4_STATUS_CB_PATH_DOWN_SESSION       0x00000200
 #define SEQ4_STATUS_BACKCHANNEL_FAULT          0x00000400
 
+#define NFS4_SECINFO_STYLE4_CURRENT_FH 0
+#define NFS4_SECINFO_STYLE4_PARENT     1
+
 #define NFS4_MAX_UINT64        (~(u64)0)
 
 /* An NFS4 sessions server must support at least NFS4_MAX_OPS operations.
index 8ae78a61eea4f2eaa8f0c137a1f77b27b3d880e8..bd316159278c57abdbfabe6205858c520ccf20bc 100644 (file)
@@ -35,7 +35,7 @@
 #define NFSEXP_NOHIDE          0x0200
 #define NFSEXP_NOSUBTREECHECK  0x0400
 #define        NFSEXP_NOAUTHNLM        0x0800          /* Don't authenticate NLM requests - just trust */
-#define NFSEXP_MSNFS           0x1000  /* do silly things that MS clients expect */
+#define NFSEXP_MSNFS           0x1000  /* do silly things that MS clients expect; no longer supported */
 #define NFSEXP_FSID            0x2000
 #define        NFSEXP_CROSSMOUNT       0x4000
 #define        NFSEXP_NOACL            0x8000  /* reserved for possible ACL related use */
index 2b89b712565b834ca3bb32a5bf5cdbe862b9326a..821ffb954f14738abf42439aedf5538cdffcd4ad 100644 (file)
  * @NL80211_CMD_SET_MPATH:  Set mesh path attributes for mesh path to
  *     destination %NL80211_ATTR_MAC on the interface identified by
  *     %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by
+ *     %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP.
+ * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
+ *     %NL80211_ATTR_MAC.
  * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
  *     the interface identified by %NL80211_ATTR_IFINDEX.
  * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
@@ -612,7 +616,7 @@ enum nl80211_commands {
  *     consisting of a nested array.
  *
  * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes).
- * @NL80211_ATTR_PLINK_ACTION: action to perform on the mesh peer link.
+ * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link.
  * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path.
  * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path
  *     info given for %NL80211_CMD_GET_MPATH, nested attribute described at
@@ -879,7 +883,9 @@ enum nl80211_commands {
  *     See &enum nl80211_key_default_types.
  *
  * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters.  These cannot be
- * changed once the mesh is active.
+ *     changed once the mesh is active.
+ * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
+ *     containing attributes from &enum nl80211_meshconf_params.
  *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1225,8 +1231,6 @@ enum nl80211_rate_info {
  * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs)
  * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station)
  * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station)
- * @__NL80211_STA_INFO_AFTER_LAST: internal
- * @NL80211_STA_INFO_MAX: highest possible station info attribute
  * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm)
  * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute
  *     containing info as possible, see &enum nl80211_sta_info_txrate.
@@ -1236,6 +1240,11 @@ enum nl80211_rate_info {
  * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station)
  * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station)
  * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm)
+ * @NL80211_STA_INFO_LLID: the station's mesh LLID
+ * @NL80211_STA_INFO_PLID: the station's mesh PLID
+ * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station
+ * @__NL80211_STA_INFO_AFTER_LAST: internal
+ * @NL80211_STA_INFO_MAX: highest possible station info attribute
  */
 enum nl80211_sta_info {
        __NL80211_STA_INFO_INVALID,
@@ -1626,7 +1635,7 @@ enum nl80211_mntr_flags {
  * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
  * that it takes for an HWMP information element to propagate across the mesh
  *
- * @NL80211_MESHCONF_ROOTMODE: whether root mode is enabled or not
+ * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not
  *
  * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a
  * source mesh point for path selection elements.
@@ -1678,6 +1687,7 @@ enum nl80211_meshconf_params {
  * element that vendors will use to identify the path selection methods and
  * metrics in use.
  *
+ * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
  * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
  */
 enum nl80211_mesh_setup_params {
index 9e67dcd054c4eda86c4957ec173fce9388eb4d54..559d028970752672cc92260eb7b64c61276f5e89 100644 (file)
@@ -993,8 +993,13 @@ extern void pci_restore_msi_state(struct pci_dev *dev);
 extern int pci_msi_enabled(void);
 #endif
 
+#ifdef CONFIG_PCIEPORTBUS
 extern bool pcie_ports_disabled;
 extern bool pcie_ports_auto;
+#else
+#define pcie_ports_disabled    true
+#define pcie_ports_auto                false
+#endif
 
 #ifndef CONFIG_PCIEASPM
 static inline int pcie_aspm_enabled(void)
index 20ec0a64cb9ff0f8708a66ddaeb2ffd1d3ed72c9..bf221d65d9ad5d0c2878795021b2733012c4ef2f 100644 (file)
@@ -255,6 +255,11 @@ typedef unsigned int sk_buff_data_t;
 typedef unsigned char *sk_buff_data_t;
 #endif
 
+#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
+    defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
+#define NET_SKBUFF_NF_DEFRAG_NEEDED 1
+#endif
+
 /** 
  *     struct sk_buff - socket buffer
  *     @next: Next buffer in list
@@ -362,6 +367,8 @@ struct sk_buff {
        void                    (*destructor)(struct sk_buff *skb);
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        struct nf_conntrack     *nfct;
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
        struct sk_buff          *nfct_reasm;
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
@@ -2057,6 +2064,8 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
        if (nfct)
                atomic_inc(&nfct->use);
 }
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
 static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
 {
        if (skb)
@@ -2085,6 +2094,8 @@ static inline void nf_reset(struct sk_buff *skb)
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        nf_conntrack_put(skb->nfct);
        skb->nfct = NULL;
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
        nf_conntrack_put_reasm(skb->nfct_reasm);
        skb->nfct_reasm = NULL;
 #endif
@@ -2101,6 +2112,8 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
        dst->nfct = src->nfct;
        nf_conntrack_get(src->nfct);
        dst->nfctinfo = src->nfctinfo;
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
        dst->nfct_reasm = src->nfct_reasm;
        nf_conntrack_get_reasm(src->nfct_reasm);
 #endif
@@ -2114,6 +2127,8 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
 {
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        nf_conntrack_put(dst->nfct);
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
        nf_conntrack_put_reasm(dst->nfct_reasm);
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
index 78aa104250b7b78755b570480353d66c304062cf..7898ea13de70a2233445c7e9deec48546c492efc 100644 (file)
@@ -256,10 +256,13 @@ static inline time_t get_expiry(char **bpp)
        return rv - boot.tv_sec;
 }
 
+#ifdef CONFIG_NFSD_DEPRECATED
 static inline void sunrpc_invalidate(struct cache_head *h,
                                     struct cache_detail *detail)
 {
        h->expiry_time = seconds_since_boot() - 1;
        detail->nextcheck = seconds_since_boot();
 }
+#endif /* CONFIG_NFSD_DEPRECATED */
+
 #endif /*  _LINUX_SUNRPC_CACHE_H_ */
index c81d4d8be3a99425729e0046c2d3683929b7a45a..ea29330b78bd002aa67b3091abd589a077318b91 100644 (file)
@@ -269,6 +269,7 @@ struct svc_rqst {
        struct cache_req        rq_chandle;     /* handle passed to caches for 
                                                 * request delaying 
                                                 */
+       bool                    rq_dropme;
        /* Catering to nfsd */
        struct auth_domain *    rq_client;      /* RPC peer info */
        struct auth_domain *    rq_gssclient;   /* "gss/"-style peer info */
index 357da5e0daa3308b0113009e0525f9a8cae3943d..059877b4d85b7c0734668bd9027745e0c10bea8b 100644 (file)
@@ -63,7 +63,6 @@ struct svc_xprt {
 #define XPT_LISTENER   11              /* listening endpoint */
 #define XPT_CACHE_AUTH 12              /* cache auth info */
 
-       struct svc_pool         *xpt_pool;      /* current pool iff queued */
        struct svc_serv         *xpt_server;    /* service for transport */
        atomic_t                xpt_reserved;   /* space on outq that is rsvd */
        struct mutex            xpt_mutex;      /* to serialize sending data */
@@ -81,6 +80,7 @@ struct svc_xprt {
        void                    *xpt_bc_sid;    /* back channel session ID */
 
        struct net              *xpt_net;
+       struct rpc_xprt         *xpt_bc_xprt;   /* NFSv4.1 backchannel */
 };
 
 static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
index 1b353a76c30492389bad8c12fb41ffcd901a2027..04dba23c59f2c4aead01ab313127368a63b93a05 100644 (file)
@@ -28,7 +28,6 @@ struct svc_sock {
        /* private TCP part */
        u32                     sk_reclen;      /* length of record */
        u32                     sk_tcplen;      /* current read length */
-       struct rpc_xprt         *sk_bc_xprt;    /* NFSv4.1 backchannel xprt */
 };
 
 /*
index 89d10d279a203d611bbc3f40760ab490c8eea098..bef0f535f7464608e4173c80d53d9c49a80384a4 100644 (file)
@@ -321,6 +321,7 @@ void                        xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int cookie);
 #define XPRT_CLOSING           (6)
 #define XPRT_CONNECTION_ABORT  (7)
 #define XPRT_CONNECTION_CLOSE  (8)
+#define XPRT_INITIALIZED       (9)
 
 static inline void xprt_set_connected(struct rpc_xprt *xprt)
 {
index be7798dea6f45c5841c8806a4751995c3fc13374..ca95b98969ddf21860590e8252f7ad8a53f690b4 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/skbuff.h>
 
 /* This is the maximum truncated ICV length that we know of. */
-#define MAX_AH_AUTH_LEN        16
+#define MAX_AH_AUTH_LEN        64
 
 struct crypto_ahash;
 
index bcc9f448ec4e6d763504c31a5b02cf4c2514d59d..1322695beb52980e741b17473ed9906ba159895e 100644 (file)
@@ -1103,6 +1103,8 @@ struct cfg80211_pmksa {
  * @change_mpath: change a given mesh path
  * @get_mpath: get a mesh path for the given parameters
  * @dump_mpath: dump mesh path callback -- resume dump at index @idx
+ * @join_mesh: join the mesh network with the specified parameters
+ * @leave_mesh: leave the current mesh network
  *
  * @get_mesh_config: Get the current mesh configuration
  *
index 5b3fd5add7a4d27982105444a2dd2a300743f309..62c0ce2d1dc874a4480ad07a91639795b2c70f64 100644 (file)
@@ -337,6 +337,10 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame
  * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this
  *     frame and selects the maximum number of streams that it can use.
+ * @IEEE80211_TX_CTL_TX_OFFCHAN: Marks this packet to be transmitted on
+ *     the off-channel channel when a remain-on-channel offload is done
+ *     in hardware -- normal packets still flow and are expected to be
+ *     handled properly by the device.
  *
  * Note: If you have to add new flags to the enumeration, then don't
  *      forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
@@ -1753,6 +1757,16 @@ enum ieee80211_ampdu_mlme_action {
  *     (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).
  *
  * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
+ *
+ * @remain_on_channel: Starts an off-channel period on the given channel, must
+ *     call back to ieee80211_ready_on_channel() when on that channel. Note
+ *     that normal channel traffic is not stopped as this is intended for hw
+ *     offload. Frames to transmit on the off-channel channel are transmitted
+ *     normally except for the %IEEE80211_TX_CTL_TX_OFFCHAN flag. When the
+ *     duration (which will always be non-zero) expires, the driver must call
+ *     ieee80211_remain_on_channel_expired(). This callback may sleep.
+ * @cancel_remain_on_channel: Requests that an ongoing off-channel period is
+ *     aborted before it expires. This callback may sleep.
  */
 struct ieee80211_ops {
        int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
index 1ee717eb5b099f6fa1fc782506c05e0dd59addb8..a4c99368579509387e6ae75eff33383db5e3f8a7 100644 (file)
@@ -7,16 +7,6 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
 extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
 
-extern int nf_ct_frag6_init(void);
-extern void nf_ct_frag6_cleanup(void);
-extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
-extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-                              struct net_device *in,
-                              struct net_device *out,
-                              int (*okfn)(struct sk_buff *));
-
-struct inet_frags_ctl;
-
 #include <linux/sysctl.h>
 extern struct ctl_table nf_ct_ipv6_sysctl_table[];
 
index 94dd54d76b48d215729059d53b9e6a983070138a..fd79c9a1779d19d6a5dd54ef7380b990763a00ea 100644 (file)
@@ -3,4 +3,14 @@
 
 extern void nf_defrag_ipv6_enable(void);
 
+extern int nf_ct_frag6_init(void);
+extern void nf_ct_frag6_cleanup(void);
+extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
+extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
+                              struct net_device *in,
+                              struct net_device *out,
+                              int (*okfn)(struct sk_buff *));
+
+struct inet_frags_ctl;
+
 #endif /* _NF_DEFRAG_IPV6_H */
index 995108e54d9f0adde1344ff76daf821567ae9b83..3319f16b3beb899727c7a434e75fb1010d7ee139 100644 (file)
@@ -97,7 +97,6 @@ struct red_stats {
        u32             forced_mark;    /* Forced marks, qavg > max_thresh */
        u32             pdrop;          /* Drops due to queue limits */
        u32             other;          /* Drops due to drop() calls */
-       u32             backlog;
 };
 
 struct red_parms {
index bb86d2932394aa9b1176ccfbba7a13102c0a3d20..6da5daeebab7266bbf5a1fa85fe3d7e1985475de 100644 (file)
@@ -1392,7 +1392,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
        ax25_cb *ax25;
        int err = 0;
 
-       memset(fsa, 0, sizeof(fsa));
+       memset(fsa, 0, sizeof(*fsa));
        lock_sock(sk);
        ax25 = ax25_sk(sk);
 
index 06d0e7b253850d35fcf3b0bcc2fa6a7635d57986..54277df0f735abf601a44053fa29c9f85cc5c87b 100644 (file)
@@ -5523,34 +5523,6 @@ void netdev_run_todo(void)
        }
 }
 
-/**
- *     dev_txq_stats_fold - fold tx_queues stats
- *     @dev: device to get statistics from
- *     @stats: struct rtnl_link_stats64 to hold results
- */
-void dev_txq_stats_fold(const struct net_device *dev,
-                       struct rtnl_link_stats64 *stats)
-{
-       u64 tx_bytes = 0, tx_packets = 0, tx_dropped = 0;
-       unsigned int i;
-       struct netdev_queue *txq;
-
-       for (i = 0; i < dev->num_tx_queues; i++) {
-               txq = netdev_get_tx_queue(dev, i);
-               spin_lock_bh(&txq->_xmit_lock);
-               tx_bytes   += txq->tx_bytes;
-               tx_packets += txq->tx_packets;
-               tx_dropped += txq->tx_dropped;
-               spin_unlock_bh(&txq->_xmit_lock);
-       }
-       if (tx_bytes || tx_packets || tx_dropped) {
-               stats->tx_bytes   = tx_bytes;
-               stats->tx_packets = tx_packets;
-               stats->tx_dropped = tx_dropped;
-       }
-}
-EXPORT_SYMBOL(dev_txq_stats_fold);
-
 /* Convert net_device_stats to rtnl_link_stats64.  They have the same
  * fields in the same order, with only the type differing.
  */
@@ -5594,7 +5566,6 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
                netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev));
        } else {
                netdev_stats_to_stats64(storage, &dev->stats);
-               dev_txq_stats_fold(dev, storage);
        }
        storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
        return storage;
index 19d6c21220fd47bb7141d8376a55c1785627a5e8..d31bb36ae0dc21cfdab61b90dd2f2fbfd665ce81 100644 (file)
@@ -380,6 +380,8 @@ static void skb_release_head_state(struct sk_buff *skb)
        }
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        nf_conntrack_put(skb->nfct);
+#endif
+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
        nf_conntrack_put_reasm(skb->nfct_reasm);
 #endif
 #ifdef CONFIG_BRIDGE_NETFILTER
index f9d7ac924f159db5d4ffb26f394021923bdf7065..44d2b42fda5616017c14f1db3caf23dd3a39935c 100644 (file)
@@ -351,7 +351,7 @@ EXPORT_SYMBOL(ether_setup);
  * @sizeof_priv: Size of additional driver-private structure to be allocated
  *     for this Ethernet device
  * @txqs: The number of TX queues this device has.
- * @txqs: The number of RX queues this device has.
+ * @rxqs: The number of RX queues this device has.
  *
  * Fill in the fields of the device structure with Ethernet-generic
  * values. Basically does everything except registering the device.
index 94b5bf132b2e33a467f662b8c0e402a459f00a3d..5f8d242be3f3016592678d09e9cf4654be9234a7 100644 (file)
@@ -401,6 +401,9 @@ int ip6_forward(struct sk_buff *skb)
                goto drop;
        }
 
+       if (skb->pkt_type != PACKET_HOST)
+               goto drop;
+
        skb_forward_csum(skb);
 
        /*
index 99abfb53bab91def61a8d7cdeaf2ee64ed8aa8f6..97c5b21b9674f3fb005da40235e78303f6323a9a 100644 (file)
 
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter_bridge.h>
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_helper.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
-#include <net/netfilter/nf_conntrack_zones.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#endif
+#include <net/netfilter/nf_conntrack_zones.h>
 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
 static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
@@ -33,8 +35,10 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
 {
        u16 zone = NF_CT_DEFAULT_ZONE;
 
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        if (skb->nfct)
                zone = nf_ct_zone((struct nf_conn *)skb->nfct);
+#endif
 
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (skb->nf_bridge &&
@@ -56,9 +60,11 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
 {
        struct sk_buff *reasm;
 
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        /* Previously seen (loopback)?  */
        if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
                return NF_ACCEPT;
+#endif
 
        reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
        /* queued */
index 5cb8d3027b18b1cb990229a30db52a3e8004fe1a..2b7eef37875ccbdd8c59c5f8d845746e9f9609d7 100644 (file)
@@ -972,7 +972,8 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
 free:
        kfree_skb(skb2);
 out:
-       return err;
+       /* this avoids a loop in nfnetlink. */
+       return err == -EAGAIN ? -ENOBUFS : err;
 }
 
 #ifdef CONFIG_NF_NAT_NEEDED
index af9360d1f6eb3b4c839bcfa2f623955c12a232a8..84ce48eadff4952e2552306fae3197858af86c59 100644 (file)
@@ -59,6 +59,10 @@ struct teql_master
        struct net_device *dev;
        struct Qdisc *slaves;
        struct list_head master_list;
+       unsigned long   tx_bytes;
+       unsigned long   tx_packets;
+       unsigned long   tx_errors;
+       unsigned long   tx_dropped;
 };
 
 struct teql_sched_data
@@ -274,7 +278,6 @@ static inline int teql_resolve(struct sk_buff *skb,
 static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct teql_master *master = netdev_priv(dev);
-       struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
        struct Qdisc *start, *q;
        int busy;
        int nores;
@@ -314,8 +317,8 @@ restart:
                                        __netif_tx_unlock(slave_txq);
                                        master->slaves = NEXT_SLAVE(q);
                                        netif_wake_queue(dev);
-                                       txq->tx_packets++;
-                                       txq->tx_bytes += length;
+                                       master->tx_packets++;
+                                       master->tx_bytes += length;
                                        return NETDEV_TX_OK;
                                }
                                __netif_tx_unlock(slave_txq);
@@ -342,10 +345,10 @@ restart:
                netif_stop_queue(dev);
                return NETDEV_TX_BUSY;
        }
-       dev->stats.tx_errors++;
+       master->tx_errors++;
 
 drop:
-       txq->tx_dropped++;
+       master->tx_dropped++;
        dev_kfree_skb(skb);
        return NETDEV_TX_OK;
 }
@@ -398,6 +401,18 @@ static int teql_master_close(struct net_device *dev)
        return 0;
 }
 
+static struct rtnl_link_stats64 *teql_master_stats64(struct net_device *dev,
+                                                    struct rtnl_link_stats64 *stats)
+{
+       struct teql_master *m = netdev_priv(dev);
+
+       stats->tx_packets       = m->tx_packets;
+       stats->tx_bytes         = m->tx_bytes;
+       stats->tx_errors        = m->tx_errors;
+       stats->tx_dropped       = m->tx_dropped;
+       return stats;
+}
+
 static int teql_master_mtu(struct net_device *dev, int new_mtu)
 {
        struct teql_master *m = netdev_priv(dev);
@@ -422,6 +437,7 @@ static const struct net_device_ops teql_netdev_ops = {
        .ndo_open       = teql_master_open,
        .ndo_stop       = teql_master_close,
        .ndo_start_xmit = teql_master_xmit,
+       .ndo_get_stats64 = teql_master_stats64,
        .ndo_change_mtu = teql_master_mtu,
 };
 
index 75ee993ea0573bb1fda3c403966a84d39a61e373..9576f35ab7014f2c506dfdd306d4201e3535b7a7 100644 (file)
@@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4])
                ms_usage = 13;
                break;
        default:
-               return EINVAL;;
+               return -EINVAL;
        }
        salt[0] = (ms_usage >> 0) & 0xff;
        salt[1] = (ms_usage >> 8) & 0xff;
index dec2a6fc7c1277f15485011e52a7671eb3052574..bcdae78fdfc6b326c6918ec72de4530bbf8e2667 100644 (file)
@@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b)
 
 #define        RSI_HASHBITS    6
 #define        RSI_HASHMAX     (1<<RSI_HASHBITS)
-#define        RSI_HASHMASK    (RSI_HASHMAX-1)
 
 struct rsi {
        struct cache_head       h;
@@ -319,7 +318,6 @@ static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
 
 #define        RSC_HASHBITS    10
 #define        RSC_HASHMAX     (1<<RSC_HASHBITS)
-#define        RSC_HASHMASK    (RSC_HASHMAX-1)
 
 #define GSS_SEQ_WIN    128
 
index e433e7580e27b221eff94d8b95ceaea703440618..72ad836e4fe05d7e5d9153918e5d8c1dacecc4a5 100644 (file)
@@ -37,7 +37,7 @@
 
 #define         RPCDBG_FACILITY RPCDBG_CACHE
 
-static void cache_defer_req(struct cache_req *req, struct cache_head *item);
+static bool cache_defer_req(struct cache_req *req, struct cache_head *item);
 static void cache_revisit_request(struct cache_head *item);
 
 static void cache_init(struct cache_head *h)
@@ -128,6 +128,7 @@ static void cache_fresh_locked(struct cache_head *head, time_t expiry)
 {
        head->expiry_time = expiry;
        head->last_refresh = seconds_since_boot();
+       smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */
        set_bit(CACHE_VALID, &head->flags);
 }
 
@@ -208,11 +209,36 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head
                /* entry is valid */
                if (test_bit(CACHE_NEGATIVE, &h->flags))
                        return -ENOENT;
-               else
+               else {
+                       /*
+                        * In combination with write barrier in
+                        * sunrpc_cache_update, ensures that anyone
+                        * using the cache entry after this sees the
+                        * updated contents:
+                        */
+                       smp_rmb();
                        return 0;
+               }
        }
 }
 
+static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h)
+{
+       int rv;
+
+       write_lock(&detail->hash_lock);
+       rv = cache_is_valid(detail, h);
+       if (rv != -EAGAIN) {
+               write_unlock(&detail->hash_lock);
+               return rv;
+       }
+       set_bit(CACHE_NEGATIVE, &h->flags);
+       cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
+       write_unlock(&detail->hash_lock);
+       cache_fresh_unlocked(h, detail);
+       return -ENOENT;
+}
+
 /*
  * This is the generic cache management routine for all
  * the authentication caches.
@@ -251,14 +277,8 @@ int cache_check(struct cache_detail *detail,
                        case -EINVAL:
                                clear_bit(CACHE_PENDING, &h->flags);
                                cache_revisit_request(h);
-                               if (rv == -EAGAIN) {
-                                       set_bit(CACHE_NEGATIVE, &h->flags);
-                                       cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY);
-                                       cache_fresh_unlocked(h, detail);
-                                       rv = -ENOENT;
-                               }
+                               rv = try_to_negate_entry(detail, h);
                                break;
-
                        case -EAGAIN:
                                clear_bit(CACHE_PENDING, &h->flags);
                                cache_revisit_request(h);
@@ -268,9 +288,11 @@ int cache_check(struct cache_detail *detail,
        }
 
        if (rv == -EAGAIN) {
-               cache_defer_req(rqstp, h);
-               if (!test_bit(CACHE_PENDING, &h->flags)) {
-                       /* Request is not deferred */
+               if (!cache_defer_req(rqstp, h)) {
+                       /*
+                        * Request was not deferred; handle it as best
+                        * we can ourselves:
+                        */
                        rv = cache_is_valid(detail, h);
                        if (rv == -EAGAIN)
                                rv = -ETIMEDOUT;
@@ -618,18 +640,19 @@ static void cache_limit_defers(void)
                discard->revisit(discard, 1);
 }
 
-static void cache_defer_req(struct cache_req *req, struct cache_head *item)
+/* Return true if and only if a deferred request is queued. */
+static bool cache_defer_req(struct cache_req *req, struct cache_head *item)
 {
        struct cache_deferred_req *dreq;
 
        if (req->thread_wait) {
                cache_wait_req(req, item);
                if (!test_bit(CACHE_PENDING, &item->flags))
-                       return;
+                       return false;
        }
        dreq = req->defer(req);
        if (dreq == NULL)
-               return;
+               return false;
        setup_deferral(dreq, item, 1);
        if (!test_bit(CACHE_PENDING, &item->flags))
                /* Bit could have been cleared before we managed to
@@ -638,6 +661,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
                cache_revisit_request(item);
 
        cache_limit_defers();
+       return true;
 }
 
 static void cache_revisit_request(struct cache_head *item)
index 0e659c665a8d8013e4507224c1b3753158492925..08e05a8ce0255b338cc9c812006302a79e7ad4a9 100644 (file)
@@ -1001,6 +1001,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
        rqstp->rq_splice_ok = 1;
        /* Will be turned off only when NFSv4 Sessions are used */
        rqstp->rq_usedeferral = 1;
+       rqstp->rq_dropme = false;
 
        /* Setup reply header */
        rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
@@ -1102,7 +1103,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
                *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
 
                /* Encode reply */
-               if (*statp == rpc_drop_reply) {
+               if (rqstp->rq_dropme) {
                        if (procp->pc_release)
                                procp->pc_release(rqstp, NULL, rqstp->rq_resp);
                        goto dropit;
index 3f2c5559ca1a49a496b9d531625c1e175fb029c8..ab86b7927f84594f188dadfa581271cf55b470cf 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sunrpc/stats.h>
 #include <linux/sunrpc/svc_xprt.h>
 #include <linux/sunrpc/svcsock.h>
+#include <linux/sunrpc/xprt.h>
 
 #define RPCDBG_FACILITY        RPCDBG_SVCXPRT
 
@@ -128,6 +129,9 @@ static void svc_xprt_free(struct kref *kref)
        if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags))
                svcauth_unix_info_release(xprt);
        put_net(xprt->xpt_net);
+       /* See comment on corresponding get in xs_setup_bc_tcp(): */
+       if (xprt->xpt_bc_xprt)
+               xprt_put(xprt->xpt_bc_xprt);
        xprt->xpt_ops->xpo_free(xprt);
        module_put(owner);
 }
@@ -303,6 +307,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp)
        list_del(&rqstp->rq_list);
 }
 
+static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt)
+{
+       if (xprt->xpt_flags & ((1<<XPT_CONN)|(1<<XPT_CLOSE)))
+               return true;
+       if (xprt->xpt_flags & ((1<<XPT_DATA)|(1<<XPT_DEFERRED)))
+               return xprt->xpt_ops->xpo_has_wspace(xprt);
+       return false;
+}
+
 /*
  * Queue up a transport with data pending. If there are idle nfsd
  * processes, wake 'em up.
@@ -315,8 +328,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
        struct svc_rqst *rqstp;
        int cpu;
 
-       if (!(xprt->xpt_flags &
-             ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
+       if (!svc_xprt_has_something_to_do(xprt))
                return;
 
        cpu = get_cpu();
@@ -343,28 +355,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
                dprintk("svc: transport %p busy, not enqueued\n", xprt);
                goto out_unlock;
        }
-       BUG_ON(xprt->xpt_pool != NULL);
-       xprt->xpt_pool = pool;
-
-       /* Handle pending connection */
-       if (test_bit(XPT_CONN, &xprt->xpt_flags))
-               goto process;
-
-       /* Handle close in-progress */
-       if (test_bit(XPT_CLOSE, &xprt->xpt_flags))
-               goto process;
-
-       /* Check if we have space to reply to a request */
-       if (!xprt->xpt_ops->xpo_has_wspace(xprt)) {
-               /* Don't enqueue while not enough space for reply */
-               dprintk("svc: no write space, transport %p  not enqueued\n",
-                       xprt);
-               xprt->xpt_pool = NULL;
-               clear_bit(XPT_BUSY, &xprt->xpt_flags);
-               goto out_unlock;
-       }
 
- process:
        if (!list_empty(&pool->sp_threads)) {
                rqstp = list_entry(pool->sp_threads.next,
                                   struct svc_rqst,
@@ -381,13 +372,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
                rqstp->rq_reserved = serv->sv_max_mesg;
                atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
                pool->sp_stats.threads_woken++;
-               BUG_ON(xprt->xpt_pool != pool);
                wake_up(&rqstp->rq_wait);
        } else {
                dprintk("svc: transport %p put into queue\n", xprt);
                list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
                pool->sp_stats.sockets_queued++;
-               BUG_ON(xprt->xpt_pool != pool);
        }
 
 out_unlock:
@@ -426,7 +415,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
 void svc_xprt_received(struct svc_xprt *xprt)
 {
        BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
-       xprt->xpt_pool = NULL;
        /* As soon as we clear busy, the xprt could be closed and
         * 'put', so we need a reference to call svc_xprt_enqueue with:
         */
@@ -722,7 +710,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
        if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
                dprintk("svc_recv: found XPT_CLOSE\n");
                svc_delete_xprt(xprt);
-       } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
+               /* Leave XPT_BUSY set on the dead xprt: */
+               goto out;
+       }
+       if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
                struct svc_xprt *newxpt;
                newxpt = xprt->xpt_ops->xpo_accept(xprt);
                if (newxpt) {
@@ -747,28 +738,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                        spin_unlock_bh(&serv->sv_lock);
                        svc_xprt_received(newxpt);
                }
-               svc_xprt_received(xprt);
-       } else {
+       } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
                dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
                        rqstp, pool->sp_id, xprt,
                        atomic_read(&xprt->xpt_ref.refcount));
                rqstp->rq_deferred = svc_deferred_dequeue(xprt);
-               if (rqstp->rq_deferred) {
-                       svc_xprt_received(xprt);
+               if (rqstp->rq_deferred)
                        len = svc_deferred_recv(rqstp);
-               } else {
+               else
                        len = xprt->xpt_ops->xpo_recvfrom(rqstp);
-                       svc_xprt_received(xprt);
-               }
                dprintk("svc: got len=%d\n", len);
        }
+       svc_xprt_received(xprt);
 
        /* No data, incomplete (TCP) read, or accept() */
-       if (len == 0 || len == -EAGAIN) {
-               rqstp->rq_res.len = 0;
-               svc_xprt_release(rqstp);
-               return -EAGAIN;
-       }
+       if (len == 0 || len == -EAGAIN)
+               goto out;
+
        clear_bit(XPT_OLD, &xprt->xpt_flags);
 
        rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp));
@@ -777,6 +763,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
        if (serv->sv_stats)
                serv->sv_stats->netcnt++;
        return len;
+out:
+       rqstp->rq_res.len = 0;
+       svc_xprt_release(rqstp);
+       return -EAGAIN;
 }
 EXPORT_SYMBOL_GPL(svc_recv);
 
@@ -935,7 +925,12 @@ void svc_close_xprt(struct svc_xprt *xprt)
        if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
                /* someone else will have to effect the close */
                return;
-
+       /*
+        * We expect svc_close_xprt() to work even when no threads are
+        * running (e.g., while configuring the server before starting
+        * any threads), so if the transport isn't busy, we delete
+        * it ourself:
+        */
        svc_delete_xprt(xprt);
 }
 EXPORT_SYMBOL_GPL(svc_close_xprt);
@@ -945,16 +940,16 @@ void svc_close_all(struct list_head *xprt_list)
        struct svc_xprt *xprt;
        struct svc_xprt *tmp;
 
+       /*
+        * The server is shutting down, and no more threads are running.
+        * svc_xprt_enqueue() might still be running, but at worst it
+        * will re-add the xprt to sp_sockets, which will soon get
+        * freed.  So we don't bother with any more locking, and don't
+        * leave the close to the (nonexistent) server threads:
+        */
        list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
                set_bit(XPT_CLOSE, &xprt->xpt_flags);
-               if (test_bit(XPT_BUSY, &xprt->xpt_flags)) {
-                       /* Waiting to be processed, but no threads left,
-                        * So just remove it from the waiting list
-                        */
-                       list_del_init(&xprt->xpt_ready);
-                       clear_bit(XPT_BUSY, &xprt->xpt_flags);
-               }
-               svc_close_xprt(xprt);
+               svc_delete_xprt(xprt);
        }
 }
 
@@ -1028,6 +1023,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
        }
        svc_xprt_get(rqstp->rq_xprt);
        dr->xprt = rqstp->rq_xprt;
+       rqstp->rq_dropme = true;
 
        dr->handle.revisit = svc_revisit;
        return &dr->handle;
@@ -1065,14 +1061,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt)
        if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags))
                return NULL;
        spin_lock(&xprt->xpt_lock);
-       clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
        if (!list_empty(&xprt->xpt_deferred)) {
                dr = list_entry(xprt->xpt_deferred.next,
                                struct svc_deferred_req,
                                handle.recent);
                list_del_init(&dr->handle.recent);
-               set_bit(XPT_DEFERRED, &xprt->xpt_flags);
-       }
+       } else
+               clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
        spin_unlock(&xprt->xpt_lock);
        return dr;
 }
index 4e9393c24687ffac1a51527de4b7d384234b6e53..7963569fc04f014745c96054946d82cde28aa879 100644 (file)
@@ -118,7 +118,6 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister);
 
 #define        DN_HASHBITS     6
 #define        DN_HASHMAX      (1<<DN_HASHBITS)
-#define        DN_HASHMASK     (DN_HASHMAX-1)
 
 static struct hlist_head       auth_domain_table[DN_HASHMAX];
 static spinlock_t      auth_domain_lock =
index 560677d187f1b0fc7eb3d72c119aa848eb306145..30916b06c12bd7f5ade9f9cea0641e51ac52e528 100644 (file)
@@ -30,7 +30,9 @@
 
 struct unix_domain {
        struct auth_domain      h;
+#ifdef CONFIG_NFSD_DEPRECATED
        int     addr_changes;
+#endif /* CONFIG_NFSD_DEPRECATED */
        /* other stuff later */
 };
 
@@ -64,7 +66,9 @@ struct auth_domain *unix_domain_find(char *name)
                        return NULL;
                }
                new->h.flavour = &svcauth_unix;
+#ifdef CONFIG_NFSD_DEPRECATED
                new->addr_changes = 0;
+#endif /* CONFIG_NFSD_DEPRECATED */
                rv = auth_domain_lookup(name, &new->h);
        }
 }
@@ -85,14 +89,15 @@ static void svcauth_unix_domain_release(struct auth_domain *dom)
  */
 #define        IP_HASHBITS     8
 #define        IP_HASHMAX      (1<<IP_HASHBITS)
-#define        IP_HASHMASK     (IP_HASHMAX-1)
 
 struct ip_map {
        struct cache_head       h;
        char                    m_class[8]; /* e.g. "nfsd" */
        struct in6_addr         m_addr;
        struct unix_domain      *m_client;
+#ifdef CONFIG_NFSD_DEPRECATED
        int                     m_add_change;
+#endif /* CONFIG_NFSD_DEPRECATED */
 };
 
 static void ip_map_put(struct kref *kref)
@@ -146,7 +151,9 @@ static void update(struct cache_head *cnew, struct cache_head *citem)
 
        kref_get(&item->m_client->h.ref);
        new->m_client = item->m_client;
+#ifdef CONFIG_NFSD_DEPRECATED
        new->m_add_change = item->m_add_change;
+#endif /* CONFIG_NFSD_DEPRECATED */
 }
 static struct cache_head *ip_map_alloc(void)
 {
@@ -331,6 +338,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
        ip.h.flags = 0;
        if (!udom)
                set_bit(CACHE_NEGATIVE, &ip.h.flags);
+#ifdef CONFIG_NFSD_DEPRECATED
        else {
                ip.m_add_change = udom->addr_changes;
                /* if this is from the legacy set_client system call,
@@ -339,6 +347,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
                if (expiry == NEVER)
                        ip.m_add_change++;
        }
+#endif /* CONFIG_NFSD_DEPRECATED */
        ip.h.expiry_time = expiry;
        ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
                                 hash_str(ipm->m_class, IP_HASHBITS) ^
@@ -358,6 +367,7 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm,
        return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry);
 }
 
+#ifdef CONFIG_NFSD_DEPRECATED
 int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom)
 {
        struct unix_domain *udom;
@@ -402,8 +412,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
                return NULL;
 
        if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) {
-               if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0)
-                       auth_domain_put(&ipm->m_client->h);
+               sunrpc_invalidate(&ipm->h, sn->ip_map_cache);
                rv = NULL;
        } else {
                rv = &ipm->m_client->h;
@@ -413,6 +422,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr)
        return rv;
 }
 EXPORT_SYMBOL_GPL(auth_unix_lookup);
+#endif /* CONFIG_NFSD_DEPRECATED */
 
 void svcauth_unix_purge(void)
 {
@@ -497,7 +507,6 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
  */
 #define        GID_HASHBITS    8
 #define        GID_HASHMAX     (1<<GID_HASHBITS)
-#define        GID_HASHMASK    (GID_HASHMAX - 1)
 
 struct unix_gid {
        struct cache_head       h;
index d265aa700bb3dc9fd036ceef3e3650f8e9b59533..7bd3bbba4710d82ff658bd6de998543bca0609a7 100644 (file)
@@ -331,19 +331,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen,
                        len = onelen;
                        break;
                }
-               if (toclose && strcmp(toclose, buf + len) == 0)
+               if (toclose && strcmp(toclose, buf + len) == 0) {
                        closesk = svsk;
-               else
+                       svc_xprt_get(&closesk->sk_xprt);
+               } else
                        len += onelen;
        }
        spin_unlock_bh(&serv->sv_lock);
 
-       if (closesk)
+       if (closesk) {
                /* Should unregister with portmap, but you cannot
                 * unregister just one protocol...
                 */
                svc_close_xprt(&closesk->sk_xprt);
-       else if (toclose)
+               svc_xprt_put(&closesk->sk_xprt);
+       } else if (toclose)
                return -ENOENT;
        return len;
 }
@@ -992,15 +994,17 @@ static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp,
                vec[0] = rqstp->rq_arg.head[0];
        } else {
                /* REPLY */
-               if (svsk->sk_bc_xprt)
-                       req = xprt_lookup_rqst(svsk->sk_bc_xprt, xid);
+               struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt;
+
+               if (bc_xprt)
+                       req = xprt_lookup_rqst(bc_xprt, xid);
 
                if (!req) {
                        printk(KERN_NOTICE
                                "%s: Got unrecognized reply: "
-                               "calldir 0x%x sk_bc_xprt %p xid %08x\n",
+                               "calldir 0x%x xpt_bc_xprt %p xid %08x\n",
                                __func__, ntohl(calldir),
-                               svsk->sk_bc_xprt, xid);
+                               bc_xprt, xid);
                        vec[0] = rqstp->rq_arg.head[0];
                        goto out;
                }
index 4c8f18aff7c341885764c6f1525a292688328c5d..856274d7e85c21eb6b89feff50ff767986b344e2 100644 (file)
@@ -965,6 +965,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req)
        xprt = kzalloc(size, GFP_KERNEL);
        if (xprt == NULL)
                goto out;
+       kref_init(&xprt->kref);
 
        xprt->max_reqs = max_req;
        xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL);
@@ -1101,8 +1102,10 @@ found:
                                -PTR_ERR(xprt));
                return xprt;
        }
+       if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state))
+               /* ->setup returned a pre-initialized xprt: */
+               return xprt;
 
-       kref_init(&xprt->kref);
        spin_lock_init(&xprt->transport_lock);
        spin_lock_init(&xprt->reserve_lock);
 
index 96549df836ee0ed5da8285960e88c47f9d6b107d..c431f5a579605bfa5ea33161ff45188ab4bd570d 100644 (file)
@@ -2359,6 +2359,15 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        struct svc_sock *bc_sock;
        struct rpc_xprt *ret;
 
+       if (args->bc_xprt->xpt_bc_xprt) {
+               /*
+                * This server connection already has a backchannel
+                * export; we can't create a new one, as we wouldn't be
+                * able to match replies based on xid any more.  So,
+                * reuse the already-existing one:
+                */
+                return args->bc_xprt->xpt_bc_xprt;
+       }
        xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
        if (IS_ERR(xprt))
                return xprt;
@@ -2375,16 +2384,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        xprt->reestablish_timeout = 0;
        xprt->idle_timeout = 0;
 
-       /*
-        * The backchannel uses the same socket connection as the
-        * forechannel
-        */
-       xprt->bc_xprt = args->bc_xprt;
-       bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt);
-       bc_sock->sk_bc_xprt = xprt;
-       transport->sock = bc_sock->sk_sock;
-       transport->inet = bc_sock->sk_sk;
-
        xprt->ops = &bc_tcp_ops;
 
        switch (addr->sa_family) {
@@ -2406,6 +2405,20 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
                        xprt->address_strings[RPC_DISPLAY_PORT],
                        xprt->address_strings[RPC_DISPLAY_PROTO]);
 
+       /*
+        * Once we've associated a backchannel xprt with a connection,
+        * we want to keep it around as long as long as the connection
+        * lasts, in case we need to start using it for a backchannel
+        * again; this reference won't be dropped until bc_xprt is
+        * destroyed.
+        */
+       xprt_get(xprt);
+       args->bc_xprt->xpt_bc_xprt = xprt;
+       xprt->bc_xprt = args->bc_xprt;
+       bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt);
+       transport->sock = bc_sock->sk_sock;
+       transport->inet = bc_sock->sk_sk;
+
        /*
         * Since we don't want connections for the backchannel, we set
         * the xprt status to connected
@@ -2415,6 +2428,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
 
        if (try_module_get(THIS_MODULE))
                return xprt;
+       xprt_put(xprt);
        ret = ERR_PTR(-EINVAL);
 out_err:
        xprt_free(xprt);