Merge branch 'for_3.5/omap_misc_cleanup' of git://gitorious.org/omap-sw-develoment...
authorTony Lindgren <tony@atomide.com>
Tue, 8 May 2012 17:17:23 +0000 (10:17 -0700)
committerTony Lindgren <tony@atomide.com>
Tue, 8 May 2012 17:17:23 +0000 (10:17 -0700)
226 files changed:
Documentation/devicetree/bindings/ata/ahci-platform.txt [new file with mode: 0644]
Documentation/devicetree/bindings/ata/calxeda-sata.txt [deleted file]
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/networking/ip-sysctl.txt
MAINTAINERS
Makefile
arch/alpha/Kconfig
arch/alpha/include/asm/rtc.h
arch/alpha/kernel/core_tsunami.c
arch/alpha/kernel/sys_marvel.c
arch/arm/Kconfig
arch/arm/boot/dts/versatile-ab.dts
arch/arm/boot/dts/versatile-pb.dts
arch/arm/include/asm/thread_info.h
arch/arm/include/asm/tls.h
arch/arm/kernel/irq.c
arch/arm/kernel/signal.c
arch/arm/kernel/smp.c
arch/arm/mm/abort-ev6.S
arch/arm/mm/cache-l2x0.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/plat-omap/dma.c
arch/arm/vfp/vfpmodule.c
arch/mips/ath79/dev-wmac.c
arch/mips/include/asm/mach-jz4740/irq.h
arch/mips/include/asm/mmu_context.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/parisc/kernel/pdc_cons.c
arch/powerpc/include/asm/irq.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/machine_kexec.c
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit_64.S
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_interrupt.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/sysdev/cpm2_pic.c
arch/powerpc/sysdev/mpc8xx_pic.c
arch/powerpc/sysdev/xics/xics-common.c
arch/x86/Kconfig
arch/x86/boot/compressed/relocs.c
arch/x86/ia32/ia32_aout.c
arch/x86/include/asm/word-at-a-time.h
arch/x86/kernel/cpu/amd.c
arch/x86/platform/geode/net5501.c
drivers/acpi/power.c
drivers/acpi/scan.c
drivers/ata/ahci.c
drivers/ata/ahci_platform.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/pata_arasan_cf.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/firmware/efivars.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_hdmi.c
drivers/gpu/drm/nouveau/nv10_gpio.c
drivers/gpu/drm/nouveau/nvc0_fb.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/hwmon/coretemp.c
drivers/i2c/busses/i2c-eg20t.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-tegra.c
drivers/input/mouse/synaptics.c
drivers/md/bitmap.c
drivers/md/bitmap.h
drivers/mfd/omap-usb-host.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
drivers/net/ethernet/dlink/dl2k.c
drivers/net/ethernet/dlink/dl2k.h
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/freescale/ucc_geth.h
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/ibm/ehea/ehea_phyp.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/e1000e/param.c
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/marvell/sky2.h
drivers/net/ethernet/sun/sungem.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/ethernet/ti/tlan.c
drivers/net/usb/asix.c
drivers/net/usb/smsc75xx.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/wireless/ath/ath5k/ahb.c
drivers/net/wireless/ath/ath9k/ar5008_phy.c
drivers/net/wireless/ath/ath9k/ar9003_paprd.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/b43/main.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
drivers/net/wireless/brcm80211/brcmsmac/main.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-mac80211.c
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/wl1251/main.c
drivers/net/wireless/wl1251/sdio.c
drivers/pci/pci-acpi.c
drivers/platform/x86/intel_mid_powerbtn.c
drivers/rtc/rtc-mpc5121.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/ipr.c
drivers/scsi/libfc/fc_lport.c
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_event.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsas/sas_init.c
drivers/scsi/libsas/sas_internal.h
drivers/scsi/libsas/sas_phy.c
drivers/scsi/libsas/sas_port.c
drivers/scsi/scsi_lib.c
drivers/tty/serial/pmac_zilog.c
drivers/tty/vt/keyboard.c
drivers/usb/host/ehci-tegra.c
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/ioctl.h
fs/btrfs/scrub.c
fs/btrfs/tree-log.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/dcache.c
fs/hfsplus/catalog.c
fs/hfsplus/dir.c
fs/namei.c
fs/nfs/blocklayout/blocklayout.c
fs/nfs/client.c
fs/nfs/idmap.c
fs/nfs/internal.h
fs/nfs/namespace.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4filelayoutdev.c
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/objlayout/objlayout.c
fs/nfs/pnfs.c
fs/nfs/super.c
fs/nfsd/nfs4recover.c
include/acpi/actypes.h
include/asm-generic/statfs.h
include/linux/efi.h
include/linux/libata.h
include/linux/netfilter_bridge.h
include/linux/seqlock.h
include/linux/skbuff.h
include/net/bluetooth/hci_core.h
include/net/dst.h
include/net/ip_vs.h
include/net/sock.h
include/scsi/libsas.h
include/scsi/sas_ata.h
init/do_mounts.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/bridge/br_forward.c
net/bridge/br_netfilter.c
net/core/drop_monitor.c
net/ieee802154/6lowpan.c
net/ipv4/inet_diag.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/udp_diag.c
net/l2tp/l2tp_ip.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/tx.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/ipvs/ip_vs_proto_tcp.c
net/netfilter/ipvs/ip_vs_proto_udp.c
net/netfilter/xt_CT.c
net/sched/sch_netem.c
net/sunrpc/clnt.c
net/sunrpc/rpc_pipe.c
sound/soc/blackfin/bf5xx-ssm2602.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm_hubs.c
sound/soc/omap/omap-pcm.c
sound/soc/samsung/s3c2412-i2s.c
sound/soc/soc-core.c
tools/testing/ktest/ktest.pl

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
new file mode 100644 (file)
index 0000000..8bb8a76
--- /dev/null
@@ -0,0 +1,16 @@
+* AHCI SATA Controller
+
+SATA nodes are defined to describe on-chip Serial ATA controllers.
+Each SATA controller should have its own node.
+
+Required properties:
+- compatible        : compatible list, contains "calxeda,hb-ahci" or "snps,spear-ahci"
+- interrupts        : <interrupt mapping for SATA IRQ>
+- reg               : <registers mapping>
+
+Example:
+        sata@ffe08000 {
+               compatible = "calxeda,hb-ahci";
+                reg = <0xffe08000 0x1000>;
+                interrupts = <115>;
+        };
diff --git a/Documentation/devicetree/bindings/ata/calxeda-sata.txt b/Documentation/devicetree/bindings/ata/calxeda-sata.txt
deleted file mode 100644 (file)
index 79caa56..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-* Calxeda SATA Controller
-
-SATA nodes are defined to describe on-chip Serial ATA controllers.
-Each SATA controller should have its own node.
-
-Required properties:
-- compatible        : compatible list, contains "calxeda,hb-ahci"
-- interrupts        : <interrupt mapping for SATA IRQ>
-- reg               : <registers mapping>
-
-Example:
-        sata@ffe08000 {
-               compatible = "calxeda,hb-ahci";
-                reg = <0xffe08000 0x1000>;
-                interrupts = <115>;
-        };
-
index 2c3cd413f042522ed9877061c728df94bb4f46e8..9cc44449508df9f2ee6704acf59b113a6ad9e079 100644 (file)
@@ -3,6 +3,8 @@
 Required properties:
 - compatible : "fsl,sgtl5000".
 
+- reg : the I2C address of the device
+
 Example:
 
 codec: sgtl5000@0a {
index bd80ba5847d2b8b44548180c7cd9f912832bc4f1..1619a8c8087341477621388701fec82ca832b70b 100644 (file)
@@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER
        (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale),
        if it is <= 0.
        Possible values are [-31, 31], inclusive.
-       Default: 2
+       Default: 1
 
 tcp_allowed_congestion_control - STRING
        Show/set the congestion control choices available to non-privileged
@@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
        net.core.rmem_max.  Calling setsockopt() with SO_RCVBUF disables
        automatic tuning of that socket's receive buffer size, in which
        case this value is ignored.
-       Default: between 87380B and 4MB, depending on RAM size.
+       Default: between 87380B and 6MB, depending on RAM size.
 
 tcp_sack - BOOLEAN
        Enable select acknowledgments (SACKS).
index bb76fc42fc42ee4d7b2d9f218d71422cfcfca357..707163365a9308845de03708d43fcbdde8c5452c 100644 (file)
@@ -1968,10 +1968,7 @@ S:       Maintained
 F:     drivers/net/ethernet/ti/cpmac.c
 
 CPU FREQUENCY DRIVERS
-M:     Dave Jones <davej@redhat.com>
 L:     cpufreq@vger.kernel.org
-W:     http://www.codemonkey.org.uk/projects/cpufreq/
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
 S:     Maintained
 F:     drivers/cpufreq/
 F:     include/linux/cpufreq.h
@@ -5892,11 +5889,11 @@ F:      Documentation/scsi/st.txt
 F:     drivers/scsi/st*
 
 SCTP PROTOCOL
-M:     Vlad Yasevich <vladislav.yasevich@hp.com>
+M:     Vlad Yasevich <vyasevich@gmail.com>
 M:     Sridhar Samudrala <sri@us.ibm.com>
 L:     linux-sctp@vger.kernel.org
 W:     http://lksctp.sourceforge.net
-S:     Supported
+S:     Maintained
 F:     Documentation/networking/sctp.txt
 F:     include/linux/sctp.h
 F:     include/net/sctp/
index a06ee9fa8022ca6e102a3b649afc8dade403bc9f..9e384ae6c403cb92d3ed633b3e033bf3a6c3c3de 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 4
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index 56a4df952fb0f2e68889229133e38b2b34de4716..22e58a99f38b0fd19232ec8fec64249ca429846f 100644 (file)
@@ -477,7 +477,7 @@ config ALPHA_BROKEN_IRQ_MASK
 
 config VGA_HOSE
        bool
-       depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI
+       depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI)
        default y
        help
          Support VGA on an arbitrary hose; needed for several platforms
index 1f7fba671ae68a25f204cf819e3e04bde362810e..d70408d36677c86d0fbd8ce90530724e54d15a57 100644 (file)
@@ -1,14 +1,10 @@
 #ifndef _ALPHA_RTC_H
 #define _ALPHA_RTC_H
 
-#if defined(CONFIG_ALPHA_GENERIC)
+#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \
+ || defined(CONFIG_ALPHA_GENERIC)
 # define get_rtc_time          alpha_mv.rtc_get_time
 # define set_rtc_time          alpha_mv.rtc_set_time
-#else
-# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP)
-#  define get_rtc_time         marvel_get_rtc_time
-#  define set_rtc_time         marvel_set_rtc_time
-# endif
 #endif
 
 #include <asm-generic/rtc.h>
index 5e7c28f92f19f29dde28d0e636ceb696f1750457..61893d7bdda552ac50e9fadadf957c6b6badb668 100644 (file)
@@ -11,6 +11,7 @@
 #include <asm/core_tsunami.h>
 #undef __EXTERN_INLINE
 
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
index 14a4b6a7cf59d3fa94b121714c7e3c67792618e8..407accc808777bc4a6f36fa6b912b92686d09a0b 100644 (file)
@@ -317,7 +317,7 @@ marvel_init_irq(void)
 }
 
 static int 
-marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
        struct pci_controller *hose = dev->sysdata;
        struct io7_port *io7_port = hose->sysdata;
index cf006d40342ca4d51a0128ca0ae60dc36452cd6f..36586dba6fa6e0af6260dce3827cfe1495c7f592 100644 (file)
@@ -1186,6 +1186,15 @@ if !MMU
 source "arch/arm/Kconfig-nommu"
 endif
 
+config ARM_ERRATA_326103
+       bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory"
+       depends on CPU_V6
+       help
+         Executing a SWP instruction to read-only memory does not set bit 11
+         of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to
+         treat the access as a read, preventing a COW from occurring and
+         causing the faulting task to livelock.
+
 config ARM_ERRATA_411920
        bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
        depends on CPU_V6 || CPU_V6K
index 0b32925f21474fcb983716aed17205bd50ee10a3..e2fe3195c0d109c6a31853455171627724c2e2d8 100644 (file)
                        mmc@5000 {
                                compatible = "arm,primecell";
                                reg = < 0x5000 0x1000>;
-                               interrupts = <22>;
+                               interrupts = <22 34>;
                        };
                        kmi@6000 {
                                compatible = "arm,pl050", "arm,primecell";
index 166461073b7893ec6dc49a60957bf8ef1d3e106f..7e8175269064d6f5dbf0a0b3bca1b933aa5efd9f 100644 (file)
@@ -41,7 +41,7 @@
                        mmc@b000 {
                                compatible = "arm,primecell";
                                reg = <0xb000 0x1000>;
-                               interrupts = <23>;
+                               interrupts = <23 34>;
                        };
                };
        };
index d4c24d412a8ddbdaba9f11a6217cd6a8b592c22c..0f04d84582e1d81ef5448ee180d23b42c80a2eee 100644 (file)
@@ -118,6 +118,13 @@ extern void iwmmxt_task_switch(struct thread_info *);
 extern void vfp_sync_hwstate(struct thread_info *);
 extern void vfp_flush_hwstate(struct thread_info *);
 
+struct user_vfp;
+struct user_vfp_exc;
+
+extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *,
+                                          struct user_vfp_exc __user *);
+extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+                                   struct user_vfp_exc __user *);
 #endif
 
 /*
index 60843eb0f61c3f9f9536d3ebaebc05b3cdfd2189..73409e6c0251001b5b03f27ae811a523cc605f62 100644 (file)
@@ -7,6 +7,8 @@
 
        .macro set_tls_v6k, tp, tmp1, tmp2
        mcr     p15, 0, \tp, c13, c0, 3         @ set TLS register
+       mov     \tmp1, #0
+       mcr     p15, 0, \tmp1, c13, c0, 2       @ clear user r/w TLS register
        .endm
 
        .macro set_tls_v6, tp, tmp1, tmp2
@@ -15,6 +17,8 @@
        mov     \tmp2, #0xffff0fff
        tst     \tmp1, #HWCAP_TLS               @ hardware TLS available?
        mcrne   p15, 0, \tp, c13, c0, 3         @ yes, set TLS register
+       movne   \tmp1, #0
+       mcrne   p15, 0, \tmp1, c13, c0, 2       @ clear user r/w TLS register
        streq   \tp, [\tmp2, #-15]              @ set TLS value at 0xffff0ff0
        .endm
 
index 71ccdbfed66276f2c76db1b683da17cab392f0ad..8349d4e97e2b8b9b7bb5672b2cf974c2cdb74fd0 100644 (file)
@@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc)
        }
 
        c = irq_data_get_irq_chip(d);
-       if (c->irq_set_affinity)
-               c->irq_set_affinity(d, affinity, true);
-       else
+       if (!c->irq_set_affinity)
                pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+       else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
+               cpumask_copy(d->affinity, affinity);
 
        return ret;
 }
index 7cb532fc8aa4e3a9dc1e9d63d4cb887a08b1fad1..d68d1b6946809831458d03d8a020ea32f571c62f 100644 (file)
@@ -180,44 +180,23 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
 
 static int preserve_vfp_context(struct vfp_sigframe __user *frame)
 {
-       struct thread_info *thread = current_thread_info();
-       struct vfp_hard_struct *h = &thread->vfpstate.hard;
        const unsigned long magic = VFP_MAGIC;
        const unsigned long size = VFP_STORAGE_SIZE;
        int err = 0;
 
-       vfp_sync_hwstate(thread);
        __put_user_error(magic, &frame->magic, err);
        __put_user_error(size, &frame->size, err);
 
-       /*
-        * Copy the floating point registers. There can be unused
-        * registers see asm/hwcap.h for details.
-        */
-       err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
-                             sizeof(h->fpregs));
-       /*
-        * Copy the status and control register.
-        */
-       __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
-
-       /*
-        * Copy the exception registers.
-        */
-       __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
-       __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
-       __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+       if (err)
+               return -EFAULT;
 
-       return err ? -EFAULT : 0;
+       return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc);
 }
 
 static int restore_vfp_context(struct vfp_sigframe __user *frame)
 {
-       struct thread_info *thread = current_thread_info();
-       struct vfp_hard_struct *h = &thread->vfpstate.hard;
        unsigned long magic;
        unsigned long size;
-       unsigned long fpexc;
        int err = 0;
 
        __get_user_error(magic, &frame->magic, err);
@@ -228,33 +207,7 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame)
        if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
                return -EINVAL;
 
-       vfp_flush_hwstate(thread);
-
-       /*
-        * Copy the floating point registers. There can be unused
-        * registers see asm/hwcap.h for details.
-        */
-       err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
-                               sizeof(h->fpregs));
-       /*
-        * Copy the status and control register.
-        */
-       __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
-
-       /*
-        * Sanitise and restore the exception registers.
-        */
-       __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
-       /* Ensure the VFP is enabled. */
-       fpexc |= FPEXC_EN;
-       /* Ensure FPINST2 is invalid and the exception flag is cleared. */
-       fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
-       h->fpexc = fpexc;
-
-       __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
-       __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
-
-       return err ? -EFAULT : 0;
+       return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc);
 }
 
 #endif
index addbbe8028c29c8789fd730fa784b056065787e5..f6a4d32b0421a9dd35fa1ca2884e8980374a76a3 100644 (file)
@@ -510,10 +510,6 @@ static void ipi_cpu_stop(unsigned int cpu)
        local_fiq_disable();
        local_irq_disable();
 
-#ifdef CONFIG_HOTPLUG_CPU
-       platform_cpu_kill(cpu);
-#endif
-
        while (1)
                cpu_relax();
 }
@@ -576,17 +572,25 @@ void smp_send_reschedule(int cpu)
        smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static void smp_kill_cpus(cpumask_t *mask)
+{
+       unsigned int cpu;
+       for_each_cpu(cpu, mask)
+               platform_cpu_kill(cpu);
+}
+#else
+static void smp_kill_cpus(cpumask_t *mask) { }
+#endif
+
 void smp_send_stop(void)
 {
        unsigned long timeout;
+       struct cpumask mask;
 
-       if (num_online_cpus() > 1) {
-               struct cpumask mask;
-               cpumask_copy(&mask, cpu_online_mask);
-               cpumask_clear_cpu(smp_processor_id(), &mask);
-
-               smp_cross_call(&mask, IPI_CPU_STOP);
-       }
+       cpumask_copy(&mask, cpu_online_mask);
+       cpumask_clear_cpu(smp_processor_id(), &mask);
+       smp_cross_call(&mask, IPI_CPU_STOP);
 
        /* Wait up to one second for other CPUs to stop */
        timeout = USEC_PER_SEC;
@@ -595,6 +599,8 @@ void smp_send_stop(void)
 
        if (num_online_cpus() > 1)
                pr_warning("SMP: failed to stop secondary CPUs\n");
+
+       smp_kill_cpus(&mask);
 }
 
 /*
index ff1f7cc11f87bdee1509757c7cd0c3cf7c105754..80741992a9fcff0b98d963ec3465bf407c51c5f6 100644 (file)
@@ -26,18 +26,23 @@ ENTRY(v6_early_abort)
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
 /*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
- * The test below covers all the write situations, including Java bytecodes
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
  */
-       bic     r1, r1, #1 << 11                @ clear bit 11 of FSR
+#ifdef CONFIG_ARM_ERRATA_326103
+       ldr     ip, =0x4107b36
+       mrc     p15, 0, r3, c0, c0, 0           @ get processor id
+       teq     ip, r3, lsr #4                  @ r0 ARM1136?
+       bne     do_DataAbort
        tst     r5, #PSR_J_BIT                  @ Java?
+       tsteq   r5, #PSR_T_BIT                  @ Thumb?
        bne     do_DataAbort
-       do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
-       ldreq   r3, [r4]                        @ read aborted ARM instruction
+       bic     r1, r1, #1 << 11                @ clear bit 11 of FSR
+       ldr     r3, [r4]                        @ read aborted ARM instruction
 #ifdef CONFIG_CPU_ENDIAN_BE8
-       reveq   r3, r3
+       rev     r3, r3
 #endif
        do_ldrd_abort tmp=ip, insn=r3
        tst     r3, #1 << 20                    @ L = 0 -> write
        orreq   r1, r1, #1 << 11                @ yes.
+#endif
        b       do_DataAbort
index a53fd2aaa2f4b59397bfa01847b22cd991bcdd8b..2a8e380501e81a2c0bcaf08c8d018f0c9f20050c 100644 (file)
@@ -32,6 +32,7 @@ static void __iomem *l2x0_base;
 static DEFINE_RAW_SPINLOCK(l2x0_lock);
 static u32 l2x0_way_mask;      /* Bitmask of active ways */
 static u32 l2x0_size;
+static unsigned long sync_reg_offset = L2X0_CACHE_SYNC;
 
 struct l2x0_regs l2x0_saved_regs;
 
@@ -61,12 +62,7 @@ static inline void cache_sync(void)
 {
        void __iomem *base = l2x0_base;
 
-#ifdef CONFIG_PL310_ERRATA_753970
-       /* write to an unmmapped register */
-       writel_relaxed(0, base + L2X0_DUMMY_REG);
-#else
-       writel_relaxed(0, base + L2X0_CACHE_SYNC);
-#endif
+       writel_relaxed(0, base + sync_reg_offset);
        cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
 
@@ -85,10 +81,13 @@ static inline void l2x0_inv_line(unsigned long addr)
 }
 
 #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
+static inline void debug_writel(unsigned long val)
+{
+       if (outer_cache.set_debug)
+               outer_cache.set_debug(val);
+}
 
-#define debug_writel(val)      outer_cache.set_debug(val)
-
-static void l2x0_set_debug(unsigned long val)
+static void pl310_set_debug(unsigned long val)
 {
        writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
 }
@@ -98,7 +97,7 @@ static inline void debug_writel(unsigned long val)
 {
 }
 
-#define l2x0_set_debug NULL
+#define pl310_set_debug        NULL
 #endif
 
 #ifdef CONFIG_PL310_ERRATA_588369
@@ -331,6 +330,11 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
                else
                        ways = 8;
                type = "L310";
+#ifdef CONFIG_PL310_ERRATA_753970
+               /* Unmapped register. */
+               sync_reg_offset = L2X0_DUMMY_REG;
+#endif
+               outer_cache.set_debug = pl310_set_debug;
                break;
        case L2X0_CACHE_ID_PART_L210:
                ways = (aux >> 13) & 0xf;
@@ -379,7 +383,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
        outer_cache.flush_all = l2x0_flush_all;
        outer_cache.inv_all = l2x0_inv_all;
        outer_cache.disable = l2x0_disable;
-       outer_cache.set_debug = l2x0_set_debug;
 
        printk(KERN_INFO "%s cache controller enabled\n", type);
        printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",
index 595079fa9d1d2eb342afae05f3b29a4395b87331..8f5813bbffb560b15b44974ff3543f0b5457e026 100644 (file)
@@ -293,11 +293,11 @@ EXPORT_SYMBOL(pfn_valid);
 #endif
 
 #ifndef CONFIG_SPARSEMEM
-static void arm_memory_present(void)
+static void __init arm_memory_present(void)
 {
 }
 #else
-static void arm_memory_present(void)
+static void __init arm_memory_present(void)
 {
        struct memblock_region *reg;
 
index b86f8933ff918908e107afe40553388e0e207988..2c7cf2f9c837263504b139e44137ac027724bd0e 100644 (file)
@@ -618,8 +618,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr,
        }
 }
 
-static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
-       unsigned long phys, const struct mem_type *type)
+static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
+       unsigned long end, unsigned long phys, const struct mem_type *type)
 {
        pud_t *pud = pud_offset(pgd, addr);
        unsigned long next;
index c046a1942ef76c043dd3a3e26f4d789e86804c01..807ce4c45ef37abcb942b53b70e1b940f2555de3 100644 (file)
@@ -916,6 +916,13 @@ void omap_start_dma(int lch)
                        l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
        l |= OMAP_DMA_CCR_EN;
 
+       /*
+        * As dma_write() uses IO accessors which are weakly ordered, there
+        * is no guarantee that data in coherent DMA memory will be visible
+        * to the DMA device.  Add a memory barrier here to ensure that any
+        * such data is visible prior to enabling DMA.
+        */
+       mb();
        p->dma_write(l, CCR, lch);
 
        dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
@@ -965,6 +972,13 @@ void omap_stop_dma(int lch)
                p->dma_write(l, CCR, lch);
        }
 
+       /*
+        * Ensure that data transferred by DMA is visible to any access
+        * after DMA has been disabled.  This is important for coherent
+        * DMA regions.
+        */
+       mb();
+
        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
                int next_lch, cur_lch = lch;
                char dma_chan_link_map[dma_lch_count];
index 858748eaa144f91c7f9b4c88fbc8bb83a8d419d7..bc683b8219b5bf3715345742b0d41d4746e4746b 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/uaccess.h>
+#include <linux/user.h>
 
 #include <asm/cp15.h>
 #include <asm/cputype.h>
@@ -528,6 +530,103 @@ void vfp_flush_hwstate(struct thread_info *thread)
        put_cpu();
 }
 
+/*
+ * Save the current VFP state into the provided structures and prepare
+ * for entry into a new function (signal handler).
+ */
+int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp,
+                                   struct user_vfp_exc __user *ufp_exc)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
+       int err = 0;
+
+       /* Ensure that the saved hwstate is up-to-date. */
+       vfp_sync_hwstate(thread);
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs,
+                             sizeof(hwstate->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __put_user_error(hwstate->fpscr, &ufp->fpscr, err);
+
+       /*
+        * Copy the exception registers.
+        */
+       __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err);
+       __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
+       __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
+
+       if (err)
+               return -EFAULT;
+
+       /* Ensure that VFP is disabled. */
+       vfp_flush_hwstate(thread);
+
+       /*
+        * As per the PCS, clear the length and stride bits for function
+        * entry.
+        */
+       hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK);
+
+       /*
+        * Disable VFP in the hwstate so that we can detect if it gets
+        * used.
+        */
+       hwstate->fpexc &= ~FPEXC_EN;
+       return 0;
+}
+
+/* Sanitise and restore the current VFP state from the provided structures. */
+int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
+                            struct user_vfp_exc __user *ufp_exc)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *hwstate = &thread->vfpstate.hard;
+       unsigned long fpexc;
+       int err = 0;
+
+       /*
+        * If VFP has been used, then disable it to avoid corrupting
+        * the new thread state.
+        */
+       if (hwstate->fpexc & FPEXC_EN)
+               vfp_flush_hwstate(thread);
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs,
+                               sizeof(hwstate->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __get_user_error(hwstate->fpscr, &ufp->fpscr, err);
+
+       /*
+        * Sanitise and restore the exception registers.
+        */
+       __get_user_error(fpexc, &ufp_exc->fpexc, err);
+
+       /* Ensure the VFP is enabled. */
+       fpexc |= FPEXC_EN;
+
+       /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+       fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+       hwstate->fpexc = fpexc;
+
+       __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err);
+       __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err);
+
+       return err ? -EFAULT : 0;
+}
+
 /*
  * VFP hardware can lose all context when a CPU goes offline.
  * As we will be running in SMP mode with CPU hotplug, we will save the
index e21507052066fbfe5aaec7185286376f2eaf4d02..9c717bf98ffe629f9f9c4061bd49b9114a9a99f5 100644 (file)
@@ -58,8 +58,8 @@ static void __init ar913x_wmac_setup(void)
 
 static int ar933x_wmac_reset(void)
 {
-       ath79_device_reset_clear(AR933X_RESET_WMAC);
        ath79_device_reset_set(AR933X_RESET_WMAC);
+       ath79_device_reset_clear(AR933X_RESET_WMAC);
 
        return 0;
 }
index a865c983c70affffc26ce5c00ab8742df7a442e8..5ad1a9c113c624136c6f2bfd584906c72f62d7a5 100644 (file)
@@ -45,7 +45,7 @@
 #define JZ4740_IRQ_LCD         JZ4740_IRQ(30)
 
 /* 2nd-level interrupts */
-#define JZ4740_IRQ_DMA(x)      (JZ4740_IRQ(32) + (X))
+#define JZ4740_IRQ_DMA(x)      (JZ4740_IRQ(32) + (x))
 
 #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
 #define JZ4740_IRQ_GPIO(x)     (JZ4740_IRQ(48) + (x))
index 73c0d45798dec6cf00fc99021fc4bc00664ccaad..9b02cfba7449ff7ceb2a1b56d4f8876efef38ca5 100644 (file)
@@ -37,12 +37,6 @@ extern void tlbmiss_handler_setup_pgd(unsigned long pgd);
                write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
        } while (0)
 
-
-static inline unsigned long get_current_pgd(void)
-{
-       return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL);
-}
-
 #else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
 
 /*
index 185ca00c4c84d53be39e2d7e98031f37b6a0d5bf..d5a338a1739c9027fcc3db50c30a59f15f6c2e62 100644 (file)
@@ -257,11 +257,8 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
-       spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&newset);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -286,11 +283,8 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
-       spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&newset);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -362,10 +356,7 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
 
        sigdelsetmask(&blocked, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = blocked;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&blocked);
 
        sig = restore_sigcontext(&regs, &frame->sf_sc);
        if (sig < 0)
@@ -401,10 +392,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
 
        sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
        if (sig < 0)
@@ -580,12 +568,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        if (ret)
                return ret;
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER))
-               sigaddset(&current->blocked, sig);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       block_sigmask(ka, sig);
 
        return ret;
 }
index 06b5da392e243ec652ba0a2e1dd25128ac005305..ac3b8d89aae51a4a75f14249ddc5a4f894046087 100644 (file)
@@ -290,11 +290,8 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
-       spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&newset);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -318,11 +315,8 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
                return -EFAULT;
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
-       spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&newset);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -488,10 +482,7 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
 
        sigdelsetmask(&blocked, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = blocked;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&blocked);
 
        sig = restore_sigcontext32(&regs, &frame->sf_sc);
        if (sig < 0)
@@ -529,10 +520,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
 
        sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
        if (sig < 0)
index ae29e894ab8d0f0cf099d28dbcc1f6cf0751e546..86eb4b04631c43924527231da81e3e23a5b01d0e 100644 (file)
@@ -93,11 +93,8 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        sigset_from_compat(&newset, &uset);
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
-       spin_lock_irq(&current->sighand->siglock);
        current->saved_sigmask = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&newset);
 
        current->state = TASK_INTERRUPTIBLE;
        schedule();
@@ -121,10 +118,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
                goto badframe;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
 
        sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
        if (sig < 0)
index 4f004596a6e7ad920674fb14780c668fe015b965..0b3393381a81261209d8b0fac80d20b6db7654c2 100644 (file)
@@ -104,7 +104,7 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
 
 static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp)
 {
-       if (!tty->count) {
+       if (tty->count == 1) {
                del_timer_sync(&pdc_console_timer);
                tty_port_tty_set(&tty_port, NULL);
        }
index e648af92ced18b20384102912fbaeafc903ddfb0..0e40843a1c6ed58273c1a0e2eb22841e9007e977 100644 (file)
 #include <linux/atomic.h>
 
 
-/* Define a way to iterate across irqs. */
-#define for_each_irq(i) \
-       for ((i) = 0; (i) < NR_IRQS; ++(i))
-
 extern atomic_t ppc_n_lost_interrupts;
 
 /* This number is used when no interrupt has been assigned */
index 5ec1b2354ca62301b83019db2f342bd92c085b80..43eb74fcedde2806da8dd0c5193f3df4c91433dc 100644 (file)
@@ -330,14 +330,10 @@ void migrate_irqs(void)
 
        alloc_cpumask_var(&mask, GFP_KERNEL);
 
-       for_each_irq(irq) {
+       for_each_irq_desc(irq, desc) {
                struct irq_data *data;
                struct irq_chip *chip;
 
-               desc = irq_to_desc(irq);
-               if (!desc)
-                       continue;
-
                data = irq_desc_get_irq_data(desc);
                if (irqd_is_per_cpu(data))
                        continue;
index c957b1202bdca6162479f395c063979b73613ba8..5df777794403d49a3820add9ba6409701b295da4 100644 (file)
 
 void machine_kexec_mask_interrupts(void) {
        unsigned int i;
+       struct irq_desc *desc;
 
-       for_each_irq(i) {
-               struct irq_desc *desc = irq_to_desc(i);
+       for_each_irq_desc(i, desc) {
                struct irq_chip *chip;
 
-               if (!desc)
-                       continue;
-
                chip = irq_desc_get_chip(desc);
                if (!chip)
                        continue;
index af1ab5e9a691e6b3c70b8d08415992f8c2205049..5c3cf2d04e41ccaa6e8b7aa94eb7ca27ba4baad9 100644 (file)
 /*
  * Assembly helpers from arch/powerpc/net/bpf_jit.S:
  */
-extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
+#define DECLARE_LOAD_FUNC(func)        \
+       extern u8 func[], func##_negative_offset[], func##_positive_offset[]
+
+DECLARE_LOAD_FUNC(sk_load_word);
+DECLARE_LOAD_FUNC(sk_load_half);
+DECLARE_LOAD_FUNC(sk_load_byte);
+DECLARE_LOAD_FUNC(sk_load_byte_msh);
 
 #define FUNCTION_DESCR_SIZE    24
 
index ff4506e85cce80bc2fdb7003078cec3f5c0d9962..55ba3855a97f58093ec06f343cde1df2dffbb17b 100644 (file)
  * then branch directly to slow_path_XXX if required.  (In fact, could
  * load a spare GPR with the address of slow_path_generic and pass size
  * as an argument, making the call site a mtlr, li and bllr.)
- *
- * Technically, the "is addr < 0" check is unnecessary & slowing down
- * the ABS path, as it's statically checked on generation.
  */
        .globl  sk_load_word
 sk_load_word:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_word_neg
+       .globl  sk_load_word_positive_offset
+sk_load_word_positive_offset:
        /* Are we accessing past headlen? */
        subi    r_scratch1, r_HL, 4
        cmpd    r_scratch1, r_addr
@@ -51,7 +50,9 @@ sk_load_word:
        .globl  sk_load_half
 sk_load_half:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_half_neg
+       .globl  sk_load_half_positive_offset
+sk_load_half_positive_offset:
        subi    r_scratch1, r_HL, 2
        cmpd    r_scratch1, r_addr
        blt     bpf_slow_path_half
@@ -61,7 +62,9 @@ sk_load_half:
        .globl  sk_load_byte
 sk_load_byte:
        cmpdi   r_addr, 0
-       blt     bpf_error
+       blt     bpf_slow_path_byte_neg
+       .globl  sk_load_byte_positive_offset
+sk_load_byte_positive_offset:
        cmpd    r_HL, r_addr
        ble     bpf_slow_path_byte
        lbzx    r_A, r_D, r_addr
@@ -69,22 +72,20 @@ sk_load_byte:
 
 /*
  * BPF_S_LDX_B_MSH: ldxb  4*([offset]&0xf)
- * r_addr is the offset value, already known positive
+ * r_addr is the offset value
  */
        .globl sk_load_byte_msh
 sk_load_byte_msh:
+       cmpdi   r_addr, 0
+       blt     bpf_slow_path_byte_msh_neg
+       .globl sk_load_byte_msh_positive_offset
+sk_load_byte_msh_positive_offset:
        cmpd    r_HL, r_addr
        ble     bpf_slow_path_byte_msh
        lbzx    r_X, r_D, r_addr
        rlwinm  r_X, r_X, 2, 32-4-2, 31-2
        blr
 
-bpf_error:
-       /* Entered with cr0 = lt */
-       li      r3, 0
-       /* Generated code will 'blt epilogue', returning 0. */
-       blr
-
 /* Call out to skb_copy_bits:
  * We'll need to back up our volatile regs first; we have
  * local variable space at r1+(BPF_PPC_STACK_BASIC).
@@ -136,3 +137,84 @@ bpf_slow_path_byte_msh:
        lbz     r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
        rlwinm  r_X, r_X, 2, 32-4-2, 31-2
        blr
+
+/* Call out to bpf_internal_load_pointer_neg_helper:
+ * We'll need to back up our volatile regs first; we have
+ * local variable space at r1+(BPF_PPC_STACK_BASIC).
+ * Allocate a new stack frame here to remain ABI-compliant in
+ * stashing LR.
+ */
+#define sk_negative_common(SIZE)                               \
+       mflr    r0;                                             \
+       std     r0, 16(r1);                                     \
+       /* R3 goes in parameter space of caller's frame */      \
+       std     r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       std     r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
+       std     r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       stdu    r1, -BPF_PPC_SLOWPATH_FRAME(r1);                \
+       /* R3 = r_skb, as passed */                             \
+       mr      r4, r_addr;                                     \
+       li      r5, SIZE;                                       \
+       bl      bpf_internal_load_pointer_neg_helper;           \
+       /* R3 != 0 on success */                                \
+       addi    r1, r1, BPF_PPC_SLOWPATH_FRAME;                 \
+       ld      r0, 16(r1);                                     \
+       ld      r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1);           \
+       ld      r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1);           \
+       mtlr    r0;                                             \
+       cmpldi  r3, 0;                                          \
+       beq     bpf_error_slow; /* cr0 = EQ */                  \
+       mr      r_addr, r3;                                     \
+       ld      r_skb, (BPF_PPC_STACKFRAME+48)(r1);             \
+       /* Great success! */
+
+bpf_slow_path_word_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_word_negative_offset
+sk_load_word_negative_offset:
+       sk_negative_common(4)
+       lwz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_half_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_half_negative_offset
+sk_load_half_negative_offset:
+       sk_negative_common(2)
+       lhz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_byte_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_byte_negative_offset
+sk_load_byte_negative_offset:
+       sk_negative_common(1)
+       lbz     r_A, 0(r_addr)
+       blr
+
+bpf_slow_path_byte_msh_neg:
+       lis     r_scratch1,-32  /* SKF_LL_OFF */
+       cmpd    r_addr, r_scratch1      /* addr < SKF_* */
+       blt     bpf_error       /* cr0 = LT */
+       .globl  sk_load_byte_msh_negative_offset
+sk_load_byte_msh_negative_offset:
+       sk_negative_common(1)
+       lbz     r_X, 0(r_addr)
+       rlwinm  r_X, r_X, 2, 32-4-2, 31-2
+       blr
+
+bpf_error_slow:
+       /* fabricate a cr0 = lt */
+       li      r_scratch1, -1
+       cmpdi   r_scratch1, 0
+bpf_error:
+       /* Entered with cr0 = lt */
+       li      r3, 0
+       /* Generated code will 'blt epilogue', returning 0. */
+       blr
index 73619d3aeb6ceebaa9d54e652b5025234f31660c..2dc8b14848455122918d13cf1d2985984f8a248b 100644 (file)
@@ -127,6 +127,9 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
        PPC_BLR();
 }
 
+#define CHOOSE_LOAD_FUNC(K, func) \
+       ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
+
 /* Assemble the body code between the prologue & epilogue. */
 static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                              struct codegen_context *ctx,
@@ -391,21 +394,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 
                        /*** Absolute loads from packet header/data ***/
                case BPF_S_LD_W_ABS:
-                       func = sk_load_word;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_word);
                        goto common_load;
                case BPF_S_LD_H_ABS:
-                       func = sk_load_half;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_half);
                        goto common_load;
                case BPF_S_LD_B_ABS:
-                       func = sk_load_byte;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_byte);
                common_load:
-                       /*
-                        * Load from [K].  Reference with the (negative)
-                        * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
-                        */
+                       /* Load from [K]. */
                        ctx->seen |= SEEN_DATAREF;
-                       if ((int)K < 0)
-                               return -ENOTSUPP;
                        PPC_LI64(r_scratch1, func);
                        PPC_MTLR(r_scratch1);
                        PPC_LI32(r_addr, K);
@@ -429,7 +427,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                common_load_ind:
                        /*
                         * Load from [X + K].  Negative offsets are tested for
-                        * in the helper functions, and result in a 'ret 0'.
+                        * in the helper functions.
                         */
                        ctx->seen |= SEEN_DATAREF | SEEN_XREG;
                        PPC_LI64(r_scratch1, func);
@@ -443,13 +441,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                        break;
 
                case BPF_S_LDX_B_MSH:
-                       /*
-                        * x86 version drops packet (RET 0) when K<0, whereas
-                        * interpreter does allow K<0 (__load_pointer, special
-                        * ancillary data).  common_load returns ENOTSUPP if K<0,
-                        * so we fall back to interpreter & filter works.
-                        */
-                       func = sk_load_byte_msh;
+                       func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh);
                        goto common_load;
                        break;
 
index d09f3e8e68670585230e52d33c28109d9ce6cf8e..85825b5401e51d936b81c99b8342b2f2a08cf6c1 100644 (file)
@@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
                pr_devel("axon_msi: woff %x roff %x msi %x\n",
                          write_offset, msic->read_offset, msi);
 
-               if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) {
+               if (msi < nr_irqs && irq_get_chip_data(msi) == msic) {
                        generic_handle_irq(msi);
                        msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
                } else {
@@ -276,9 +276,6 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
        if (rc)
                return rc;
 
-       /* We rely on being able to stash a virq in a u16 */
-       BUILD_BUG_ON(NR_IRQS > 65536);
-
        list_for_each_entry(entry, &dev->msi_list, list) {
                virq = irq_create_direct_mapping(msic->irq_domain);
                if (virq == NO_IRQ) {
@@ -392,7 +389,8 @@ static int axon_msi_probe(struct platform_device *device)
        }
        memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
-       msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
+       /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */
+       msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic);
        if (!msic->irq_domain) {
                printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
                       dn->full_name);
index f9a48af335cb8d17b52cb1ed34503175d0772fef..8c6dc42ecf65440f0a488e84483b43cdbfa4816f 100644 (file)
@@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void)
 {
        int     i;
 
-       for (i = 1; i < NR_IRQS; i++)
+       for (i = 1; i < nr_irqs; i++)
                beat_destruct_irq_plug(i);
 }
index 66ad93de1d5571f80b5431dd72b69b88b304f6fc..c4e630576ff283666f74c37ee985cf4f1b22b105 100644 (file)
@@ -57,9 +57,9 @@ static int max_real_irqs;
 
 static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
 
-#define NR_MASK_WORDS  ((NR_IRQS + 31) / 32)
-static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+/* The max irq number this driver deals with is 128; see max_irqs */
+static DECLARE_BITMAP(ppc_lost_interrupts, 128);
+static DECLARE_BITMAP(ppc_cached_irq_mask, 128);
 static int pmac_irq_cascade = -1;
 static struct irq_domain *pmac_pic_host;
 
index aadbe4f6d5373d03bef6fd8de146a02c43a04ceb..178a5f300bc973afeb8c4a21799992cbfbdc74e1 100644 (file)
@@ -30,9 +30,9 @@ config PPC_SPLPAR
          two or more partitions.
 
 config EEH
-       bool "PCI Extended Error Handling (EEH)" if EXPERT
+       bool
        depends on PPC_PSERIES && PCI
-       default y if !EXPERT
+       default y
 
 config PSERIES_MSI
        bool
index d3be961e2ae73d3fd9a3cebe0481a2f0f5e652ad..10386b676d8758b7f52bb8348f7cf321cc8db89a 100644 (file)
@@ -51,8 +51,7 @@
 static intctl_cpm2_t __iomem *cpm2_intctl;
 
 static struct irq_domain *cpm2_pic_host;
-#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
-static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */
 
 static const u_char irq_to_siureg[] = {
        1, 1, 1, 1, 1, 1, 1, 1,
index d5f5416be310b0fc5f78f7466cc5755b34a6f1cd..b724622c3a0b74ab5eddfa3b0cfc10dc6eab2c34 100644 (file)
 extern int cpm_get_irq(struct pt_regs *regs);
 
 static struct irq_domain *mpc8xx_pic_host;
-#define NR_MASK_WORDS   ((NR_IRQS + 31) / 32)
-static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
+static unsigned long mpc8xx_cached_irq_mask;
 static sysconf8xx_t __iomem *siu_reg;
 
-int cpm_get_irq(struct pt_regs *regs);
+static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d)
+{
+       return 0x80000000 >> irqd_to_hwirq(d);
+}
 
 static void mpc8xx_unmask_irq(struct irq_data *d)
 {
-       int     bit, word;
-       unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
-
-       bit = irq_nr & 0x1f;
-       word = irq_nr >> 5;
-
-       ppc_cached_irq_mask[word] |= (1 << (31-bit));
-       out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
+       mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
+       out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 }
 
 static void mpc8xx_mask_irq(struct irq_data *d)
 {
-       int     bit, word;
-       unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
-
-       bit = irq_nr & 0x1f;
-       word = irq_nr >> 5;
-
-       ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
-       out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
+       mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d);
+       out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 }
 
 static void mpc8xx_ack(struct irq_data *d)
 {
-       int     bit;
-       unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
-
-       bit = irq_nr & 0x1f;
-       out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
+       out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));
 }
 
 static void mpc8xx_end_irq(struct irq_data *d)
 {
-       int bit, word;
-       unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
-
-       bit = irq_nr & 0x1f;
-       word = irq_nr >> 5;
-
-       ppc_cached_irq_mask[word] |= (1 << (31-bit));
-       out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]);
+       mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
+       out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 }
 
 static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
-       if (flow_type & IRQ_TYPE_EDGE_FALLING) {
-               irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d);
+       /* only external IRQ senses are programmable */
+       if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {
                unsigned int siel = in_be32(&siu_reg->sc_siel);
-
-               /* only external IRQ senses are programmable */
-               if ((hw & 1) == 0) {
-                       siel |= (0x80000000 >> hw);
-                       out_be32(&siu_reg->sc_siel, siel);
-                       __irq_set_handler_locked(d->irq, handle_edge_irq);
-               }
+               siel |= mpc8xx_irqd_to_bit(d);
+               out_be32(&siu_reg->sc_siel, siel);
+               __irq_set_handler_locked(d->irq, handle_edge_irq);
        }
        return 0;
 }
@@ -132,6 +108,9 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
                IRQ_TYPE_EDGE_FALLING,
        };
 
+       if (intspec[0] > 0x1f)
+               return 0;
+
        *out_hwirq = intspec[0];
        if (intsize > 1 && intspec[1] < 4)
                *out_flags = map_pic_senses[intspec[1]];
index ea5e204e345093cedfc320d06f23a804d3c8589e..cd1d18db92c6afdc5e35c7980b4e038b8a6057a4 100644 (file)
@@ -188,6 +188,7 @@ void xics_migrate_irqs_away(void)
 {
        int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
        unsigned int irq, virq;
+       struct irq_desc *desc;
 
        /* If we used to be the default server, move to the new "boot_cpuid" */
        if (hw_cpu == xics_default_server)
@@ -202,8 +203,7 @@ void xics_migrate_irqs_away(void)
        /* Allow IPIs again... */
        icp_ops->set_priority(DEFAULT_PRIORITY);
 
-       for_each_irq(virq) {
-               struct irq_desc *desc;
+       for_each_irq_desc(virq, desc) {
                struct irq_chip *chip;
                long server;
                unsigned long flags;
@@ -212,9 +212,8 @@ void xics_migrate_irqs_away(void)
                /* We can't set affinity on ISA interrupts */
                if (virq < NUM_ISA_INTERRUPTS)
                        continue;
-               desc = irq_to_desc(virq);
                /* We only need to migrate enabled IRQS */
-               if (!desc || !desc->action)
+               if (!desc->action)
                        continue;
                if (desc->irq_data.domain != xics_host)
                        continue;
index 1d14cc6b79ad399d1ad293030c9f2271d9e5df1d..c9866b0b77d81d678e97ebbacd48ed5d5e659a77 100644 (file)
@@ -81,7 +81,7 @@ config X86
        select CLKEVT_I8253
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_IOMAP
-       select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC
+       select DCACHE_WORD_ACCESS
 
 config INSTRUCTION_DECODER
        def_bool (KPROBES || PERF_EVENTS)
index d3c0b027766656c69dfc82404b74de3849eaadaa..fb7117a4ade1e259c69d45b47d4ffc3b62196540 100644 (file)
@@ -403,13 +403,11 @@ static void print_absolute_symbols(void)
        for (i = 0; i < ehdr.e_shnum; i++) {
                struct section *sec = &secs[i];
                char *sym_strtab;
-               Elf32_Sym *sh_symtab;
                int j;
 
                if (sec->shdr.sh_type != SHT_SYMTAB) {
                        continue;
                }
-               sh_symtab = sec->symtab;
                sym_strtab = sec->link->strtab;
                for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {
                        Elf32_Sym *sym;
index 4824fb45560f7b6afe7bef4bf260f9f39f95a117..07b3a68d2d291ab4c8582a1cc5121c6443e208bb 100644 (file)
@@ -294,8 +294,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 
        /* OK, This is the point of no return */
        set_personality(PER_LINUX);
-       set_thread_flag(TIF_IA32);
-       current->mm->context.ia32_compat = 1;
+       set_personality_ia32(false);
 
        setup_new_exec(bprm);
 
index 6fe6767b7124aad25ac92ecd7dccd9a2fd2519ed..e58f03b206c3fb187b469032a1aba09b9d63ec05 100644 (file)
@@ -43,4 +43,37 @@ static inline unsigned long has_zero(unsigned long a)
        return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80);
 }
 
+/*
+ * Load an unaligned word from kernel space.
+ *
+ * In the (very unlikely) case of the word being a page-crosser
+ * and the next page not being mapped, take the exception and
+ * return zeroes in the non-existing part.
+ */
+static inline unsigned long load_unaligned_zeropad(const void *addr)
+{
+       unsigned long ret, dummy;
+
+       asm(
+               "1:\tmov %2,%0\n"
+               "2:\n"
+               ".section .fixup,\"ax\"\n"
+               "3:\t"
+               "lea %2,%1\n\t"
+               "and %3,%1\n\t"
+               "mov (%1),%0\n\t"
+               "leal %2,%%ecx\n\t"
+               "andl %4,%%ecx\n\t"
+               "shll $3,%%ecx\n\t"
+               "shr %%cl,%0\n\t"
+               "jmp 2b\n"
+               ".previous\n"
+               _ASM_EXTABLE(1b, 3b)
+               :"=&r" (ret),"=&c" (dummy)
+               :"m" (*(unsigned long *)addr),
+                "i" (-sizeof(unsigned long)),
+                "i" (sizeof(unsigned long)-1));
+       return ret;
+}
+
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 1c67ca100e4cc96ad708b0707474a4b3d9f9d683..146bb6218eec3daa3cdbe0472c04bcfac7500e8a 100644 (file)
@@ -580,6 +580,24 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                }
        }
 
+       /* re-enable TopologyExtensions if switched off by BIOS */
+       if ((c->x86 == 0x15) &&
+           (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) &&
+           !cpu_has(c, X86_FEATURE_TOPOEXT)) {
+               u64 val;
+
+               if (!rdmsrl_amd_safe(0xc0011005, &val)) {
+                       val |= 1ULL << 54;
+                       wrmsrl_amd_safe(0xc0011005, val);
+                       rdmsrl(0xc0011005, val);
+                       if (val & (1ULL << 54)) {
+                               set_cpu_cap(c, X86_FEATURE_TOPOEXT);
+                               printk(KERN_INFO FW_INFO "CPU: Re-enabling "
+                                 "disabled Topology Extensions Support\n");
+                       }
+               }
+       }
+
        cpu_detect_cache_sizes(c);
 
        /* Multi core CPU? */
index 66d377e334f7711d0d2c388afe485e52d932212d..646e3b5b4bb6af37766f0fa81625b7d7f876d4d2 100644 (file)
@@ -63,7 +63,7 @@ static struct gpio_led net5501_leds[] = {
                .name = "net5501:1",
                .gpio = 6,
                .default_trigger = "default-on",
-               .active_low = 1,
+               .active_low = 0,
        },
 };
 
index 7049a7d27c4f8bbd80991be1a633616474c0e2f4..330bb4d75852a02b928d3ac4bed0168458115bfc 100644 (file)
@@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
         * We know a device's inferred power state when all the resources
         * required for a given D-state are 'on'.
         */
-       for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) {
+       for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) {
                list = &device->power.states[i].resources;
                if (list->count < 1)
                        continue;
index 767e2dcb96169a9ef676b409b808ff823c280578..7417267e88fa9763617e0cc7e36fde6154ff4335 100644 (file)
@@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
        /*
         * Enumerate supported power management states
         */
-       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) {
+       for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
                struct acpi_device_power_state *ps = &device->power.states[i];
                char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' };
 
@@ -884,21 +884,18 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
                                acpi_bus_add_power_resource(ps->resources.handles[j]);
                }
 
-               /* The exist of _PR3 indicates D3Cold support */
-               if (i == ACPI_STATE_D3) {
-                       status = acpi_get_handle(device->handle, object_name, &handle);
-                       if (ACPI_SUCCESS(status))
-                               device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1;
-               }
-
                /* Evaluate "_PSx" to see if we can do explicit sets */
                object_name[2] = 'S';
                status = acpi_get_handle(device->handle, object_name, &handle);
                if (ACPI_SUCCESS(status))
                        ps->flags.explicit_set = 1;
 
-               /* State is valid if we have some power control */
-               if (ps->resources.count || ps->flags.explicit_set)
+               /*
+                * State is valid if there are means to put the device into it.
+                * D3hot is only valid if _PR3 present.
+                */
+               if (ps->resources.count ||
+                   (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
                        ps->flags.valid = 1;
 
                ps->power = -1; /* Unknown - driver assigned */
index 79a1e9dd56d98abfc68155d46df733acbb3ee8e0..ebaf67e4b2bc7382f4c2cc6e985df47c9de26c52 100644 (file)
@@ -394,6 +394,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          .driver_data = board_ahci_yes_fbs },                  /* 88se9128 */
        { PCI_DEVICE(0x1b4b, 0x9125),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9125 */
+       { PCI_DEVICE(0x1b4b, 0x917a),
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(0x1b4b, 0x91a3),
          .driver_data = board_ahci_yes_fbs },
 
index 0c86c77764bc7dec9f4bb6a2605aebac70abd18d..9e419e1c200629f9a556d519a0a553996727a554 100644 (file)
@@ -280,6 +280,7 @@ static struct dev_pm_ops ahci_pm_ops = {
 
 static const struct of_device_id ahci_of_match[] = {
        { .compatible = "calxeda,hb-ahci", },
+       { .compatible = "snps,spear-ahci", },
        {},
 };
 MODULE_DEVICE_TABLE(of, ahci_of_match);
index 28db50b57b918df812e5bb9f262243421dd97bea..23763a1ec570aa08149e23f65de1a7fb0087c860 100644 (file)
@@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
-atomic_t ata_print_id = ATOMIC_INIT(1);
+atomic_t ata_print_id = ATOMIC_INIT(0);
 
 struct ata_force_param {
        const char      *name;
index c61316e9d2f7fe0aa45cf542093be2fd811eec05..d1fbd59ead167b50544749e40f711ba09e138083 100644 (file)
@@ -3501,7 +3501,8 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg
        u64 now = get_jiffies_64();
        int *trials = void_arg;
 
-       if (ent->timestamp < now - min(now, interval))
+       if ((ent->eflags & ATA_EFLAG_OLD_ER) ||
+           (ent->timestamp < now - min(now, interval)))
                return -1;
 
        (*trials)++;
index 93dabdcd2cbe3712191f4ae05c0720a1bf42549d..22226350cd0c296b2849e59bc3f1b5e2927da9d2 100644 (file)
@@ -3399,7 +3399,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
                 */
                shost->max_host_blocked = 1;
 
-               rc = scsi_add_host(ap->scsi_host, &ap->tdev);
+               rc = scsi_add_host_with_dma(ap->scsi_host,
+                                               &ap->tdev, ap->host->dev);
                if (rc)
                        goto err_add;
        }
@@ -3838,18 +3839,25 @@ void ata_sas_port_stop(struct ata_port *ap)
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_stop);
 
-int ata_sas_async_port_init(struct ata_port *ap)
+/**
+ * ata_sas_async_probe - simply schedule probing and return
+ * @ap: Port to probe
+ *
+ * For batch scheduling of probe for sas attached ata devices, assumes
+ * the port has already been through ata_sas_port_init()
+ */
+void ata_sas_async_probe(struct ata_port *ap)
 {
-       int rc = ap->ops->port_start(ap);
-
-       if (!rc) {
-               ap->print_id = atomic_inc_return(&ata_print_id);
-               __ata_port_probe(ap);
-       }
+       __ata_port_probe(ap);
+}
+EXPORT_SYMBOL_GPL(ata_sas_async_probe);
 
-       return rc;
+int ata_sas_sync_probe(struct ata_port *ap)
+{
+       return ata_port_probe(ap);
 }
-EXPORT_SYMBOL_GPL(ata_sas_async_port_init);
+EXPORT_SYMBOL_GPL(ata_sas_sync_probe);
+
 
 /**
  *     ata_sas_port_init - Initialize a SATA device
@@ -3866,12 +3874,10 @@ int ata_sas_port_init(struct ata_port *ap)
 {
        int rc = ap->ops->port_start(ap);
 
-       if (!rc) {
-               ap->print_id = atomic_inc_return(&ata_print_id);
-               rc = ata_port_probe(ap);
-       }
-
-       return rc;
+       if (rc)
+               return rc;
+       ap->print_id = atomic_inc_return(&ata_print_id);
+       return 0;
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_init);
 
index fc2db2a89a6bb27b5d58722814a8e6f3f41957d8..3239517f4d902952654212f0a462d646fbd94608 100644 (file)
@@ -943,9 +943,9 @@ static int arasan_cf_resume(struct device *dev)
 
        return 0;
 }
+#endif
 
 static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume);
-#endif
 
 static struct platform_driver arasan_cf_driver = {
        .probe          = arasan_cf_probe,
@@ -953,9 +953,7 @@ static struct platform_driver arasan_cf_driver = {
        .driver         = {
                .name   = DRIVER_NAME,
                .owner  = THIS_MODULE,
-#ifdef CONFIG_PM
                .pm     = &arasan_cf_pm_ops,
-#endif
        },
 };
 
index ae9edca7b56dc474a140c8f0eb579f556dc8e308..57fd867553d7ab1dc5fcf1737e3c19e8d8181257 100644 (file)
@@ -75,6 +75,8 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x0CF3, 0x311D) },
        { USB_DEVICE(0x13d3, 0x3375) },
        { USB_DEVICE(0x04CA, 0x3005) },
+       { USB_DEVICE(0x13d3, 0x3362) },
+       { USB_DEVICE(0x0CF3, 0xE004) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -94,6 +96,8 @@ static struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 
        { }     /* Terminating entry */
 };
index 3311b812a0c68a37c9728c7bef3af2c050af587b..9217121362e10820da89b5678311b61ad6cac849 100644 (file)
@@ -101,12 +101,16 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE(0x0c10, 0x0000) },
 
        /* Broadcom BCM20702A0 */
+       { USB_DEVICE(0x0489, 0xe042) },
        { USB_DEVICE(0x0a5c, 0x21e3) },
        { USB_DEVICE(0x0a5c, 0x21e6) },
        { USB_DEVICE(0x0a5c, 0x21e8) },
        { USB_DEVICE(0x0a5c, 0x21f3) },
        { USB_DEVICE(0x413c, 0x8197) },
 
+       /* Foxconn - Hon Hai */
+       { USB_DEVICE(0x0489, 0xe033) },
+
        { }     /* Terminating entry */
 };
 
@@ -133,6 +137,8 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
index d25599f2a3f8bbb882ada61957239f030a06fa18..47408e802ab6effa670f8b3ba0637a3a75a14b36 100644 (file)
@@ -191,6 +191,190 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
        }
 }
 
+static bool
+validate_device_path(struct efi_variable *var, int match, u8 *buffer,
+                    unsigned long len)
+{
+       struct efi_generic_dev_path *node;
+       int offset = 0;
+
+       node = (struct efi_generic_dev_path *)buffer;
+
+       if (len < sizeof(*node))
+               return false;
+
+       while (offset <= len - sizeof(*node) &&
+              node->length >= sizeof(*node) &&
+               node->length <= len - offset) {
+               offset += node->length;
+
+               if ((node->type == EFI_DEV_END_PATH ||
+                    node->type == EFI_DEV_END_PATH2) &&
+                   node->sub_type == EFI_DEV_END_ENTIRE)
+                       return true;
+
+               node = (struct efi_generic_dev_path *)(buffer + offset);
+       }
+
+       /*
+        * If we're here then either node->length pointed past the end
+        * of the buffer or we reached the end of the buffer without
+        * finding a device path end node.
+        */
+       return false;
+}
+
+static bool
+validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
+                   unsigned long len)
+{
+       /* An array of 16-bit integers */
+       if ((len % 2) != 0)
+               return false;
+
+       return true;
+}
+
+static bool
+validate_load_option(struct efi_variable *var, int match, u8 *buffer,
+                    unsigned long len)
+{
+       u16 filepathlength;
+       int i, desclength = 0, namelen;
+
+       namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName));
+
+       /* Either "Boot" or "Driver" followed by four digits of hex */
+       for (i = match; i < match+4; i++) {
+               if (var->VariableName[i] > 127 ||
+                   hex_to_bin(var->VariableName[i] & 0xff) < 0)
+                       return true;
+       }
+
+       /* Reject it if there's 4 digits of hex and then further content */
+       if (namelen > match + 4)
+               return false;
+
+       /* A valid entry must be at least 8 bytes */
+       if (len < 8)
+               return false;
+
+       filepathlength = buffer[4] | buffer[5] << 8;
+
+       /*
+        * There's no stored length for the description, so it has to be
+        * found by hand
+        */
+       desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2;
+
+       /* Each boot entry must have a descriptor */
+       if (!desclength)
+               return false;
+
+       /*
+        * If the sum of the length of the description, the claimed filepath
+        * length and the original header are greater than the length of the
+        * variable, it's malformed
+        */
+       if ((desclength + filepathlength + 6) > len)
+               return false;
+
+       /*
+        * And, finally, check the filepath
+        */
+       return validate_device_path(var, match, buffer + desclength + 6,
+                                   filepathlength);
+}
+
+static bool
+validate_uint16(struct efi_variable *var, int match, u8 *buffer,
+               unsigned long len)
+{
+       /* A single 16-bit integer */
+       if (len != 2)
+               return false;
+
+       return true;
+}
+
+static bool
+validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
+                     unsigned long len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if (buffer[i] > 127)
+                       return false;
+
+               if (buffer[i] == 0)
+                       return true;
+       }
+
+       return false;
+}
+
+struct variable_validate {
+       char *name;
+       bool (*validate)(struct efi_variable *var, int match, u8 *data,
+                        unsigned long len);
+};
+
+static const struct variable_validate variable_validate[] = {
+       { "BootNext", validate_uint16 },
+       { "BootOrder", validate_boot_order },
+       { "DriverOrder", validate_boot_order },
+       { "Boot*", validate_load_option },
+       { "Driver*", validate_load_option },
+       { "ConIn", validate_device_path },
+       { "ConInDev", validate_device_path },
+       { "ConOut", validate_device_path },
+       { "ConOutDev", validate_device_path },
+       { "ErrOut", validate_device_path },
+       { "ErrOutDev", validate_device_path },
+       { "Timeout", validate_uint16 },
+       { "Lang", validate_ascii_string },
+       { "PlatformLang", validate_ascii_string },
+       { "", NULL },
+};
+
+static bool
+validate_var(struct efi_variable *var, u8 *data, unsigned long len)
+{
+       int i;
+       u16 *unicode_name = var->VariableName;
+
+       for (i = 0; variable_validate[i].validate != NULL; i++) {
+               const char *name = variable_validate[i].name;
+               int match;
+
+               for (match = 0; ; match++) {
+                       char c = name[match];
+                       u16 u = unicode_name[match];
+
+                       /* All special variables are plain ascii */
+                       if (u > 127)
+                               return true;
+
+                       /* Wildcard in the matching name means we've matched */
+                       if (c == '*')
+                               return variable_validate[i].validate(var,
+                                                            match, data, len);
+
+                       /* Case sensitive match */
+                       if (c != u)
+                               break;
+
+                       /* Reached the end of the string while matching */
+                       if (!c)
+                               return variable_validate[i].validate(var,
+                                                            match, data, len);
+               }
+       }
+
+       return true;
+}
+
 static efi_status_t
 get_var_data_locked(struct efivars *efivars, struct efi_variable *var)
 {
@@ -324,6 +508,12 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
                return -EINVAL;
        }
 
+       if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+           validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
+               printk(KERN_ERR "efivars: Malformed variable content\n");
+               return -EINVAL;
+       }
+
        spin_lock(&efivars->lock);
        status = efivars->ops->set_variable(new_var->VariableName,
                                            &new_var->VendorGuid,
@@ -626,6 +816,12 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
+       if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+           validate_var(new_var, new_var->Data, new_var->DataSize) == false) {
+               printk(KERN_ERR "efivars: Malformed variable content\n");
+               return -EINVAL;
+       }
+
        spin_lock(&efivars->lock);
 
        /*
index b505b70dba05b98a514e35aeba96044ca03e2843..e6162a1681f0931911bcf7a412c174666b23d50a 100644 (file)
@@ -1224,6 +1224,9 @@ static int i915_emon_status(struct seq_file *m, void *unused)
        unsigned long temp, chipset, gfx;
        int ret;
 
+       if (!IS_GEN5(dev))
+               return -ENODEV;
+
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
                return ret;
index 785f67f963efd5b53e0a0358e956888b103da5bd..ba60f3c8f911c187dc636e809af16bd64f51cc8d 100644 (file)
@@ -1701,6 +1701,9 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv)
        unsigned long diffms;
        u32 count;
 
+       if (dev_priv->info->gen != 5)
+               return;
+
        getrawmonotonic(&now);
        diff1 = timespec_sub(now, dev_priv->last_time2);
 
@@ -2121,12 +2124,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed,
                    (unsigned long) dev);
 
-       spin_lock(&mchdev_lock);
-       i915_mch_dev = dev_priv;
-       dev_priv->mchdev_lock = &mchdev_lock;
-       spin_unlock(&mchdev_lock);
+       if (IS_GEN5(dev)) {
+               spin_lock(&mchdev_lock);
+               i915_mch_dev = dev_priv;
+               dev_priv->mchdev_lock = &mchdev_lock;
+               spin_unlock(&mchdev_lock);
 
-       ips_ping_for_i915_load();
+               ips_ping_for_i915_load();
+       }
 
        return 0;
 
index 5908cd563400f486f7ae5a302f6a12f4c62da8af..1b1cf3b3ff515c8612cf69c42837824ab57bc7d9 100644 (file)
@@ -7072,9 +7072,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
        struct drm_device *dev = crtc->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       int pipe = intel_crtc->pipe;
-       int dpll_reg = DPLL(pipe);
-       int dpll = I915_READ(dpll_reg);
 
        if (HAS_PCH_SPLIT(dev))
                return;
@@ -7087,10 +7084,15 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
         * the manual case.
         */
        if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
+               int pipe = intel_crtc->pipe;
+               int dpll_reg = DPLL(pipe);
+               u32 dpll;
+
                DRM_DEBUG_DRIVER("downclocking LVDS\n");
 
                assert_panel_unlocked(dev_priv, pipe);
 
+               dpll = I915_READ(dpll_reg);
                dpll |= DISPLAY_RATE_SELECT_FPA1;
                I915_WRITE(dpll_reg, dpll);
                intel_wait_for_vblank(dev, pipe);
@@ -7098,7 +7100,6 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc)
                if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
                        DRM_DEBUG_DRIVER("failed to downclock LVDS!\n");
        }
-
 }
 
 /**
index cae3e5f17a49d8b767a371710935dcf89146121a..2d7f47b56b6ae7a7b1922a328ab971fe9d63077a 100644 (file)
@@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder,
 
        val &= ~VIDEO_DIP_SELECT_MASK;
 
-       I915_WRITE(VIDEO_DIP_CTL, val | port | flags);
+       I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags);
 
        for (i = 0; i < len; i += 4) {
                I915_WRITE(VIDEO_DIP_DATA, *data);
index 30e2c82101de0d8cb0c841d97f77db6acfc501aa..9c71183629c2a08fa1e9bddae13cd12dde26429f 100644 (file)
@@ -750,7 +750,7 @@ static const struct dmi_system_id intel_no_lvds[] = {
                .ident = "Hewlett-Packard t5745",
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_BOARD_NAME, "hp t5745"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"),
                },
        },
        {
@@ -758,7 +758,7 @@ static const struct dmi_system_id intel_no_lvds[] = {
                .ident = "Hewlett-Packard st5747",
                .matches = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_BOARD_NAME, "hp st5747"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"),
                },
        },
        {
index 7814a760c16439e8d6a0c74da474b4a978ce9793..284bd25d5d2127a3d44f9d8efae7449b77edcfbd 100644 (file)
@@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void)
        struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
        struct pci_dev *pdev = NULL;
        int has_dsm = 0;
-       int has_optimus;
+       int has_optimus = 0;
        int vga_count = 0;
        bool guid_valid;
        int retval;
index 80963d05b54aad27ebe0e1f3325fc9c923221daf..0be4a815e706cadd4e2bd4b0734f640c807f86ec 100644 (file)
@@ -6156,10 +6156,14 @@ dcb_fake_connectors(struct nvbios *bios)
 
        /* heuristic: if we ever get a non-zero connector field, assume
         * that all the indices are valid and we don't need fake them.
+        *
+        * and, as usual, a blacklist of boards with bad bios data..
         */
-       for (i = 0; i < dcbt->entries; i++) {
-               if (dcbt->entry[i].connector)
-                       return;
+       if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) {
+               for (i = 0; i < dcbt->entries; i++) {
+                       if (dcbt->entry[i].connector)
+                               return;
+               }
        }
 
        /* no useful connector info available, we need to make it up
index 59ea1c14eca0363b7f132abc4c86242e68b82e0f..c3de36384522f9668a99e6aa26fb2da39dc01dd8 100644 (file)
@@ -32,7 +32,9 @@ static bool
 hdmi_sor(struct drm_encoder *encoder)
 {
        struct drm_nouveau_private *dev_priv = encoder->dev->dev_private;
-       if (dev_priv->chipset < 0xa3)
+       if (dev_priv->chipset <  0xa3 ||
+           dev_priv->chipset == 0xaa ||
+           dev_priv->chipset == 0xac)
                return false;
        return true;
 }
index 550ad3fcf0afa691153f293f7e36f64e181105f7..9d79180069df2cdb93b6e8b7ea45cb0508fed38c 100644 (file)
@@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out)
        if (line < 10) {
                line = (line - 2) * 4;
                reg  = NV_PCRTC_GPIO_EXT;
-               mask = 0x00000003 << ((line - 2) * 4);
+               mask = 0x00000003;
                data = (dir << 1) | out;
        } else
        if (line < 14) {
index 5bf55038fd9238a4ec582f0d72b505dc3b804bd2..f704e942372e75b291cc505536a197c4c464a537 100644 (file)
@@ -54,6 +54,11 @@ nvc0_mfb_isr(struct drm_device *dev)
                        nvc0_mfb_subp_isr(dev, unit, subp);
                units &= ~(1 << unit);
        }
+
+       /* we do something horribly wrong and upset PMFB a lot, so mask off
+        * interrupts from it after the first one until it's fixed
+        */
+       nv_mask(dev, 0x000640, 0x02000000, 0x00000000);
 }
 
 static void
index ea7df16e2f84f267f0a129fac762333b96d54b56..5992502a3448dc692e426891751822f26aec3350 100644 (file)
@@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev)
                                rdev->wb.use_event = true;
                }
        }
-       /* always use writeback/events on NI */
-       if (ASIC_IS_DCE5(rdev)) {
+       /* always use writeback/events on NI, APUs */
+       if (rdev->family >= CHIP_PALM) {
                rdev->wb.enabled = true;
                rdev->wb.use_event = true;
        }
index 0d3141fbbc204bbb533dfce334bc0a741f0b7095..b9d512331ed49561331b638b78f29e5120288b39 100644 (file)
@@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444);
 MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
 
 #define BASE_SYSFS_ATTR_NO     2       /* Sysfs Base attr no for coretemp */
-#define NUM_REAL_CORES         16      /* Number of Real cores per cpu */
+#define NUM_REAL_CORES         32      /* Number of Real cores per cpu */
 #define CORETEMP_NAME_LENGTH   17      /* String Length of attrs */
 #define MAX_CORE_ATTRS         4       /* Maximum no of basic attrs */
 #define TOTAL_ATTRS            (MAX_CORE_ATTRS + 1)
@@ -709,6 +709,10 @@ static void __cpuinit put_core_offline(unsigned int cpu)
 
        indx = TO_ATTR_NO(cpu);
 
+       /* The core id is too big, just return */
+       if (indx > MAX_CORE_DATA - 1)
+               return;
+
        if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu)
                coretemp_remove_core(pdata, &pdev->dev, indx);
 
index f086131cb1c70372384d1af7be50414ce73b4356..c811289b61e21628f28d79b71f27651c39e3e024 100644 (file)
@@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap)
 {
        long ret;
        ret = wait_event_timeout(pch_event,
-                       (adap->pch_event_flag != 0), msecs_to_jiffies(50));
+                       (adap->pch_event_flag != 0), msecs_to_jiffies(1000));
 
        if (ret == 0) {
                pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
@@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit);
 
 MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.lapis-semi.com>");
+MODULE_AUTHOR("Tomoya MORINAGA. <tomoya.rohm@gmail.com>");
 module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));
 module_param(pch_clk, int, (S_IRUSR | S_IWUSR));
index 3d471d56bf15d1faf295f606c31f19d90f384e79..76b8af44f63492884d1b2b9ebc70ec58da9b9eba 100644 (file)
@@ -227,6 +227,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
                return -EINVAL;
 
        init_completion(&i2c->cmd_complete);
+       i2c->cmd_err = 0;
 
        flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
 
@@ -252,6 +253,9 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
 
        if (i2c->cmd_err == -ENXIO)
                mxs_i2c_reset(i2c);
+       else
+               writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
+                               i2c->regs + MXS_I2C_QUEUECTRL_CLR);
 
        dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
 
@@ -299,8 +303,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
                    MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))
                /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
                i2c->cmd_err = -EIO;
-       else
-               i2c->cmd_err = 0;
 
        is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
                MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
@@ -384,8 +386,6 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
        if (ret)
                return -EBUSY;
 
-       writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
-                       i2c->regs + MXS_I2C_QUEUECTRL_CLR);
        writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
 
        platform_set_drvdata(pdev, NULL);
index 04be9f82e14bda8518c4d9562c680731e42c23b3..eb8ad538c79ffb97616e43f135b5d9ff991cce96 100644 (file)
@@ -546,8 +546,7 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev,
 {
        struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
 
-       /* FIXME: shouldn't this be clk_disable? */
-       clk_enable(alg_data->clk);
+       clk_disable(alg_data->clk);
 
        return 0;
 }
index e978635e60f04189e6478ccb112a0df4a2596ed3..55e5ea62ccee3b69148c13ce337a1ff8531bc467 100644 (file)
@@ -516,6 +516,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
                return 0;
 
+       /*
+        * NACK interrupt is generated before the I2C controller generates the
+        * STOP condition on the bus. So wait for 2 clock periods before resetting
+        * the controller so that STOP condition has been delivered properly.
+        */
+       if (i2c_dev->msg_err == I2C_ERR_NO_ACK)
+               udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate));
+
        tegra_i2c_init(i2c_dev);
        if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
                if (msg->flags & I2C_M_IGNORE_NAK)
index 8081a0a5d602c0b9f04557b5323882c4bcf89694..a4b14a41cbf43a2d788989d7bfc3e71294ffc94e 100644 (file)
@@ -274,7 +274,8 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
        static unsigned char param = 0xc8;
        struct synaptics_data *priv = psmouse->private;
 
-       if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
+       if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
+             SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)))
                return 0;
 
        if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
index 97e73e555d112c8762b7934bd9892d39f5c6e4ce..17e2b472e16dccba1a94202f616f260e8f656b6c 100644 (file)
@@ -1727,8 +1727,7 @@ int bitmap_create(struct mddev *mddev)
        bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize)
                              - BITMAP_BLOCK_SHIFT);
 
-       /* now that chunksize and chunkshift are set, we can use these macros */
-       chunks = (blocks + bitmap->chunkshift - 1) >>
+       chunks = (blocks + (1 << bitmap->chunkshift) - 1) >>
                        bitmap->chunkshift;
        pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
 
index 55ca5aec84e4cb06280f335a6b260ac2ae23dd5c..b44b0aba2d47b970f9b76f39763192995e5984fb 100644 (file)
@@ -101,9 +101,6 @@ typedef __u16 bitmap_counter_t;
 
 #define BITMAP_BLOCK_SHIFT 9
 
-/* how many blocks per chunk? (this is variable) */
-#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT)
-
 #endif
 
 /*
index c8aae6640e64cc00bdc4079f3326ac8ef512df34..7e96bb2297244f7946537a5da5f78226e6a4db40 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
+#include <plat/cpu.h>
 #include <plat/usb.h>
 #include <linux/pm_runtime.h>
 
index 062ac333fde60be0732572f39e0a7a46335da499..ceeab8e852ef6a2cf86b682bb17bd0f17ab5ade8 100644 (file)
@@ -879,8 +879,13 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
                if (sblk->status & SD_STATUS_LINK_CHG)
                        work_exists = 1;
        }
-       /* check for RX/TX work to do */
-       if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
+
+       /* check for TX work to do */
+       if (sblk->idx[0].tx_consumer != tnapi->tx_cons)
+               work_exists = 1;
+
+       /* check for RX work to do */
+       if (tnapi->rx_rcb_prod_idx &&
            *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
                work_exists = 1;
 
@@ -6124,6 +6129,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
                        return work_done;
        }
 
+       if (!tnapi->rx_rcb_prod_idx)
+               return work_done;
+
        /* run RX thread, within the bounds set by NAPI.
         * All RX "locking" is done by ensuring outside
         * code synchronizes with tg3->napi.poll()
@@ -7567,6 +7575,12 @@ static int tg3_alloc_consistent(struct tg3 *tp)
                 */
                switch (i) {
                default:
+                       if (tg3_flag(tp, ENABLE_RSS)) {
+                               tnapi->rx_rcb_prod_idx = NULL;
+                               break;
+                       }
+                       /* Fall through */
+               case 1:
                        tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
                        break;
                case 2:
index 63bfdd10bd6d857b33cb52f4702919f1843fd094..abb6ce7c1b7ed2a67ee6b064377698df2efcb9c6 100644 (file)
@@ -1149,6 +1149,48 @@ release_tpsram:
        return ret;
 }
 
+/**
+ * t3_synchronize_rx - wait for current Rx processing on a port to complete
+ * @adap: the adapter
+ * @p: the port
+ *
+ * Ensures that current Rx processing on any of the queues associated with
+ * the given port completes before returning.  We do this by acquiring and
+ * releasing the locks of the response queues associated with the port.
+ */
+static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
+{
+       int i;
+
+       for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
+               struct sge_rspq *q = &adap->sge.qs[i].rspq;
+
+               spin_lock_irq(&q->lock);
+               spin_unlock_irq(&q->lock);
+       }
+}
+
+static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
+{
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+
+       if (adapter->params.rev > 0) {
+               t3_set_vlan_accel(adapter, 1 << pi->port_id,
+                                 features & NETIF_F_HW_VLAN_RX);
+       } else {
+               /* single control for all ports */
+               unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
+
+               for_each_port(adapter, i)
+                       have_vlans |=
+                               adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
+
+               t3_set_vlan_accel(adapter, 1, have_vlans);
+       }
+       t3_synchronize_rx(adapter, pi);
+}
+
 /**
  *     cxgb_up - enable the adapter
  *     @adapter: adapter being enabled
@@ -1161,7 +1203,7 @@ release_tpsram:
  */
 static int cxgb_up(struct adapter *adap)
 {
-       int err;
+       int i, err;
 
        if (!(adap->flags & FULL_INIT_DONE)) {
                err = t3_check_fw_version(adap);
@@ -1198,6 +1240,9 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto out;
 
+               for_each_port(adap, i)
+                       cxgb_vlan_mode(adap->port[i], adap->port[i]->features);
+
                setup_rss(adap);
                if (!(adap->flags & NAPI_INIT))
                        init_napi(adap);
@@ -2508,48 +2553,6 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p)
        return 0;
 }
 
-/**
- * t3_synchronize_rx - wait for current Rx processing on a port to complete
- * @adap: the adapter
- * @p: the port
- *
- * Ensures that current Rx processing on any of the queues associated with
- * the given port completes before returning.  We do this by acquiring and
- * releasing the locks of the response queues associated with the port.
- */
-static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
-{
-       int i;
-
-       for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
-               struct sge_rspq *q = &adap->sge.qs[i].rspq;
-
-               spin_lock_irq(&q->lock);
-               spin_unlock_irq(&q->lock);
-       }
-}
-
-static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features)
-{
-       struct port_info *pi = netdev_priv(dev);
-       struct adapter *adapter = pi->adapter;
-
-       if (adapter->params.rev > 0) {
-               t3_set_vlan_accel(adapter, 1 << pi->port_id,
-                                 features & NETIF_F_HW_VLAN_RX);
-       } else {
-               /* single control for all ports */
-               unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX;
-
-               for_each_port(adapter, i)
-                       have_vlans |=
-                               adapter->port[i]->features & NETIF_F_HW_VLAN_RX;
-
-               t3_set_vlan_accel(adapter, 1, have_vlans);
-       }
-       t3_synchronize_rx(adapter, pi);
-}
-
 static netdev_features_t cxgb_fix_features(struct net_device *dev,
        netdev_features_t features)
 {
@@ -3353,9 +3356,6 @@ static int __devinit init_one(struct pci_dev *pdev,
        err = sysfs_create_group(&adapter->port[0]->dev.kobj,
                                 &cxgb3_attr_group);
 
-       for_each_port(adapter, i)
-               cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features);
-
        print_port_info(adapter, ai);
        return 0;
 
index b2dc2c81a147f66581d1302f1b8eb1ee92346288..2e09edb9cdf84b3d1cc49d7dad5167a2ce3be75a 100644 (file)
@@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int phy_addr;
        struct netdev_private *np = netdev_priv(dev);
-       struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
-
-       struct netdev_desc *desc;
-       int i;
+       struct mii_ioctl_data *miidata = if_mii(rq);
 
        phy_addr = np->phy_addr;
        switch (cmd) {
-       case SIOCDEVPRIVATE:
-               break;
-
-       case SIOCDEVPRIVATE + 1:
-               miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
+       case SIOCGMIIPHY:
+               miidata->phy_id = phy_addr;
                break;
-       case SIOCDEVPRIVATE + 2:
-               mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
+       case SIOCGMIIREG:
+               miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
                break;
-       case SIOCDEVPRIVATE + 3:
-               break;
-       case SIOCDEVPRIVATE + 4:
-               break;
-       case SIOCDEVPRIVATE + 5:
-               netif_stop_queue (dev);
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
                break;
-       case SIOCDEVPRIVATE + 6:
-               netif_wake_queue (dev);
-               break;
-       case SIOCDEVPRIVATE + 7:
-               printk
-                   ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
-                    netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
-                    np->old_rx);
-               break;
-       case SIOCDEVPRIVATE + 8:
-               printk("TX ring:\n");
-               for (i = 0; i < TX_RING_SIZE; i++) {
-                       desc = &np->tx_ring[i];
-                       printk
-                           ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
-                            i,
-                            (u32) (np->tx_ring_dma + i * sizeof (*desc)),
-                            (u32)le64_to_cpu(desc->next_desc),
-                            (u32)le64_to_cpu(desc->status),
-                            (u32)(le64_to_cpu(desc->fraginfo) >> 32),
-                            (u32)le64_to_cpu(desc->fraginfo));
-                       printk ("\n");
-               }
-               printk ("\n");
-               break;
-
        default:
                return -EOPNOTSUPP;
        }
index ba0adcafa55ad71c2dd63098796ce003a4cb6701..30c2da3de548f92ce0ebe794dc9c894af284c010 100644 (file)
@@ -365,13 +365,6 @@ struct ioctl_data {
        char *data;
 };
 
-struct mii_data {
-       __u16 reserved;
-       __u16 reg_num;
-       __u16 in_value;
-       __u16 out_value;
-};
-
 /* The Rx and Tx buffer descriptors. */
 struct netdev_desc {
        __le64 next_desc;
index 17a46e76123f92a510b39d2ebaa29eeecf8e97ab..9ac14f8048512a66aef3a8fc2bba992d198393ef 100644 (file)
@@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = {
        .maxGroupAddrInHash = 4,
        .maxIndAddrInHash = 4,
        .prel = 7,
-       .maxFrameLength = 1518,
+       .maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */
        .minFrameLength = 64,
-       .maxD1Length = 1520,
-       .maxD2Length = 1520,
+       .maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */
+       .maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */
        .vlantype = 0x8100,
        .ecamptr = ((uint32_t) NULL),
        .eventRegMask = UCCE_OTHER,
index 2e395a2566b8d6221747f79828cbdfb70f72947c..f71b3e7b12defe7c92489ca967fbfe72819ab382 100644 (file)
@@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics {
 
 /* Driver definitions */
 #define TX_BD_RING_LEN                          0x10
-#define RX_BD_RING_LEN                          0x10
+#define RX_BD_RING_LEN                          0x20
 
 #define TX_RING_MOD_MASK(size)                  (size-1)
 #define RX_RING_MOD_MASK(size)                  (size-1)
index 3516e17a399d3137ccf0e2eea06318c0171aeba4..c9069a28832b0bfa39e4b118c7399a744ac0c8a2 100644 (file)
@@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void)
 
                                arr[i].adh = adapter->handle;
                                arr[i].port_id = port->logical_port_id;
-                               arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
-                                                 EHEA_BCMC_MULTICAST |
+                               arr[i].reg_type = EHEA_BCMC_MULTICAST |
                                                  EHEA_BCMC_UNTAGGED;
+                               if (mc_entry->macaddr == 0)
+                                       arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
                                arr[i++].macaddr = mc_entry->macaddr;
 
                                arr[i].adh = adapter->handle;
                                arr[i].port_id = port->logical_port_id;
-                               arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
-                                                 EHEA_BCMC_MULTICAST |
+                               arr[i].reg_type = EHEA_BCMC_MULTICAST |
                                                  EHEA_BCMC_VLANID_ALL;
+                               if (mc_entry->macaddr == 0)
+                                       arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL;
                                arr[i++].macaddr = mc_entry->macaddr;
                                num_registrations -= 2;
                        }
@@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
        u64 hret;
        u8 reg_type;
 
-       reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
-                | EHEA_BCMC_UNTAGGED;
+       reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED;
+       if (mc_mac_addr == 0)
+               reg_type |= EHEA_BCMC_SCOPE_ALL;
 
        hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
                                     port->logical_port_id,
@@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
        if (hret)
                goto out;
 
-       reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST
-                | EHEA_BCMC_VLANID_ALL;
+       reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL;
+       if (mc_mac_addr == 0)
+               reg_type |= EHEA_BCMC_SCOPE_ALL;
 
        hret = ehea_h_reg_dereg_bcmc(port->adapter->handle,
                                     port->logical_port_id,
@@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
                                netdev_err(dev,
                                           "failed enabling IFF_ALLMULTI\n");
                }
-       } else
+       } else {
                if (!enable) {
                        /* Disable ALLMULTI */
                        hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC);
@@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable)
                                netdev_err(dev,
                                           "failed disabling IFF_ALLMULTI\n");
                }
+       }
 }
 
 static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
@@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
        struct netdev_hw_addr *ha;
        int ret;
 
-       if (port->promisc) {
-               ehea_promiscuous(dev, 1);
-               return;
-       }
-       ehea_promiscuous(dev, 0);
+       ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC));
 
        if (dev->flags & IFF_ALLMULTI) {
                ehea_allmulti(dev, 1);
@@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev)
                return 0;
 
        ehea_drop_multicast_list(dev);
+       ehea_allmulti(dev, 0);
        ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 
        ehea_free_interrupts(dev);
@@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
        struct ehea_adapter *adapter;
        const u64 *adapter_handle;
        int ret;
+       int i;
 
        if (!dev || !dev->dev.of_node) {
                pr_err("Invalid ibmebus device probed\n");
@@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
        tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet,
                     (unsigned long)adapter);
 
-       ret = ibmebus_request_irq(adapter->neq->attr.ist1,
-                                 ehea_interrupt_neq, IRQF_DISABLED,
-                                 "ehea_neq", adapter);
-       if (ret) {
-               dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
-               goto out_kill_eq;
-       }
-
        ret = ehea_create_device_sysfs(dev);
        if (ret)
-               goto out_free_irq;
+               goto out_kill_eq;
 
        ret = ehea_setup_ports(adapter);
        if (ret) {
@@ -3332,15 +3327,28 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
                goto out_rem_dev_sysfs;
        }
 
+       ret = ibmebus_request_irq(adapter->neq->attr.ist1,
+                                 ehea_interrupt_neq, IRQF_DISABLED,
+                                 "ehea_neq", adapter);
+       if (ret) {
+               dev_err(&dev->dev, "requesting NEQ IRQ failed\n");
+               goto out_shutdown_ports;
+       }
+
+
        ret = 0;
        goto out;
 
+out_shutdown_ports:
+       for (i = 0; i < EHEA_MAX_PORTS; i++)
+               if (adapter->port[i]) {
+                       ehea_shutdown_single_port(adapter->port[i]);
+                       adapter->port[i] = NULL;
+               }
+
 out_rem_dev_sysfs:
        ehea_remove_device_sysfs(dev);
 
-out_free_irq:
-       ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
-
 out_kill_eq:
        ehea_destroy_eq(adapter->neq);
 
index 52c456ec4d6cf811567f82f80477b4e32910ee9a..8364815c32ff63f04fd7942d2f240b980e156f2f 100644 (file)
@@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num,
                            void *cb_addr);
 
 #define H_REGBCMC_PN            EHEA_BMASK_IBM(48, 63)
-#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(61, 63)
+#define H_REGBCMC_REGTYPE       EHEA_BMASK_IBM(60, 63)
 #define H_REGBCMC_MACADDR       EHEA_BMASK_IBM(16, 63)
 #define H_REGBCMC_VLANID        EHEA_BMASK_IBM(52, 63)
 
index 19ab2154802c171fcadaeceb82419681b51c90f2..9520a6ac1f3069592be3cc199c9d5e2ee99215b3 100644 (file)
@@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
        /* fire an unusual interrupt on the test handler */
        ew32(ICS, E1000_ICS_RXSEQ);
        e1e_flush();
-       msleep(50);
+       msleep(100);
 
        e1000_irq_disable(adapter);
 
index ff796e42c3ebbf1b146a28b677e7bb885e1f6bf6..16adeb9418a8903e5ccbb7503e513f1918978930 100644 (file)
@@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
 /*
  * Interrupt Throttle Rate (interrupts/sec)
  *
- * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
+ * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative
  */
 E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define DEFAULT_ITR 3
@@ -344,53 +344,60 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 
                if (num_InterruptThrottleRate > bd) {
                        adapter->itr = InterruptThrottleRate[bd];
-                       switch (adapter->itr) {
-                       case 0:
-                               e_info("%s turned off\n", opt.name);
-                               break;
-                       case 1:
-                               e_info("%s set to dynamic mode\n", opt.name);
-                               adapter->itr_setting = adapter->itr;
-                               adapter->itr = 20000;
-                               break;
-                       case 3:
-                               e_info("%s set to dynamic conservative mode\n",
-                                       opt.name);
-                               adapter->itr_setting = adapter->itr;
-                               adapter->itr = 20000;
-                               break;
-                       case 4:
-                               e_info("%s set to simplified (2000-8000 ints) "
-                                      "mode\n", opt.name);
-                               adapter->itr_setting = 4;
-                               break;
-                       default:
-                               /*
-                                * Save the setting, because the dynamic bits
-                                * change itr.
-                                */
-                               if (e1000_validate_option(&adapter->itr, &opt,
-                                                         adapter) &&
-                                   (adapter->itr == 3)) {
-                                       /*
-                                        * In case of invalid user value,
-                                        * default to conservative mode.
-                                        */
-                                       adapter->itr_setting = adapter->itr;
-                                       adapter->itr = 20000;
-                               } else {
-                                       /*
-                                        * Clear the lower two bits because
-                                        * they are used as control.
-                                        */
-                                       adapter->itr_setting =
-                                               adapter->itr & ~3;
-                               }
-                               break;
-                       }
+
+                       /*
+                        * Make sure a message is printed for non-special
+                        * values.  And in case of an invalid option, display
+                        * warning, use default and got through itr/itr_setting
+                        * adjustment logic below
+                        */
+                       if ((adapter->itr > 4) &&
+                           e1000_validate_option(&adapter->itr, &opt, adapter))
+                               adapter->itr = opt.def;
                } else {
-                       adapter->itr_setting = opt.def;
+                       /*
+                        * If no option specified, use default value and go
+                        * through the logic below to adjust itr/itr_setting
+                        */
+                       adapter->itr = opt.def;
+
+                       /*
+                        * Make sure a message is printed for non-special
+                        * default values
+                        */
+                       if (adapter->itr > 40)
+                               e_info("%s set to default %d\n", opt.name,
+                                      adapter->itr);
+               }
+
+               adapter->itr_setting = adapter->itr;
+               switch (adapter->itr) {
+               case 0:
+                       e_info("%s turned off\n", opt.name);
+                       break;
+               case 1:
+                       e_info("%s set to dynamic mode\n", opt.name);
+                       adapter->itr = 20000;
+                       break;
+               case 3:
+                       e_info("%s set to dynamic conservative mode\n",
+                              opt.name);
                        adapter->itr = 20000;
+                       break;
+               case 4:
+                       e_info("%s set to simplified (2000-8000 ints) mode\n",
+                              opt.name);
+                       break;
+               default:
+                       /*
+                        * Save the setting, because the dynamic bits
+                        * change itr.
+                        *
+                        * Clear the lower two bits because
+                        * they are used as control.
+                        */
+                       adapter->itr_setting &= ~3;
+                       break;
                }
        }
        { /* Interrupt Mode */
index d61ca2a732f0ef341ccaf036ce0dcb6efb468013..8ec74b07f940a234ccc1691e9dcd2b67691e0f4b 100644 (file)
@@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev,
                        netdev->addr_len);
        }
 
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
+       if (!is_valid_ether_addr(netdev->dev_addr)) {
                dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
                        netdev->dev_addr);
                err = -EIO;
                goto err_hw_init;
        }
 
-       memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
        setup_timer(&adapter->watchdog_timer, &igbvf_watchdog,
                    (unsigned long) adapter);
index 77ea4b7165351707192dde0ea3c678950502a71b..bc07933d67dadec6845fb667fbc9cc1edf025c3e 100644 (file)
@@ -437,6 +437,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
         */
        if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
            (fctl & FC_FC_END_SEQ)) {
+               skb_linearize(skb);
                crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
                crc->fcoe_eof = FC_EOF_T;
        }
index a7f3cd872caf9c21e3725d1dab0ab64228a88f72..88f6b2e9b72db2ddb22b917fcb4e4ae4c9b99514 100644 (file)
@@ -4873,10 +4873,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
        }
 
        ixgbe_clear_interrupt_scheme(adapter);
-#ifdef CONFIG_DCB
-       kfree(adapter->ixgbe_ieee_pfc);
-       kfree(adapter->ixgbe_ieee_ets);
-#endif
 
 #ifdef CONFIG_PM
        retval = pci_save_state(pdev);
@@ -7224,6 +7220,11 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 
        ixgbe_release_hw_control(adapter);
 
+#ifdef CONFIG_DCB
+       kfree(adapter->ixgbe_ieee_pfc);
+       kfree(adapter->ixgbe_ieee_ets);
+
+#endif
        iounmap(adapter->hw.hw_addr);
        pci_release_selected_regions(pdev, pci_select_bars(pdev,
                                     IORESOURCE_MEM));
index c9b504e2dfc3bfdc4707dd0f3db240b1f365ec0c..487a6c8bd4eccf6c21dc394c317e408cabe9aa12 100644 (file)
@@ -2494,8 +2494,13 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2,
                skb_copy_from_linear_data(re->skb, skb->data, length);
                skb->ip_summed = re->skb->ip_summed;
                skb->csum = re->skb->csum;
+               skb->rxhash = re->skb->rxhash;
+               skb->vlan_tci = re->skb->vlan_tci;
+
                pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr,
                                               length, PCI_DMA_FROMDEVICE);
+               re->skb->vlan_tci = 0;
+               re->skb->rxhash = 0;
                re->skb->ip_summed = CHECKSUM_NONE;
                skb_put(skb, length);
        }
@@ -2580,9 +2585,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        struct sk_buff *skb = NULL;
        u16 count = (status & GMR_FS_LEN) >> 16;
 
-       if (status & GMR_FS_VLAN)
-               count -= VLAN_HLEN;     /* Account for vlan tag */
-
        netif_printk(sky2, rx_status, KERN_DEBUG, dev,
                     "rx slot %u status 0x%x len %d\n",
                     sky2->rx_next, status, length);
@@ -2590,6 +2592,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
        sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
        prefetch(sky2->rx_ring + sky2->rx_next);
 
+       if (vlan_tx_tag_present(re->skb))
+               count -= VLAN_HLEN;     /* Account for vlan tag */
+
        /* This chip has hardware problems that generates bogus status.
         * So do only marginal checking and expect higher level protocols
         * to handle crap frames.
@@ -2647,11 +2652,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 }
 
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
-                              u32 status, struct sk_buff *skb)
+                              struct sk_buff *skb)
 {
-       if (status & GMR_FS_VLAN)
-               __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag));
-
        if (skb->ip_summed == CHECKSUM_NONE)
                netif_receive_skb(skb);
        else
@@ -2705,6 +2707,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status)
        }
 }
 
+static void sky2_rx_tag(struct sky2_port *sky2, u16 length)
+{
+       struct sk_buff *skb;
+
+       skb = sky2->rx_ring[sky2->rx_next].skb;
+       __vlan_hwaccel_put_tag(skb, be16_to_cpu(length));
+}
+
 static void sky2_rx_hash(struct sky2_port *sky2, u32 status)
 {
        struct sk_buff *skb;
@@ -2763,8 +2773,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
                        }
 
                        skb->protocol = eth_type_trans(skb, dev);
-
-                       sky2_skb_rx(sky2, status, skb);
+                       sky2_skb_rx(sky2, skb);
 
                        /* Stop after net poll weight */
                        if (++work_done >= to_do)
@@ -2772,11 +2781,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
                        break;
 
                case OP_RXVLAN:
-                       sky2->rx_tag = length;
+                       sky2_rx_tag(sky2, length);
                        break;
 
                case OP_RXCHKSVLAN:
-                       sky2->rx_tag = length;
+                       sky2_rx_tag(sky2, length);
                        /* fall through */
                case OP_RXCHKS:
                        if (likely(dev->features & NETIF_F_RXCSUM))
index ff6f58bf822aa378ffa0975140733fa40bf41f5d..3c896ce80b71ec1facc6f04f666ab80711c5dfe3 100644 (file)
@@ -2241,7 +2241,6 @@ struct sky2_port {
        u16                  rx_pending;
        u16                  rx_data_size;
        u16                  rx_nfrags;
-       u16                  rx_tag;
 
        struct {
                unsigned long last;
index 558409ff40582fa9f5cd1ae91248f9d214c51d3e..4ba969096717a7ce59e55eaa97f40bdc974ef8b2 100644 (file)
@@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        netif_device_detach(dev);
 
        /* Switch off chip, remember WOL setting */
-       gp->asleep_wol = gp->wake_on_lan;
+       gp->asleep_wol = !!gp->wake_on_lan;
        gem_do_stop(dev, gp->asleep_wol);
 
        /* Unlock the network stack */
index 174a3348f6762d67a661801342ea6cbe95a7810f..08aff1a2087c920207f544bf540917b481c35344 100644 (file)
@@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
 
 static int match_first_device(struct device *dev, void *data)
 {
-       return 1;
+       return !strncmp(dev_name(dev), "davinci_mdio", 12);
 }
 
 /**
index 817ad3bc49574670ab6040b6805528c5b863c852..efd36691ce5450881dd14114037071708df4e7c1 100644 (file)
@@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag)
        unsigned long addr;
 
        addr = tag->buffer[9].address;
-       addr |= (tag->buffer[8].address << 16) << 16;
+       addr |= ((unsigned long) tag->buffer[8].address << 16) << 16;
        return (struct sk_buff *) addr;
 }
 
index 5ee032cafadea0f8405f4d8f66cb356eec236262..42b5151aa78ae8523b27493394ba87e9900338a5 100644 (file)
@@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        u32 packet_len;
        u32 padbytes = 0xffff0000;
 
-       padlen = ((skb->len + 4) % 512) ? 0 : 4;
+       padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4;
 
        if ((!skb_cloned(skb)) &&
            ((headroom + tailroom) >= (4 + padlen))) {
@@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        cpu_to_le32s(&packet_len);
        skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len));
 
-       if ((skb->len % 512) == 0) {
+       if (padlen) {
                cpu_to_le32s(&padbytes);
                memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes));
                skb_put(skb, sizeof(padbytes));
index a2349483cd2ab1d36ac9eb5a192215ad23d93ba2..00103a8c5e04d69e17408d32f139c9bee93aa03c 100644 (file)
@@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
 
        if (unlikely(ret < 0))
                netdev_warn(dev->net,
-                       "Failed to read register index 0x%08x", index);
+                       "Failed to read reg index 0x%08x: %d", index, ret);
 
        le32_to_cpus(buf);
        *data = *buf;
@@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
 
        if (unlikely(ret < 0))
                netdev_warn(dev->net,
-                       "Failed to write register index 0x%08x", index);
+                       "Failed to write reg index 0x%08x: %d", index, ret);
 
        kfree(buf);
 
@@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
        idx &= dev->mii.reg_num_mask;
        addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
                | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
-               | MII_ACCESS_READ;
+               | MII_ACCESS_READ | MII_ACCESS_BUSY;
        ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
        check_warn_goto_done(ret, "Error writing MII_ACCESS");
 
@@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
        idx &= dev->mii.reg_num_mask;
        addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
                | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
-               | MII_ACCESS_WRITE;
+               | MII_ACCESS_WRITE | MII_ACCESS_BUSY;
        ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
        check_warn_goto_done(ret, "Error writing MII_ACCESS");
 
@@ -508,9 +508,10 @@ static int smsc75xx_link_reset(struct usbnet *dev)
        u16 lcladv, rmtadv;
        int ret;
 
-       /* clear interrupt status */
+       /* read and write to clear phy interrupt status */
        ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
        check_warn_return(ret, "Error reading PHY_INT_SRC");
+       smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff);
 
        ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
        check_warn_return(ret, "Error writing INT_STS");
@@ -643,7 +644,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev)
 
 static int smsc75xx_phy_initialize(struct usbnet *dev)
 {
-       int bmcr, timeout = 0;
+       int bmcr, ret, timeout = 0;
 
        /* Initialize MII structure */
        dev->mii.dev = dev->net;
@@ -651,6 +652,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
        dev->mii.mdio_write = smsc75xx_mdio_write;
        dev->mii.phy_id_mask = 0x1f;
        dev->mii.reg_num_mask = 0x1f;
+       dev->mii.supports_gmii = 1;
        dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
 
        /* reset phy and wait for reset to complete */
@@ -661,7 +663,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
                bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
                check_warn_return(bmcr, "Error reading MII_BMCR");
                timeout++;
-       } while ((bmcr & MII_BMCR) && (timeout < 100));
+       } while ((bmcr & BMCR_RESET) && (timeout < 100));
 
        if (timeout >= 100) {
                netdev_warn(dev->net, "timeout on PHY Reset");
@@ -671,10 +673,13 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
        smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
                ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
                ADVERTISE_PAUSE_ASYM);
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000,
+               ADVERTISE_1000FULL);
 
-       /* read to clear */
-       smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
-       check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+       /* read and write to clear phy interrupt status */
+       ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+       check_warn_return(ret, "Error reading PHY_INT_SRC");
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff);
 
        smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
                PHY_INT_MASK_DEFAULT);
@@ -946,6 +951,14 @@ static int smsc75xx_reset(struct usbnet *dev)
        ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
        check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
 
+       /* allow mac to detect speed and duplex from phy */
+       ret = smsc75xx_read_reg(dev, MAC_CR, &buf);
+       check_warn_return(ret, "Failed to read MAC_CR: %d", ret);
+
+       buf |= (MAC_CR_ADD | MAC_CR_ASD);
+       ret = smsc75xx_write_reg(dev, MAC_CR, buf);
+       check_warn_return(ret, "Failed to write MAC_CR: %d", ret);
+
        ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
        check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
 
@@ -1212,7 +1225,7 @@ static const struct driver_info smsc75xx_info = {
        .rx_fixup       = smsc75xx_rx_fixup,
        .tx_fixup       = smsc75xx_tx_fixup,
        .status         = smsc75xx_status,
-       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
 };
 
 static const struct usb_device_id products[] = {
index 5f19f84d3494696254793320cda6a1f132a0e6e1..94ae66999f592a4a8a1c45fdc24505050271d086 100644 (file)
@@ -1017,6 +1017,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
        dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
        dev->net->flags |= IFF_MULTICAST;
        dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
        return 0;
 }
 
@@ -1191,7 +1192,7 @@ static const struct driver_info smsc95xx_info = {
        .rx_fixup       = smsc95xx_rx_fixup,
        .tx_fixup       = smsc95xx_tx_fixup,
        .status         = smsc95xx_status,
-       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
 };
 
 static const struct usb_device_id products[] = {
index b7b3f5b0d40654c3c50b18ae56c969c03382c71c..2d927fb4adf4ea6805b2aeb02d06c8cb5108f496 100644 (file)
@@ -210,6 +210,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
                } else {
                        usb_fill_int_urb(dev->interrupt, dev->udev, pipe,
                                buf, maxp, intr_complete, dev, period);
+                       dev->interrupt->transfer_flags |= URB_FREE_BUFFER;
                        dev_dbg(&intf->dev,
                                "status ep%din, %d bytes period %d\n",
                                usb_pipeendpoint(pipe), maxp, period);
@@ -1443,7 +1444,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        status = register_netdev (net);
        if (status)
-               goto out3;
+               goto out4;
        netif_info(dev, probe, dev->net,
                   "register '%s' at usb-%s-%s, %s, %pM\n",
                   udev->dev.driver->name,
@@ -1461,6 +1462,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
        return 0;
 
+out4:
+       usb_free_urb(dev->interrupt);
 out3:
        if (info->unbind)
                info->unbind (dev, udev);
index 8c50d9d19d786e5f0e28ef78bed157455cfcf705..aec33cc207fdbba47e67a6aa28a52ac19f4bfede 100644 (file)
@@ -220,6 +220,7 @@ static int ath_ahb_remove(struct platform_device *pdev)
        }
 
        ath5k_deinit_ah(ah);
+       iounmap(ah->iobase);
        platform_set_drvdata(pdev, NULL);
        ieee80211_free_hw(hw);
 
index d7d8e91991408a7a5c18fea055a4f17f1a0741cf..aba088005b2274a43873f277993113ec59cca45e 100644 (file)
@@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
        ar5008_hw_set_channel_regs(ah, chan);
        ar5008_hw_init_chain_masks(ah);
        ath9k_olc_init(ah);
-       ath9k_hw_apply_txpower(ah, chan);
+       ath9k_hw_apply_txpower(ah, chan, false);
 
        /* Write analog registers */
        if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
index 59647a3ceb7f98ea568d34e16248c80471290f78..3d400e8d653544ffd16bc3db8710f075598dce2f 100644 (file)
@@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
 
        if (val) {
                ah->paprd_table_write_done = true;
-               ath9k_hw_apply_txpower(ah, chan);
+               ath9k_hw_apply_txpower(ah, chan, false);
        }
 
        REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
index bc992b237ae5a47a42f53db6b59a5cd5a59cf94d..deb6cfb2959a7344886bb7e10799feb3a5106de0 100644 (file)
@@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
        ar9003_hw_override_ini(ah);
        ar9003_hw_set_channel_regs(ah, chan);
        ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
-       ath9k_hw_apply_txpower(ah, chan);
+       ath9k_hw_apply_txpower(ah, chan, false);
 
        if (AR_SREV_9462(ah)) {
                if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
index f272236d8053d58201b973b6397b11362a112bb1..b34e8b2990b127a359b88991af37687307fbcf60 100644 (file)
@@ -824,6 +824,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
                        regulatory->max_power_level = ratesArray[i];
        }
 
+       ath9k_hw_update_regulatory_maxpower(ah);
+
        if (test)
                return;
 
index 6c69e4e8b1cb7ca85b6710aecb8fbe3cba1e10c9..fa84e37bf091546035c6638130892a5bbe559c66 100644 (file)
@@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
                return false;
        }
        ath9k_hw_set_clockrate(ah);
-       ath9k_hw_apply_txpower(ah, chan);
+       ath9k_hw_apply_txpower(ah, chan, false);
        ath9k_hw_rfbus_done(ah);
 
        if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
@@ -2652,7 +2652,8 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
        return ah->eep_ops->get_eeprom(ah, gain_param);
 }
 
-void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
+void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
+                           bool test)
 {
        struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
        struct ieee80211_channel *channel;
@@ -2673,7 +2674,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
 
        ah->eep_ops->set_txpower(ah, chan,
                                 ath9k_regd_get_ctl(reg, chan),
-                                ant_reduction, new_pwr, false);
+                                ant_reduction, new_pwr, test);
 }
 
 void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
@@ -2686,7 +2687,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
        if (test)
                channel->max_power = MAX_RATE_POWER / 2;
 
-       ath9k_hw_apply_txpower(ah, chan);
+       ath9k_hw_apply_txpower(ah, chan, test);
 
        if (test)
                channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
index aa1680a0c7fdbeccd4ba36a7be8733b5a1a0ed4c..e88f182ff45c1b36b88cd8eda93af3d335b0a0e2 100644 (file)
@@ -985,7 +985,8 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
 /* PHY */
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
                                   u32 *coef_mantissa, u32 *coef_exponent);
-void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan,
+                           bool test);
 
 /*
  * Code Specific to AR5008, AR9001 or AR9002,
index c79e6638c88d599e6efdcd048c9145b869d6211a..e4d6dc2e37d12479ab2bdef3560d8f700e9e0d13 100644 (file)
@@ -4827,8 +4827,14 @@ static int b43_op_start(struct ieee80211_hw *hw)
  out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
-       /* reload configuration */
-       b43_op_config(hw, ~0);
+       /*
+        * Configuration may have been overwritten during initialization.
+        * Reload the configuration, but only if initialization was
+        * successful. Reloading the configuration after a failed init
+        * may hang the system.
+        */
+       if (!err)
+               b43_op_config(hw, ~0);
 
        return err;
 }
index 4688904908ec464b3b9895504e8566eb61d6c5e7..758c115b556ebbcde32b669ccd563c12969b01e7 100644 (file)
@@ -108,9 +108,15 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
                        sdio_release_host(sdfunc);
                }
        } else if (regaddr == SDIO_CCCR_ABORT) {
+               sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
+                                GFP_KERNEL);
+               if (!sdfunc)
+                       return -ENOMEM;
+               sdfunc->num = 0;
                sdio_claim_host(sdfunc);
                sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
                sdio_release_host(sdfunc);
+               kfree(sdfunc);
        } else if (regaddr < 0xF0) {
                brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
                err_ret = -EPERM;
@@ -486,7 +492,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
                        kfree(bus_if);
                        return -ENOMEM;
                }
-               sdiodev->func[0] = func->card->sdio_func[0];
+               sdiodev->func[0] = func;
                sdiodev->func[1] = func;
                sdiodev->bus_if = bus_if;
                bus_if->bus_priv.sdio = sdiodev;
index 2bf5dda292919868a90a9dad3722f0a4991f7024..eb3829b03cd37cf587edab5e4e12aa839e6635e0 100644 (file)
@@ -574,6 +574,8 @@ struct brcmf_sdio {
 
        struct task_struct *dpc_tsk;
        struct completion dpc_wait;
+       struct list_head dpc_tsklst;
+       spinlock_t dpc_tl_lock;
 
        struct semaphore sdsem;
 
@@ -2594,29 +2596,58 @@ clkwait:
        return resched;
 }
 
+static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
+{
+       struct list_head *new_hd;
+       unsigned long flags;
+
+       if (in_interrupt())
+               new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
+       else
+               new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
+       if (new_hd == NULL)
+               return;
+
+       spin_lock_irqsave(&bus->dpc_tl_lock, flags);
+       list_add_tail(new_hd, &bus->dpc_tsklst);
+       spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
+}
+
 static int brcmf_sdbrcm_dpc_thread(void *data)
 {
        struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
+       struct list_head *cur_hd, *tmp_hd;
+       unsigned long flags;
 
        allow_signal(SIGTERM);
        /* Run until signal received */
        while (1) {
                if (kthread_should_stop())
                        break;
-               if (!wait_for_completion_interruptible(&bus->dpc_wait)) {
-                       /* Call bus dpc unless it indicated down
-                       (then clean stop) */
-                       if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) {
-                               if (brcmf_sdbrcm_dpc(bus))
-                                       complete(&bus->dpc_wait);
-                       } else {
+
+               if (list_empty(&bus->dpc_tsklst))
+                       if (wait_for_completion_interruptible(&bus->dpc_wait))
+                               break;
+
+               spin_lock_irqsave(&bus->dpc_tl_lock, flags);
+               list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
+                       spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
+
+                       if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
                                /* after stopping the bus, exit thread */
                                brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
                                bus->dpc_tsk = NULL;
                                break;
                        }
-               } else
-                       break;
+
+                       if (brcmf_sdbrcm_dpc(bus))
+                               brcmf_sdbrcm_adddpctsk(bus);
+
+                       spin_lock_irqsave(&bus->dpc_tl_lock, flags);
+                       list_del(cur_hd);
+                       kfree(cur_hd);
+               }
+               spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
        }
        return 0;
 }
@@ -2669,8 +2700,10 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
        /* Schedule DPC if needed to send queued packet(s) */
        if (!bus->dpc_sched) {
                bus->dpc_sched = true;
-               if (bus->dpc_tsk)
+               if (bus->dpc_tsk) {
+                       brcmf_sdbrcm_adddpctsk(bus);
                        complete(&bus->dpc_wait);
+               }
        }
 
        return ret;
@@ -3514,8 +3547,10 @@ void brcmf_sdbrcm_isr(void *arg)
                brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
 
        bus->dpc_sched = true;
-       if (bus->dpc_tsk)
+       if (bus->dpc_tsk) {
+               brcmf_sdbrcm_adddpctsk(bus);
                complete(&bus->dpc_wait);
+       }
 }
 
 static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
@@ -3559,8 +3594,10 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
                                bus->ipend = true;
 
                                bus->dpc_sched = true;
-                               if (bus->dpc_tsk)
+                               if (bus->dpc_tsk) {
+                                       brcmf_sdbrcm_adddpctsk(bus);
                                        complete(&bus->dpc_wait);
+                               }
                        }
                }
 
@@ -3897,6 +3934,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
        }
        /* Initialize DPC thread */
        init_completion(&bus->dpc_wait);
+       INIT_LIST_HEAD(&bus->dpc_tsklst);
+       spin_lock_init(&bus->dpc_tl_lock);
        bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
                                   bus, "brcmf_dpc");
        if (IS_ERR(bus->dpc_tsk)) {
index 7083db75b00cdb7213f2f4038de37ad84f881f10..b4d92792c5028de56ef78b5bbdd1ef3c9c0c317b 100644 (file)
@@ -847,8 +847,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
         */
        if (!(txs->status & TX_STATUS_AMPDU)
            && (txs->status & TX_STATUS_INTERMEDIATE)) {
-               wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
-                         __func__);
+               BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n");
                return false;
        }
 
index 2b022571a8595a5dd41c89bdd515d0f1fd0dc70b..1779db3aa2b00c3a11bbcad080dadf8f0da0984c 100644 (file)
@@ -2191,6 +2191,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 {
        int rc = 0;
        unsigned long flags;
+       unsigned long now, end;
 
        spin_lock_irqsave(&priv->lock, flags);
        if (priv->status & STATUS_HCMD_ACTIVE) {
@@ -2232,10 +2233,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       now = jiffies;
+       end = now + HOST_COMPLETE_TIMEOUT;
+again:
        rc = wait_event_interruptible_timeout(priv->wait_command_queue,
                                              !(priv->
                                                status & STATUS_HCMD_ACTIVE),
-                                             HOST_COMPLETE_TIMEOUT);
+                                             end - now);
+       if (rc < 0) {
+               now = jiffies;
+               if (time_before(now, end))
+                       goto again;
+               rc = 0;
+       }
+
        if (rc == 0) {
                spin_lock_irqsave(&priv->lock, flags);
                if (priv->status & STATUS_HCMD_ACTIVE) {
index 5b0d888f746bbc27ea492d6351458476aabdbd4d..8d80e233bc7a73aec74b267edb61bd191bdf5eb2 100644 (file)
@@ -46,8 +46,8 @@
 #include "iwl-prph.h"
 
 /* Highest firmware API version supported */
-#define IWL1000_UCODE_API_MAX 6
-#define IWL100_UCODE_API_MAX 6
+#define IWL1000_UCODE_API_MAX 5
+#define IWL100_UCODE_API_MAX 5
 
 /* Oldest version we won't warn about */
 #define IWL1000_UCODE_API_OK 5
@@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = {
        IWL_DEVICE_100,
 };
 
-MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK));
index 5635b9e2c69e6b4e27e9337d88f97095ac71029d..ea108622e0bd0adf4a961be817378df86664e1c1 100644 (file)
 #define IWL135_UCODE_API_MAX 6
 
 /* Oldest version we won't warn about */
-#define IWL2030_UCODE_API_OK 5
-#define IWL2000_UCODE_API_OK 5
-#define IWL105_UCODE_API_OK 5
-#define IWL135_UCODE_API_OK 5
+#define IWL2030_UCODE_API_OK 6
+#define IWL2000_UCODE_API_OK 6
+#define IWL105_UCODE_API_OK 6
+#define IWL135_UCODE_API_OK 6
 
 /* Lowest firmware API version supported */
 #define IWL2030_UCODE_API_MIN 5
@@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = {
        .ht_params = &iwl2000_ht_params,
 };
 
-MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK));
+MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK));
+MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK));
index a805e97b89af85cb1a066c156cc1899dde7034c7..de0920c74cdd2369b7a528de29536163aba01f50 100644 (file)
 #define IWL5000_UCODE_API_MAX 5
 #define IWL5150_UCODE_API_MAX 2
 
+/* Oldest version we won't warn about */
+#define IWL5000_UCODE_API_OK 5
+#define IWL5150_UCODE_API_OK 2
+
 /* Lowest firmware API version supported */
 #define IWL5000_UCODE_API_MIN 1
 #define IWL5150_UCODE_API_MIN 1
@@ -326,6 +330,7 @@ static const struct iwl_ht_params iwl5000_ht_params = {
 #define IWL_DEVICE_5000                                                \
        .fw_name_pre = IWL5000_FW_PRE,                          \
        .ucode_api_max = IWL5000_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL5000_UCODE_API_OK,                   \
        .ucode_api_min = IWL5000_UCODE_API_MIN,                 \
        .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
        .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
@@ -371,6 +376,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {
        .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
        .fw_name_pre = IWL5000_FW_PRE,
        .ucode_api_max = IWL5000_UCODE_API_MAX,
+       .ucode_api_ok = IWL5000_UCODE_API_OK,
        .ucode_api_min = IWL5000_UCODE_API_MIN,
        .max_inst_size = IWLAGN_RTC_INST_SIZE,
        .max_data_size = IWLAGN_RTC_DATA_SIZE,
@@ -386,6 +392,7 @@ const struct iwl_cfg iwl5350_agn_cfg = {
 #define IWL_DEVICE_5150                                                \
        .fw_name_pre = IWL5150_FW_PRE,                          \
        .ucode_api_max = IWL5150_UCODE_API_MAX,                 \
+       .ucode_api_ok = IWL5150_UCODE_API_OK,                   \
        .ucode_api_min = IWL5150_UCODE_API_MIN,                 \
        .max_inst_size = IWLAGN_RTC_INST_SIZE,                  \
        .max_data_size = IWLAGN_RTC_DATA_SIZE,                  \
@@ -409,5 +416,5 @@ const struct iwl_cfg iwl5150_abg_cfg = {
        IWL_DEVICE_5150,
 };
 
-MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK));
+MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK));
index 64060cd738b5d90b069a8289eba923842365a023..f0c91505a7f775ac0e8cb819dca0be1bfc983094 100644 (file)
@@ -53,6 +53,8 @@
 /* Oldest version we won't warn about */
 #define IWL6000_UCODE_API_OK 4
 #define IWL6000G2_UCODE_API_OK 5
+#define IWL6050_UCODE_API_OK 5
+#define IWL6000G2B_UCODE_API_OK 6
 
 /* Lowest firmware API version supported */
 #define IWL6000_UCODE_API_MIN 4
@@ -388,7 +390,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
 #define IWL_DEVICE_6030                                                \
        .fw_name_pre = IWL6030_FW_PRE,                          \
        .ucode_api_max = IWL6000G2_UCODE_API_MAX,               \
-       .ucode_api_ok = IWL6000G2_UCODE_API_OK,                 \
+       .ucode_api_ok = IWL6000G2B_UCODE_API_OK,                \
        .ucode_api_min = IWL6000G2_UCODE_API_MIN,               \
        .max_inst_size = IWL60_RTC_INST_SIZE,                   \
        .max_data_size = IWL60_RTC_DATA_SIZE,                   \
@@ -557,6 +559,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK));
-MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK));
+MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK));
+MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK));
index f1226dbf789d796c7c366fe102f410eb32537f7f..2a9a16f901c3f940dd87f4865bcab51a53a7a48d 100644 (file)
@@ -863,7 +863,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
 
 void iwlagn_prepare_restart(struct iwl_priv *priv)
 {
-       struct iwl_rxon_context *ctx;
        bool bt_full_concurrent;
        u8 bt_ci_compliance;
        u8 bt_load;
@@ -872,8 +871,6 @@ void iwlagn_prepare_restart(struct iwl_priv *priv)
 
        lockdep_assert_held(&priv->mutex);
 
-       for_each_context(priv, ctx)
-               ctx->vif = NULL;
        priv->is_open = 0;
 
        /*
index 90208094b8ebdb472fcc9078ca605c83f37d9197..74bce97a860004b3fc8e921df2afef593379ebfb 100644 (file)
  * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04
  * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte
  * aligned (address bits 0-7 must be 0).
+ * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers
+ * for them are in different places.
  *
  * Bit fields in each pointer register:
  *  27-0: TFD CB physical base address [35:8], must be 256-byte aligned
  */
-#define FH_MEM_CBBC_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0x9D0)
-#define FH_MEM_CBBC_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xA10)
-
-/* Find TFD CB base pointer for given queue (range 0-15). */
-#define FH_MEM_CBBC_QUEUE(x)  (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
+#define FH_MEM_CBBC_0_15_LOWER_BOUND           (FH_MEM_LOWER_BOUND + 0x9D0)
+#define FH_MEM_CBBC_0_15_UPPER_BOUND           (FH_MEM_LOWER_BOUND + 0xA10)
+#define FH_MEM_CBBC_16_19_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0xBF0)
+#define FH_MEM_CBBC_16_19_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xC00)
+#define FH_MEM_CBBC_20_31_LOWER_BOUND          (FH_MEM_LOWER_BOUND + 0xB20)
+#define FH_MEM_CBBC_20_31_UPPER_BOUND          (FH_MEM_LOWER_BOUND + 0xB80)
+
+/* Find TFD CB base pointer for given queue */
+static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
+{
+       if (chnl < 16)
+               return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl;
+       if (chnl < 20)
+               return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16);
+       WARN_ON_ONCE(chnl >= 32);
+       return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20);
+}
 
 
 /**
index b6805f8e9a014553cca088e4992aa09c421897f7..c24a7134a6f9a3729d81350ea699246744805884 100644 (file)
@@ -1244,6 +1244,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
        struct iwl_rxon_context *tmp, *ctx = NULL;
        int err;
        enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif);
+       bool reset = false;
 
        IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
                           viftype, vif->addr);
@@ -1265,6 +1266,13 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
                        tmp->interface_modes | tmp->exclusive_interface_modes;
 
                if (tmp->vif) {
+                       /* On reset we need to add the same interface again */
+                       if (tmp->vif == vif) {
+                               reset = true;
+                               ctx = tmp;
+                               break;
+                       }
+
                        /* check if this busy context is exclusive */
                        if (tmp->exclusive_interface_modes &
                                                BIT(tmp->vif->type)) {
@@ -1291,7 +1299,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
        ctx->vif = vif;
 
        err = iwl_setup_interface(priv, ctx);
-       if (!err)
+       if (!err || reset)
                goto out;
 
        ctx->vif = NULL;
index 75dc20bd965b4d80715881b5657d099c75274854..3b1069290fa9a9cf646a2f04325d6c1862b70a7a 100644 (file)
 #define SCD_AIT                        (SCD_BASE + 0x0c)
 #define SCD_TXFACT             (SCD_BASE + 0x10)
 #define SCD_ACTIVE             (SCD_BASE + 0x14)
-#define SCD_QUEUE_WRPTR(x)     (SCD_BASE + 0x18 + (x) * 4)
-#define SCD_QUEUE_RDPTR(x)     (SCD_BASE + 0x68 + (x) * 4)
 #define SCD_QUEUECHAIN_SEL     (SCD_BASE + 0xe8)
 #define SCD_AGGR_SEL           (SCD_BASE + 0x248)
 #define SCD_INTERRUPT_MASK     (SCD_BASE + 0x108)
-#define SCD_QUEUE_STATUS_BITS(x)       (SCD_BASE + 0x10c + (x) * 4)
+
+static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
+{
+       if (chnl < 20)
+               return SCD_BASE + 0x18 + chnl * 4;
+       WARN_ON_ONCE(chnl >= 32);
+       return SCD_BASE + 0x284 + (chnl - 20) * 4;
+}
+
+static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
+{
+       if (chnl < 20)
+               return SCD_BASE + 0x68 + chnl * 4;
+       WARN_ON_ONCE(chnl >= 32);
+       return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
+}
+
+static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
+{
+       if (chnl < 20)
+               return SCD_BASE + 0x10c + chnl * 4;
+       WARN_ON_ONCE(chnl >= 32);
+       return SCD_BASE + 0x384 + (chnl - 20) * 4;
+}
 
 /*********************** END TX SCHEDULER *************************************/
 
index 288b035a3579b06b2dfba78c17369416b4ab2a44..cc15fdb36060b3dd387124e6288ac288c901cc78 100644 (file)
@@ -1941,6 +1941,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
                rtl_deinit_deferred_work(hw);
                rtlpriv->intf_ops->adapter_stop(hw);
        }
+       rtlpriv->cfg->ops->disable_interrupt(hw);
 
        /*deinit rfkill */
        rtl_deinit_rfkill(hw);
index 41302c7b1ad0089480a495a26dac4da2552eecf2..d1afb8e3b2ef0a3673b5ff9ef60f98379180bfa3 100644 (file)
@@ -479,6 +479,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw)
        cancel_work_sync(&wl->irq_work);
        cancel_work_sync(&wl->tx_work);
        cancel_work_sync(&wl->filter_work);
+       cancel_delayed_work_sync(&wl->elp_work);
 
        mutex_lock(&wl->mutex);
 
index f78694295c397f053f4a00115ff2aff22d8a4379..1b851f650e074eb795ffb708dd25b3c94a2cb9e1 100644 (file)
@@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func)
 
        if (wl->irq)
                free_irq(wl->irq, wl);
-       kfree(wl_sdio);
        wl1251_free_hw(wl);
+       kfree(wl_sdio);
 
        sdio_claim_host(func);
        sdio_release_irq(func);
index 0f150f271c2aa4040c8fcb9905783c99cb8b4e7a..1929c0c63b75b0773d45e39a845f663678b55d67 100644 (file)
@@ -200,7 +200,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
                return PCI_D1;
        case ACPI_STATE_D2:
                return PCI_D2;
-       case ACPI_STATE_D3:
+       case ACPI_STATE_D3_HOT:
                return PCI_D3hot;
        case ACPI_STATE_D3_COLD:
                return PCI_D3cold;
@@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                [PCI_D0] = ACPI_STATE_D0,
                [PCI_D1] = ACPI_STATE_D1,
                [PCI_D2] = ACPI_STATE_D2,
-               [PCI_D3hot] = ACPI_STATE_D3,
+               [PCI_D3hot] = ACPI_STATE_D3_HOT,
                [PCI_D3cold] = ACPI_STATE_D3
        };
        int error = -EINVAL;
index 0a3594c7e91263fcf7d1498e4e3634d4d8690ac2..bcbad8452a6f0ca5bb818b684837e207ffef7b5f 100644 (file)
@@ -78,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev)
 
        input_set_capability(input, EV_KEY, KEY_POWER);
 
-       error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0,
+       error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,
                        DRIVER_NAME, input);
        if (error) {
                dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
index 42f5f829b3ee1c0ff8adfcc3d120f47367b7cd05..029e421baaed49b7f62c58c0ef89454d2fa2053b 100644 (file)
@@ -360,12 +360,11 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op)
                                                &mpc5200_rtc_ops, THIS_MODULE);
        }
 
-       rtc->rtc->uie_unsupported = 1;
-
        if (IS_ERR(rtc->rtc)) {
                err = PTR_ERR(rtc->rtc);
                goto out_free_irq;
        }
+       rtc->rtc->uie_unsupported = 1;
 
        return 0;
 
index 120955c66410faf8e4c8254baebba15895d38aa9..8334dadc681de98eeb7ac78fed5755336ff58d63 100644 (file)
@@ -1672,7 +1672,8 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd)
 {
        QETH_DBF_TEXT(SETUP, 2, "cfgblkt");
 
-       if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) {
+       if (prcd[74] == 0xF0 && prcd[75] == 0xF0 &&
+           (prcd[76] == 0xF5 || prcd[76] == 0xF6)) {
                card->info.blkt.time_total = 250;
                card->info.blkt.inter_packet = 5;
                card->info.blkt.inter_packet_jumbo = 15;
@@ -4540,7 +4541,8 @@ static void qeth_determine_capabilities(struct qeth_card *card)
                goto out_offline;
        }
        qeth_configure_unitaddr(card, prcd);
-       qeth_configure_blkt_default(card, prcd);
+       if (ddev_offline)
+               qeth_configure_blkt_default(card, prcd);
        kfree(prcd);
 
        rc = qdio_get_ssqd_desc(ddev, &card->ssqd);
index e002cd466e9a916d24d6064012d0488c854cd63e..467dc38246f93317221239e45a798c867bd1cdb0 100644 (file)
@@ -4549,8 +4549,12 @@ static int ipr_ata_slave_alloc(struct scsi_device *sdev)
        ENTER;
        if (sdev->sdev_target)
                sata_port = sdev->sdev_target->hostdata;
-       if (sata_port)
+       if (sata_port) {
                rc = ata_sas_port_init(sata_port->ap);
+               if (rc == 0)
+                       rc = ata_sas_sync_probe(sata_port->ap);
+       }
+
        if (rc)
                ipr_slave_destroy(sdev);
 
index ef9560dff295f9252bf9ccdf3a4d9d2de61d1852..cc83b66d45b7836aebe4fe55085935922fdb4a56 100644 (file)
@@ -1742,17 +1742,19 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 
        mfs = ntohs(flp->fl_csp.sp_bb_data) &
                FC_SP_BB_DATA_MASK;
-       if (mfs >= FC_SP_MIN_MAX_PAYLOAD &&
-           mfs <= lport->mfs) {
-               lport->mfs = mfs;
-               fc_host_maxframe_size(lport->host) = mfs;
-       } else {
+
+       if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) {
                FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, "
                             "lport->mfs:%hu\n", mfs, lport->mfs);
                fc_lport_error(lport, fp);
                goto err;
        }
 
+       if (mfs <= lport->mfs) {
+               lport->mfs = mfs;
+               fc_host_maxframe_size(lport->host) = mfs;
+       }
+
        csp_flags = ntohs(flp->fl_csp.sp_features);
        r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov);
        e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov);
index bc0cecc6ad62492c02b153ecee767ed0cfd650b1..441d88ad99a7bb3abadb8b1e9af25281ced8334b 100644 (file)
@@ -546,11 +546,12 @@ static struct ata_port_info sata_port_info = {
        .port_ops = &sas_sata_ops
 };
 
-int sas_ata_init_host_and_port(struct domain_device *found_dev)
+int sas_ata_init(struct domain_device *found_dev)
 {
        struct sas_ha_struct *ha = found_dev->port->ha;
        struct Scsi_Host *shost = ha->core.shost;
        struct ata_port *ap;
+       int rc;
 
        ata_host_init(&found_dev->sata_dev.ata_host,
                      ha->dev,
@@ -567,8 +568,11 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev)
        ap->private_data = found_dev;
        ap->cbl = ATA_CBL_SATA;
        ap->scsi_host = shost;
-       /* publish initialized ata port */
-       smp_wmb();
+       rc = ata_sas_port_init(ap);
+       if (rc) {
+               ata_sas_port_destroy(ap);
+               return rc;
+       }
        found_dev->sata_dev.ap = ap;
 
        return 0;
@@ -648,18 +652,13 @@ static void sas_get_ata_command_set(struct domain_device *dev)
 void sas_probe_sata(struct asd_sas_port *port)
 {
        struct domain_device *dev, *n;
-       int err;
 
        mutex_lock(&port->ha->disco_mutex);
-       list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) {
+       list_for_each_entry(dev, &port->disco_list, disco_list_node) {
                if (!dev_is_sata(dev))
                        continue;
 
-               err = sas_ata_init_host_and_port(dev);
-               if (err)
-                       sas_fail_probe(dev, __func__, err);
-               else
-                       ata_sas_async_port_init(dev->sata_dev.ap);
+               ata_sas_async_probe(dev->sata_dev.ap);
        }
        mutex_unlock(&port->ha->disco_mutex);
 
@@ -718,18 +717,6 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie)
        sas_put_device(dev);
 }
 
-static bool sas_ata_dev_eh_valid(struct domain_device *dev)
-{
-       struct ata_port *ap;
-
-       if (!dev_is_sata(dev))
-               return false;
-       ap = dev->sata_dev.ap;
-       /* consume fully initialized ata ports */
-       smp_rmb();
-       return !!ap;
-}
-
 void sas_ata_strategy_handler(struct Scsi_Host *shost)
 {
        struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
@@ -753,7 +740,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost)
 
                spin_lock(&port->dev_list_lock);
                list_for_each_entry(dev, &port->dev_list, dev_list_node) {
-                       if (!sas_ata_dev_eh_valid(dev))
+                       if (!dev_is_sata(dev))
                                continue;
                        async_schedule_domain(async_sas_ata_eh, dev, &async);
                }
index 3646796756028bd1258a7dd920025d860baa294d..629a0865b130db3fc25036103ab78aaf94eba5ea 100644 (file)
@@ -72,6 +72,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
        struct asd_sas_phy *phy;
        struct sas_rphy *rphy;
        struct domain_device *dev;
+       int rc = -ENODEV;
 
        dev = sas_alloc_device();
        if (!dev)
@@ -110,9 +111,16 @@ static int sas_get_port_device(struct asd_sas_port *port)
 
        sas_init_dev(dev);
 
+       dev->port = port;
        switch (dev->dev_type) {
-       case SAS_END_DEV:
        case SATA_DEV:
+               rc = sas_ata_init(dev);
+               if (rc) {
+                       rphy = NULL;
+                       break;
+               }
+               /* fall through */
+       case SAS_END_DEV:
                rphy = sas_end_device_alloc(port->port);
                break;
        case EDGE_DEV:
@@ -131,19 +139,14 @@ static int sas_get_port_device(struct asd_sas_port *port)
 
        if (!rphy) {
                sas_put_device(dev);
-               return -ENODEV;
+               return rc;
        }
 
-       spin_lock_irq(&port->phy_list_lock);
-       list_for_each_entry(phy, &port->phy_list, port_phy_el)
-               sas_phy_set_target(phy, dev);
-       spin_unlock_irq(&port->phy_list_lock);
        rphy->identify.phy_identifier = phy->phy->identify.phy_identifier;
        memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE);
        sas_fill_in_rphy(dev, rphy);
        sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
        port->port_dev = dev;
-       dev->port = port;
        dev->linkrate = port->linkrate;
        dev->min_linkrate = port->linkrate;
        dev->max_linkrate = port->linkrate;
@@ -155,6 +158,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
        sas_device_set_phy(dev, port->port);
 
        dev->rphy = rphy;
+       get_device(&dev->rphy->dev);
 
        if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV)
                list_add_tail(&dev->disco_list_node, &port->disco_list);
@@ -164,6 +168,11 @@ static int sas_get_port_device(struct asd_sas_port *port)
                spin_unlock_irq(&port->dev_list_lock);
        }
 
+       spin_lock_irq(&port->phy_list_lock);
+       list_for_each_entry(phy, &port->phy_list, port_phy_el)
+               sas_phy_set_target(phy, dev);
+       spin_unlock_irq(&port->phy_list_lock);
+
        return 0;
 }
 
@@ -205,8 +214,7 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
 static void sas_probe_devices(struct work_struct *work)
 {
        struct domain_device *dev, *n;
-       struct sas_discovery_event *ev =
-               container_of(work, struct sas_discovery_event, work);
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
        struct asd_sas_port *port = ev->port;
 
        clear_bit(DISCE_PROBE, &port->disc.pending);
@@ -255,6 +263,9 @@ void sas_free_device(struct kref *kref)
 {
        struct domain_device *dev = container_of(kref, typeof(*dev), kref);
 
+       put_device(&dev->rphy->dev);
+       dev->rphy = NULL;
+
        if (dev->parent)
                sas_put_device(dev->parent);
 
@@ -291,8 +302,7 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d
 static void sas_destruct_devices(struct work_struct *work)
 {
        struct domain_device *dev, *n;
-       struct sas_discovery_event *ev =
-               container_of(work, struct sas_discovery_event, work);
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
        struct asd_sas_port *port = ev->port;
 
        clear_bit(DISCE_DESTRUCT, &port->disc.pending);
@@ -302,7 +312,6 @@ static void sas_destruct_devices(struct work_struct *work)
 
                sas_remove_children(&dev->rphy->dev);
                sas_rphy_delete(dev->rphy);
-               dev->rphy = NULL;
                sas_unregister_common_dev(port, dev);
        }
 }
@@ -314,11 +323,11 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
                /* this rphy never saw sas_rphy_add */
                list_del_init(&dev->disco_list_node);
                sas_rphy_free(dev->rphy);
-               dev->rphy = NULL;
                sas_unregister_common_dev(port, dev);
+               return;
        }
 
-       if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {
+       if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {
                sas_rphy_unlink(dev->rphy);
                list_move_tail(&dev->disco_list_node, &port->destroy_list);
                sas_discover_event(dev->port, DISCE_DESTRUCT);
@@ -377,8 +386,7 @@ static void sas_discover_domain(struct work_struct *work)
 {
        struct domain_device *dev;
        int error = 0;
-       struct sas_discovery_event *ev =
-               container_of(work, struct sas_discovery_event, work);
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
        struct asd_sas_port *port = ev->port;
 
        clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending);
@@ -419,8 +427,6 @@ static void sas_discover_domain(struct work_struct *work)
 
        if (error) {
                sas_rphy_free(dev->rphy);
-               dev->rphy = NULL;
-
                list_del_init(&dev->disco_list_node);
                spin_lock_irq(&port->dev_list_lock);
                list_del_init(&dev->dev_list_node);
@@ -437,8 +443,7 @@ static void sas_discover_domain(struct work_struct *work)
 static void sas_revalidate_domain(struct work_struct *work)
 {
        int res = 0;
-       struct sas_discovery_event *ev =
-               container_of(work, struct sas_discovery_event, work);
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
        struct asd_sas_port *port = ev->port;
        struct sas_ha_struct *ha = port->ha;
 
@@ -466,21 +471,25 @@ static void sas_revalidate_domain(struct work_struct *work)
 
 /* ---------- Events ---------- */
 
-static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work)
+static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw)
 {
-       /* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */
-       scsi_queue_work(ha->core.shost, work);
+       /* chained work is not subject to SA_HA_DRAINING or
+        * SAS_HA_REGISTERED, because it is either submitted in the
+        * workqueue, or known to be submitted from a context that is
+        * not racing against draining
+        */
+       scsi_queue_work(ha->core.shost, &sw->work);
 }
 
 static void sas_chain_event(int event, unsigned long *pending,
-                           struct work_struct *work,
+                           struct sas_work *sw,
                            struct sas_ha_struct *ha)
 {
        if (!test_and_set_bit(event, pending)) {
                unsigned long flags;
 
                spin_lock_irqsave(&ha->state_lock, flags);
-               sas_chain_work(ha, work);
+               sas_chain_work(ha, sw);
                spin_unlock_irqrestore(&ha->state_lock, flags);
        }
 }
@@ -519,7 +528,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
 
        disc->pending = 0;
        for (i = 0; i < DISC_NUM_EVENTS; i++) {
-               INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
+               INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]);
                disc->disc_work[i].port = port;
        }
 }
index 16639bbae629d279af43a33f78072e4d88d09fc8..4e4292d210c1478131b6eda3260f51b6ffc3fa52 100644 (file)
 #include "sas_internal.h"
 #include "sas_dump.h"
 
-void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work)
+void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw)
 {
        if (!test_bit(SAS_HA_REGISTERED, &ha->state))
                return;
 
-       if (test_bit(SAS_HA_DRAINING, &ha->state))
-               list_add(&work->entry, &ha->defer_q);
-       else
-               scsi_queue_work(ha->core.shost, work);
+       if (test_bit(SAS_HA_DRAINING, &ha->state)) {
+               /* add it to the defer list, if not already pending */
+               if (list_empty(&sw->drain_node))
+                       list_add(&sw->drain_node, &ha->defer_q);
+       } else
+               scsi_queue_work(ha->core.shost, &sw->work);
 }
 
 static void sas_queue_event(int event, unsigned long *pending,
-                           struct work_struct *work,
+                           struct sas_work *work,
                            struct sas_ha_struct *ha)
 {
        if (!test_and_set_bit(event, pending)) {
@@ -55,7 +57,7 @@ static void sas_queue_event(int event, unsigned long *pending,
 void __sas_drain_work(struct sas_ha_struct *ha)
 {
        struct workqueue_struct *wq = ha->core.shost->work_q;
-       struct work_struct *w, *_w;
+       struct sas_work *sw, *_sw;
 
        set_bit(SAS_HA_DRAINING, &ha->state);
        /* flush submitters */
@@ -66,9 +68,9 @@ void __sas_drain_work(struct sas_ha_struct *ha)
 
        spin_lock_irq(&ha->state_lock);
        clear_bit(SAS_HA_DRAINING, &ha->state);
-       list_for_each_entry_safe(w, _w, &ha->defer_q, entry) {
-               list_del_init(&w->entry);
-               sas_queue_work(ha, w);
+       list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) {
+               list_del_init(&sw->drain_node);
+               sas_queue_work(ha, sw);
        }
        spin_unlock_irq(&ha->state_lock);
 }
@@ -151,7 +153,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha)
        int i;
 
        for (i = 0; i < HA_NUM_EVENTS; i++) {
-               INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);
+               INIT_SAS_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]);
                sas_ha->ha_events[i].ha = sas_ha;
        }
 
index 05acd9e35fc4def9872d8b19debdb2875302b65b..caa0525d2523037f7bace6a27cfdb007176b0448 100644 (file)
@@ -202,6 +202,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        u8 sas_addr[SAS_ADDR_SIZE];
        struct smp_resp *resp = rsp;
        struct discover_resp *dr = &resp->disc;
+       struct sas_ha_struct *ha = dev->port->ha;
        struct expander_device *ex = &dev->ex_dev;
        struct ex_phy *phy = &ex->ex_phy[phy_id];
        struct sas_rphy *rphy = dev->rphy;
@@ -209,6 +210,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        char *type;
 
        if (new_phy) {
+               if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)))
+                       return;
                phy->phy = sas_phy_alloc(&rphy->dev, phy_id);
 
                /* FIXME: error_handling */
@@ -233,6 +236,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
 
        phy->attached_dev_type = to_dev_type(dr);
+       if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
+               goto out;
        phy->phy_id = phy_id;
        phy->linkrate = dr->linkrate;
        phy->attached_sata_host = dr->attached_sata_host;
@@ -240,7 +245,14 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        phy->attached_sata_ps   = dr->attached_sata_ps;
        phy->attached_iproto = dr->iproto << 1;
        phy->attached_tproto = dr->tproto << 1;
-       memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
+       /* help some expanders that fail to zero sas_address in the 'no
+        * device' case
+        */
+       if (phy->attached_dev_type == NO_DEVICE ||
+           phy->linkrate < SAS_LINK_RATE_1_5_GBPS)
+               memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
+       else
+               memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE);
        phy->attached_phy_id = dr->attached_phy_id;
        phy->phy_change_count = dr->change_count;
        phy->routing_attr = dr->routing_attr;
@@ -266,6 +278,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
                        return;
                }
 
+ out:
        switch (phy->attached_dev_type) {
        case SATA_PENDING:
                type = "stp pending";
@@ -304,7 +317,15 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
        else
                return;
 
-       SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
+       /* if the attached device type changed and ata_eh is active,
+        * make sure we run revalidation when eh completes (see:
+        * sas_enable_revalidation)
+        */
+       if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))
+               set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending);
+
+       SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
+                   test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "",
                    SAS_ADDR(dev->sas_addr), phy->phy_id,
                    sas_route_char(dev, phy), phy->linkrate,
                    SAS_ADDR(phy->attached_sas_addr), type);
@@ -776,13 +797,16 @@ static struct domain_device *sas_ex_discover_end_dev(
                if (res)
                        goto out_free;
 
+               sas_init_dev(child);
+               res = sas_ata_init(child);
+               if (res)
+                       goto out_free;
                rphy = sas_end_device_alloc(phy->port);
-               if (unlikely(!rphy))
+               if (!rphy)
                        goto out_free;
 
-               sas_init_dev(child);
-
                child->rphy = rphy;
+               get_device(&rphy->dev);
 
                list_add_tail(&child->disco_list_node, &parent->port->disco_list);
 
@@ -806,6 +830,7 @@ static struct domain_device *sas_ex_discover_end_dev(
                sas_init_dev(child);
 
                child->rphy = rphy;
+               get_device(&rphy->dev);
                sas_fill_in_rphy(child, rphy);
 
                list_add_tail(&child->disco_list_node, &parent->port->disco_list);
@@ -830,8 +855,6 @@ static struct domain_device *sas_ex_discover_end_dev(
 
  out_list_del:
        sas_rphy_free(child->rphy);
-       child->rphy = NULL;
-
        list_del(&child->disco_list_node);
        spin_lock_irq(&parent->port->dev_list_lock);
        list_del(&child->dev_list_node);
@@ -911,6 +934,7 @@ static struct domain_device *sas_ex_discover_expander(
        }
        port = parent->port;
        child->rphy = rphy;
+       get_device(&rphy->dev);
        edev = rphy_to_expander_device(rphy);
        child->dev_type = phy->attached_dev_type;
        kref_get(&parent->kref);
@@ -934,6 +958,7 @@ static struct domain_device *sas_ex_discover_expander(
 
        res = sas_discover_expander(child);
        if (res) {
+               sas_rphy_delete(rphy);
                spin_lock_irq(&parent->port->dev_list_lock);
                list_del(&child->dev_list_node);
                spin_unlock_irq(&parent->port->dev_list_lock);
@@ -1718,9 +1743,17 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
                int phy_change_count = 0;
 
                res = sas_get_phy_change_count(dev, i, &phy_change_count);
-               if (res)
-                       goto out;
-               else if (phy_change_count != ex->ex_phy[i].phy_change_count) {
+               switch (res) {
+               case SMP_RESP_PHY_VACANT:
+               case SMP_RESP_NO_PHY:
+                       continue;
+               case SMP_RESP_FUNC_ACC:
+                       break;
+               default:
+                       return res;
+               }
+
+               if (phy_change_count != ex->ex_phy[i].phy_change_count) {
                        if (update)
                                ex->ex_phy[i].phy_change_count =
                                        phy_change_count;
@@ -1728,8 +1761,7 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id,
                        return 0;
                }
        }
-out:
-       return res;
+       return 0;
 }
 
 static int sas_get_ex_change_count(struct domain_device *dev, int *ecc)
index 120bff64be303c67cc66aba9fdfae3af7d58e2c8..10cb5ae30977cfaa9da66f5ad0b7b497aa51b758 100644 (file)
@@ -94,8 +94,7 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
 
 void sas_hae_reset(struct work_struct *work)
 {
-       struct sas_ha_event *ev =
-               container_of(work, struct sas_ha_event, work);
+       struct sas_ha_event *ev = to_sas_ha_event(work);
        struct sas_ha_struct *ha = ev->ha;
 
        clear_bit(HAE_RESET, &ha->pending);
@@ -369,14 +368,14 @@ static void sas_phy_release(struct sas_phy *phy)
 
 static void phy_reset_work(struct work_struct *work)
 {
-       struct sas_phy_data *d = container_of(work, typeof(*d), reset_work);
+       struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work);
 
        d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
 }
 
 static void phy_enable_work(struct work_struct *work)
 {
-       struct sas_phy_data *d = container_of(work, typeof(*d), enable_work);
+       struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work);
 
        d->enable_result = sas_phy_enable(d->phy, d->enable);
 }
@@ -389,8 +388,8 @@ static int sas_phy_setup(struct sas_phy *phy)
                return -ENOMEM;
 
        mutex_init(&d->event_lock);
-       INIT_WORK(&d->reset_work, phy_reset_work);
-       INIT_WORK(&d->enable_work, phy_enable_work);
+       INIT_SAS_WORK(&d->reset_work, phy_reset_work);
+       INIT_SAS_WORK(&d->enable_work, phy_enable_work);
        d->phy = phy;
        phy->hostdata = d;
 
index f05c63879949a1b70ef1553571d54e87922f0d18..507e4cf12e56cef87cd3b80af00215cc62db6078 100644 (file)
@@ -45,10 +45,10 @@ struct sas_phy_data {
        struct mutex event_lock;
        int hard_reset;
        int reset_result;
-       struct work_struct reset_work;
+       struct sas_work reset_work;
        int enable;
        int enable_result;
-       struct work_struct enable_work;
+       struct sas_work enable_work;
 };
 
 void sas_scsi_recover_host(struct Scsi_Host *shost);
@@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work);
 void sas_porte_link_reset_err(struct work_struct *work);
 void sas_porte_timer_event(struct work_struct *work);
 void sas_porte_hard_reset(struct work_struct *work);
-void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work);
+void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw);
 
 int sas_notify_lldd_dev_found(struct domain_device *);
 void sas_notify_lldd_dev_gone(struct domain_device *);
index dcfd4a9105c5e2429b210bf427f85cf97ae2620b..521422e857ab330ee3a659ad11dae2dd02aee9f0 100644 (file)
@@ -32,8 +32,7 @@
 
 static void sas_phye_loss_of_signal(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending);
@@ -43,8 +42,7 @@ static void sas_phye_loss_of_signal(struct work_struct *work)
 
 static void sas_phye_oob_done(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending);
@@ -53,8 +51,7 @@ static void sas_phye_oob_done(struct work_struct *work)
 
 static void sas_phye_oob_error(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
        struct sas_ha_struct *sas_ha = phy->ha;
        struct asd_sas_port *port = phy->port;
@@ -85,8 +82,7 @@ static void sas_phye_oob_error(struct work_struct *work)
 
 static void sas_phye_spinup_hold(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
        struct sas_ha_struct *sas_ha = phy->ha;
        struct sas_internal *i =
@@ -127,14 +123,12 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
                phy->error = 0;
                INIT_LIST_HEAD(&phy->port_phy_el);
                for (k = 0; k < PORT_NUM_EVENTS; k++) {
-                       INIT_WORK(&phy->port_events[k].work,
-                                 sas_port_event_fns[k]);
+                       INIT_SAS_WORK(&phy->port_events[k].work, sas_port_event_fns[k]);
                        phy->port_events[k].phy = phy;
                }
 
                for (k = 0; k < PHY_NUM_EVENTS; k++) {
-                       INIT_WORK(&phy->phy_events[k].work,
-                                 sas_phy_event_fns[k]);
+                       INIT_SAS_WORK(&phy->phy_events[k].work, sas_phy_event_fns[k]);
                        phy->phy_events[k].phy = phy;
                }
 
@@ -144,8 +138,7 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
                spin_lock_init(&phy->sas_prim_lock);
                phy->frame_rcvd_size = 0;
 
-               phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev,
-                                        i);
+               phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, i);
                if (!phy->phy)
                        return -ENOMEM;
 
index eb19c016d5001b1890feafa0f8ae140e1982a1bf..e884a8c58a0ccb181424051281fda4b4a45fc1a9 100644 (file)
@@ -123,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
        spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
 
        if (!port->port) {
-               port->port = sas_port_alloc(phy->phy->dev.parent, phy->id);
+               port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
                BUG_ON(!port->port);
                sas_port_add(port->port);
        }
@@ -208,8 +208,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
 
 void sas_porte_bytes_dmaed(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending);
@@ -219,8 +218,7 @@ void sas_porte_bytes_dmaed(struct work_struct *work)
 
 void sas_porte_broadcast_rcvd(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
        unsigned long flags;
        u32 prim;
@@ -237,8 +235,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work)
 
 void sas_porte_link_reset_err(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending);
@@ -248,8 +245,7 @@ void sas_porte_link_reset_err(struct work_struct *work)
 
 void sas_porte_timer_event(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending);
@@ -259,8 +255,7 @@ void sas_porte_timer_event(struct work_struct *work)
 
 void sas_porte_hard_reset(struct work_struct *work)
 {
-       struct asd_sas_event *ev =
-               container_of(work, struct asd_sas_event, work);
+       struct asd_sas_event *ev = to_asd_sas_event(work);
        struct asd_sas_phy *phy = ev->phy;
 
        clear_bit(PORTE_HARD_RESET, &phy->port_events_pending);
index ead6405f3e51465f5dfe95412cb4d242fa704608..5dfd7495d1a1bc4231123760090aa3d38eb9a764 100644 (file)
@@ -1638,7 +1638,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
                                         request_fn_proc *request_fn)
 {
        struct request_queue *q;
-       struct device *dev = shost->shost_gendev.parent;
+       struct device *dev = shost->dma_dev;
 
        q = blk_init_queue(request_fn, NULL);
        if (!q)
index 08ebe901bb59875a95b87148a04d15404523c019..654755a990dfc30cac559567e260b17978bbc54b 100644 (file)
@@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)
        tty = NULL;
        if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
                if (!ZS_IS_OPEN(uap_a)) {
-                       pmz_debug("ChanA interrupt while open !\n");
+                       pmz_debug("ChanA interrupt while not open !\n");
                        goto skip_a;
                }
                write_zsreg(uap_a, R0, RES_H_IUS);
@@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)
        spin_lock(&uap_b->port.lock);
        tty = NULL;
        if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
-               if (!ZS_IS_OPEN(uap_a)) {
-                       pmz_debug("ChanB interrupt while open !\n");
+               if (!ZS_IS_OPEN(uap_b)) {
+                       pmz_debug("ChanB interrupt while not open !\n");
                        goto skip_b;
                }
                write_zsreg(uap_b, R0, RES_H_IUS);
index 86dd1e302bb3f0989d52ba2b136d1ec39e29c488..29ca20dbd335da2235339b8f7970849f2d22895f 100644 (file)
@@ -1085,15 +1085,21 @@ void vt_set_led_state(int console, int leds)
  *
  *     Handle console start. This is a wrapper for the VT layer
  *     so that we can keep kbd knowledge internal
+ *
+ *     FIXME: We eventually need to hold the kbd lock here to protect
+ *     the LED updating. We can't do it yet because fn_hold calls stop_tty
+ *     and start_tty under the kbd_event_lock, while normal tty paths
+ *     don't hold the lock. We probably need to split out an LED lock
+ *     but not during an -rc release!
  */
 void vt_kbd_con_start(int console)
 {
        struct kbd_struct * kbd = kbd_table + console;
-       unsigned long flags;
-       spin_lock_irqsave(&kbd_event_lock, flags);
+/*     unsigned long flags; */
+/*     spin_lock_irqsave(&kbd_event_lock, flags); */
        clr_vc_kbd_led(kbd, VC_SCROLLOCK);
        set_leds();
-       spin_unlock_irqrestore(&kbd_event_lock, flags);
+/*     spin_unlock_irqrestore(&kbd_event_lock, flags); */
 }
 
 /**
@@ -1102,22 +1108,28 @@ void vt_kbd_con_start(int console)
  *
  *     Handle console stop. This is a wrapper for the VT layer
  *     so that we can keep kbd knowledge internal
+ *
+ *     FIXME: We eventually need to hold the kbd lock here to protect
+ *     the LED updating. We can't do it yet because fn_hold calls stop_tty
+ *     and start_tty under the kbd_event_lock, while normal tty paths
+ *     don't hold the lock. We probably need to split out an LED lock
+ *     but not during an -rc release!
  */
 void vt_kbd_con_stop(int console)
 {
        struct kbd_struct * kbd = kbd_table + console;
-       unsigned long flags;
-       spin_lock_irqsave(&kbd_event_lock, flags);
+/*     unsigned long flags; */
+/*     spin_lock_irqsave(&kbd_event_lock, flags); */
        set_vc_kbd_led(kbd, VC_SCROLLOCK);
        set_leds();
-       spin_unlock_irqrestore(&kbd_event_lock, flags);
+/*     spin_unlock_irqrestore(&kbd_event_lock, flags); */
 }
 
 /*
  * This is the tasklet that updates LED state on all keyboards
  * attached to the box. The reason we use tasklet is that we
  * need to handle the scenario when keyboard handler is not
- * registered yet but we already getting updates form VT to
+ * registered yet but we already getting updates from the VT to
  * update led state.
  */
 static void kbd_bh(unsigned long dummy)
index 86183366647f7803f256d2ef6d05da639818c8e5..f214a80cdee212ec816601ef51645b05fd3f6d68 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
 
 #include <mach/usb_phy.h>
 #include <mach/iomap.h>
@@ -37,9 +38,7 @@ struct tegra_ehci_hcd {
        struct clk *emc_clk;
        struct usb_phy *transceiver;
        int host_resumed;
-       int bus_suspended;
        int port_resuming;
-       int power_down_on_bus_suspend;
        enum tegra_usb_phy_port_speed port_speed;
 };
 
@@ -273,120 +272,6 @@ static void tegra_ehci_restart(struct usb_hcd *hcd)
        up_write(&ehci_cf_port_reset_rwsem);
 }
 
-static int tegra_usb_suspend(struct usb_hcd *hcd)
-{
-       struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
-       struct ehci_regs __iomem *hw = tegra->ehci->regs;
-       unsigned long flags;
-
-       spin_lock_irqsave(&tegra->ehci->lock, flags);
-
-       tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3;
-       ehci_halt(tegra->ehci);
-       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-
-       spin_unlock_irqrestore(&tegra->ehci->lock, flags);
-
-       tegra_ehci_power_down(hcd);
-       return 0;
-}
-
-static int tegra_usb_resume(struct usb_hcd *hcd)
-{
-       struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
-       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-       struct ehci_regs __iomem *hw = ehci->regs;
-       unsigned long val;
-
-       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-       tegra_ehci_power_up(hcd);
-
-       if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) {
-               /* Wait for the phy to detect new devices
-                * before we restart the controller */
-               msleep(10);
-               goto restart;
-       }
-
-       /* Force the phy to keep data lines in suspend state */
-       tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed);
-
-       /* Enable host mode */
-       tdi_reset(ehci);
-
-       /* Enable Port Power */
-       val = readl(&hw->port_status[0]);
-       val |= PORT_POWER;
-       writel(val, &hw->port_status[0]);
-       udelay(10);
-
-       /* Check if the phy resume from LP0. When the phy resume from LP0
-        * USB register will be reset. */
-       if (!readl(&hw->async_next)) {
-               /* Program the field PTC based on the saved speed mode */
-               val = readl(&hw->port_status[0]);
-               val &= ~PORT_TEST(~0);
-               if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH)
-                       val |= PORT_TEST_FORCE;
-               else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL)
-                       val |= PORT_TEST(6);
-               else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
-                       val |= PORT_TEST(7);
-               writel(val, &hw->port_status[0]);
-               udelay(10);
-
-               /* Disable test mode by setting PTC field to NORMAL_OP */
-               val = readl(&hw->port_status[0]);
-               val &= ~PORT_TEST(~0);
-               writel(val, &hw->port_status[0]);
-               udelay(10);
-       }
-
-       /* Poll until CCS is enabled */
-       if (handshake(ehci, &hw->port_status[0], PORT_CONNECT,
-                                                PORT_CONNECT, 2000)) {
-               pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__);
-               goto restart;
-       }
-
-       /* Poll until PE is enabled */
-       if (handshake(ehci, &hw->port_status[0], PORT_PE,
-                                                PORT_PE, 2000)) {
-               pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__);
-               goto restart;
-       }
-
-       /* Clear the PCI status, to avoid an interrupt taken upon resume */
-       val = readl(&hw->status);
-       val |= STS_PCD;
-       writel(val, &hw->status);
-
-       /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */
-       val = readl(&hw->port_status[0]);
-       if ((val & PORT_POWER) && (val & PORT_PE)) {
-               val |= PORT_SUSPEND;
-               writel(val, &hw->port_status[0]);
-
-               /* Wait until port suspend completes */
-               if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND,
-                                                        PORT_SUSPEND, 1000)) {
-                       pr_err("%s: timeout waiting for PORT_SUSPEND\n",
-                                                               __func__);
-                       goto restart;
-               }
-       }
-
-       tegra_ehci_phy_restore_end(tegra->phy);
-       return 0;
-
-restart:
-       if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH)
-               tegra_ehci_phy_restore_end(tegra->phy);
-
-       tegra_ehci_restart(hcd);
-       return 0;
-}
-
 static void tegra_ehci_shutdown(struct usb_hcd *hcd)
 {
        struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
@@ -434,36 +319,6 @@ static int tegra_ehci_setup(struct usb_hcd *hcd)
        return retval;
 }
 
-#ifdef CONFIG_PM
-static int tegra_ehci_bus_suspend(struct usb_hcd *hcd)
-{
-       struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
-       int error_status = 0;
-
-       error_status = ehci_bus_suspend(hcd);
-       if (!error_status && tegra->power_down_on_bus_suspend) {
-               tegra_usb_suspend(hcd);
-               tegra->bus_suspended = 1;
-       }
-
-       return error_status;
-}
-
-static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
-{
-       struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller);
-
-       if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) {
-               tegra_usb_resume(hcd);
-               tegra->bus_suspended = 0;
-       }
-
-       tegra_usb_phy_preresume(tegra->phy);
-       tegra->port_resuming = 1;
-       return ehci_bus_resume(hcd);
-}
-#endif
-
 struct temp_buffer {
        void *kmalloc_ptr;
        void *old_xfer_buffer;
@@ -574,8 +429,8 @@ static const struct hc_driver tegra_ehci_hc_driver = {
        .hub_control            = tegra_ehci_hub_control,
        .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 #ifdef CONFIG_PM
-       .bus_suspend            = tegra_ehci_bus_suspend,
-       .bus_resume             = tegra_ehci_bus_resume,
+       .bus_suspend            = ehci_bus_suspend,
+       .bus_resume             = ehci_bus_resume,
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
@@ -603,11 +458,187 @@ static int setup_vbus_gpio(struct platform_device *pdev)
                dev_err(&pdev->dev, "can't enable vbus\n");
                return err;
        }
-       gpio_set_value(gpio, 1);
 
        return err;
 }
 
+#ifdef CONFIG_PM
+
+static int controller_suspend(struct device *dev)
+{
+       struct tegra_ehci_hcd *tegra =
+                       platform_get_drvdata(to_platform_device(dev));
+       struct ehci_hcd *ehci = tegra->ehci;
+       struct usb_hcd *hcd = ehci_to_hcd(ehci);
+       struct ehci_regs __iomem *hw = ehci->regs;
+       unsigned long flags;
+
+       if (time_before(jiffies, ehci->next_statechange))
+               msleep(10);
+
+       spin_lock_irqsave(&ehci->lock, flags);
+
+       tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3;
+       ehci_halt(ehci);
+       clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+       spin_unlock_irqrestore(&ehci->lock, flags);
+
+       tegra_ehci_power_down(hcd);
+       return 0;
+}
+
+static int controller_resume(struct device *dev)
+{
+       struct tegra_ehci_hcd *tegra =
+                       platform_get_drvdata(to_platform_device(dev));
+       struct ehci_hcd *ehci = tegra->ehci;
+       struct usb_hcd *hcd = ehci_to_hcd(ehci);
+       struct ehci_regs __iomem *hw = ehci->regs;
+       unsigned long val;
+
+       set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+       tegra_ehci_power_up(hcd);
+
+       if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) {
+               /* Wait for the phy to detect new devices
+                * before we restart the controller */
+               msleep(10);
+               goto restart;
+       }
+
+       /* Force the phy to keep data lines in suspend state */
+       tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed);
+
+       /* Enable host mode */
+       tdi_reset(ehci);
+
+       /* Enable Port Power */
+       val = readl(&hw->port_status[0]);
+       val |= PORT_POWER;
+       writel(val, &hw->port_status[0]);
+       udelay(10);
+
+       /* Check if the phy resume from LP0. When the phy resume from LP0
+        * USB register will be reset. */
+       if (!readl(&hw->async_next)) {
+               /* Program the field PTC based on the saved speed mode */
+               val = readl(&hw->port_status[0]);
+               val &= ~PORT_TEST(~0);
+               if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH)
+                       val |= PORT_TEST_FORCE;
+               else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL)
+                       val |= PORT_TEST(6);
+               else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
+                       val |= PORT_TEST(7);
+               writel(val, &hw->port_status[0]);
+               udelay(10);
+
+               /* Disable test mode by setting PTC field to NORMAL_OP */
+               val = readl(&hw->port_status[0]);
+               val &= ~PORT_TEST(~0);
+               writel(val, &hw->port_status[0]);
+               udelay(10);
+       }
+
+       /* Poll until CCS is enabled */
+       if (handshake(ehci, &hw->port_status[0], PORT_CONNECT,
+                                                PORT_CONNECT, 2000)) {
+               pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__);
+               goto restart;
+       }
+
+       /* Poll until PE is enabled */
+       if (handshake(ehci, &hw->port_status[0], PORT_PE,
+                                                PORT_PE, 2000)) {
+               pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__);
+               goto restart;
+       }
+
+       /* Clear the PCI status, to avoid an interrupt taken upon resume */
+       val = readl(&hw->status);
+       val |= STS_PCD;
+       writel(val, &hw->status);
+
+       /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */
+       val = readl(&hw->port_status[0]);
+       if ((val & PORT_POWER) && (val & PORT_PE)) {
+               val |= PORT_SUSPEND;
+               writel(val, &hw->port_status[0]);
+
+               /* Wait until port suspend completes */
+               if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND,
+                                                        PORT_SUSPEND, 1000)) {
+                       pr_err("%s: timeout waiting for PORT_SUSPEND\n",
+                                                               __func__);
+                       goto restart;
+               }
+       }
+
+       tegra_ehci_phy_restore_end(tegra->phy);
+       goto done;
+
+ restart:
+       if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH)
+               tegra_ehci_phy_restore_end(tegra->phy);
+
+       tegra_ehci_restart(hcd);
+
+ done:
+       tegra_usb_phy_preresume(tegra->phy);
+       tegra->port_resuming = 1;
+       return 0;
+}
+
+static int tegra_ehci_suspend(struct device *dev)
+{
+       struct tegra_ehci_hcd *tegra =
+                       platform_get_drvdata(to_platform_device(dev));
+       struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
+       int rc = 0;
+
+       /*
+        * When system sleep is supported and USB controller wakeup is
+        * implemented: If the controller is runtime-suspended and the
+        * wakeup setting needs to be changed, call pm_runtime_resume().
+        */
+       if (HCD_HW_ACCESSIBLE(hcd))
+               rc = controller_suspend(dev);
+       return rc;
+}
+
+static int tegra_ehci_resume(struct device *dev)
+{
+       int rc;
+
+       rc = controller_resume(dev);
+       if (rc == 0) {
+               pm_runtime_disable(dev);
+               pm_runtime_set_active(dev);
+               pm_runtime_enable(dev);
+       }
+       return rc;
+}
+
+static int tegra_ehci_runtime_suspend(struct device *dev)
+{
+       return controller_suspend(dev);
+}
+
+static int tegra_ehci_runtime_resume(struct device *dev)
+{
+       return controller_resume(dev);
+}
+
+static const struct dev_pm_ops tegra_ehci_pm_ops = {
+       .suspend        = tegra_ehci_suspend,
+       .resume         = tegra_ehci_resume,
+       .runtime_suspend = tegra_ehci_runtime_suspend,
+       .runtime_resume = tegra_ehci_runtime_resume,
+};
+
+#endif
+
 static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32);
 
 static int tegra_ehci_probe(struct platform_device *pdev)
@@ -722,7 +753,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
        }
 
        tegra->host_resumed = 1;
-       tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend;
        tegra->ehci = hcd_to_ehci(hcd);
 
        irq = platform_get_irq(pdev, 0);
@@ -746,6 +776,14 @@ static int tegra_ehci_probe(struct platform_device *pdev)
                goto fail;
        }
 
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_get_noresume(&pdev->dev);
+
+       /* Don't skip the pm_runtime_forbid call if wakeup isn't working */
+       /* if (!pdata->power_down_on_bus_suspend) */
+               pm_runtime_forbid(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_put_sync(&pdev->dev);
        return err;
 
 fail:
@@ -772,33 +810,6 @@ fail_hcd:
        return err;
 }
 
-#ifdef CONFIG_PM
-static int tegra_ehci_resume(struct platform_device *pdev)
-{
-       struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
-       struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
-
-       if (tegra->bus_suspended)
-               return 0;
-
-       return tegra_usb_resume(hcd);
-}
-
-static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
-       struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci);
-
-       if (tegra->bus_suspended)
-               return 0;
-
-       if (time_before(jiffies, tegra->ehci->next_statechange))
-               msleep(10);
-
-       return tegra_usb_suspend(hcd);
-}
-#endif
-
 static int tegra_ehci_remove(struct platform_device *pdev)
 {
        struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev);
@@ -807,6 +818,10 @@ static int tegra_ehci_remove(struct platform_device *pdev)
        if (tegra == NULL || hcd == NULL)
                return -EINVAL;
 
+       pm_runtime_get_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_put_noidle(&pdev->dev);
+
 #ifdef CONFIG_USB_OTG_UTILS
        if (tegra->transceiver) {
                otg_set_host(tegra->transceiver->otg, NULL);
@@ -847,13 +862,12 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = {
 static struct platform_driver tegra_ehci_driver = {
        .probe          = tegra_ehci_probe,
        .remove         = tegra_ehci_remove,
-#ifdef CONFIG_PM
-       .suspend        = tegra_ehci_suspend,
-       .resume         = tegra_ehci_resume,
-#endif
        .shutdown       = tegra_ehci_hcd_shutdown,
        .driver         = {
                .name   = "tegra-ehci",
                .of_match_table = tegra_ehci_of_match,
+#ifdef CONFIG_PM
+               .pm     = &tegra_ehci_pm_ops,
+#endif
        }
 };
index e801f226d7e028b72ca08b5726ed409215c27b84..4106264fbc655ac79b26efa1177384ea92b72988 100644 (file)
@@ -220,10 +220,12 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root)
  */
 static void add_root_to_dirty_list(struct btrfs_root *root)
 {
+       spin_lock(&root->fs_info->trans_lock);
        if (root->track_dirty && list_empty(&root->dirty_list)) {
                list_add(&root->dirty_list,
                         &root->fs_info->dirty_cowonly_roots);
        }
+       spin_unlock(&root->fs_info->trans_lock);
 }
 
 /*
@@ -723,7 +725,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
 
                cur = btrfs_find_tree_block(root, blocknr, blocksize);
                if (cur)
-                       uptodate = btrfs_buffer_uptodate(cur, gen);
+                       uptodate = btrfs_buffer_uptodate(cur, gen, 0);
                else
                        uptodate = 0;
                if (!cur || !uptodate) {
@@ -1358,7 +1360,12 @@ static noinline int reada_for_balance(struct btrfs_root *root,
                block1 = btrfs_node_blockptr(parent, slot - 1);
                gen = btrfs_node_ptr_generation(parent, slot - 1);
                eb = btrfs_find_tree_block(root, block1, blocksize);
-               if (eb && btrfs_buffer_uptodate(eb, gen))
+               /*
+                * if we get -eagain from btrfs_buffer_uptodate, we
+                * don't want to return eagain here.  That will loop
+                * forever
+                */
+               if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
                        block1 = 0;
                free_extent_buffer(eb);
        }
@@ -1366,7 +1373,7 @@ static noinline int reada_for_balance(struct btrfs_root *root,
                block2 = btrfs_node_blockptr(parent, slot + 1);
                gen = btrfs_node_ptr_generation(parent, slot + 1);
                eb = btrfs_find_tree_block(root, block2, blocksize);
-               if (eb && btrfs_buffer_uptodate(eb, gen))
+               if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
                        block2 = 0;
                free_extent_buffer(eb);
        }
@@ -1504,8 +1511,9 @@ read_block_for_search(struct btrfs_trans_handle *trans,
 
        tmp = btrfs_find_tree_block(root, blocknr, blocksize);
        if (tmp) {
-               if (btrfs_buffer_uptodate(tmp, 0)) {
-                       if (btrfs_buffer_uptodate(tmp, gen)) {
+               /* first we do an atomic uptodate check */
+               if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) {
+                       if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
                                /*
                                 * we found an up to date block without
                                 * sleeping, return
@@ -1523,8 +1531,9 @@ read_block_for_search(struct btrfs_trans_handle *trans,
                        free_extent_buffer(tmp);
                        btrfs_set_path_blocking(p);
 
+                       /* now we're allowed to do a blocking uptodate check */
                        tmp = read_tree_block(root, blocknr, blocksize, gen);
-                       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+                       if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) {
                                *eb_ret = tmp;
                                return 0;
                        }
@@ -1559,7 +1568,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
                 * and give up so that our caller doesn't loop forever
                 * on our EAGAINs.
                 */
-               if (!btrfs_buffer_uptodate(tmp, 0))
+               if (!btrfs_buffer_uptodate(tmp, 0, 0))
                        ret = -EIO;
                free_extent_buffer(tmp);
        }
@@ -4043,7 +4052,7 @@ again:
                        tmp = btrfs_find_tree_block(root, blockptr,
                                            btrfs_level_size(root, level - 1));
 
-                       if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+                       if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
                                free_extent_buffer(tmp);
                                break;
                        }
@@ -4166,7 +4175,8 @@ next:
                                struct extent_buffer *cur;
                                cur = btrfs_find_tree_block(root, blockptr,
                                            btrfs_level_size(root, level - 1));
-                               if (!cur || !btrfs_buffer_uptodate(cur, gen)) {
+                               if (!cur ||
+                                   btrfs_buffer_uptodate(cur, gen, 1) <= 0) {
                                        slot++;
                                        if (cur)
                                                free_extent_buffer(cur);
index d0c969beaad4d30a52e13ebb74d3f4fcefa9fece..a7ffc88a7dbe4bcc028d3397970275dffcf0492e 100644 (file)
@@ -323,7 +323,8 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
  * in the wrong place.
  */
 static int verify_parent_transid(struct extent_io_tree *io_tree,
-                                struct extent_buffer *eb, u64 parent_transid)
+                                struct extent_buffer *eb, u64 parent_transid,
+                                int atomic)
 {
        struct extent_state *cached_state = NULL;
        int ret;
@@ -331,6 +332,9 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
        if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
                return 0;
 
+       if (atomic)
+               return -EAGAIN;
+
        lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
                         0, &cached_state);
        if (extent_buffer_uptodate(eb) &&
@@ -372,7 +376,8 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
                ret = read_extent_buffer_pages(io_tree, eb, start,
                                               WAIT_COMPLETE,
                                               btree_get_extent, mirror_num);
-               if (!ret && !verify_parent_transid(io_tree, eb, parent_transid))
+               if (!ret && !verify_parent_transid(io_tree, eb,
+                                                  parent_transid, 0))
                        break;
 
                /*
@@ -1202,7 +1207,7 @@ static int __must_check find_and_setup_root(struct btrfs_root *tree_root,
        root->commit_root = NULL;
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
-       if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+       if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) {
                free_extent_buffer(root->node);
                root->node = NULL;
                return -EIO;
@@ -3143,7 +3148,8 @@ int close_ctree(struct btrfs_root *root)
        return 0;
 }
 
-int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
+int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
+                         int atomic)
 {
        int ret;
        struct inode *btree_inode = buf->pages[0]->mapping->host;
@@ -3153,7 +3159,9 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
                return ret;
 
        ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf,
-                                   parent_transid);
+                                   parent_transid, atomic);
+       if (ret == -EAGAIN)
+               return ret;
        return !ret;
 }
 
index a7ace1a2dd12516a57102e44591f881e922ed89d..ab1830aaf0edbffba6a0cef86d13e9b3f2742cda 100644 (file)
@@ -66,7 +66,8 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
 void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
 void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
 void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
-int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid);
+int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
+                         int atomic);
 int btrfs_set_buffer_uptodate(struct extent_buffer *buf);
 int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid);
 u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
index 6fc2e6f5aab859f2c94ca7135c57cee2de8218ba..49fd7b66d57b272c7aeaea7db4b1bbd0985f8aa2 100644 (file)
@@ -6568,7 +6568,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
                        goto skip;
        }
 
-       if (!btrfs_buffer_uptodate(next, generation)) {
+       if (!btrfs_buffer_uptodate(next, generation, 0)) {
                btrfs_tree_unlock(next);
                free_extent_buffer(next);
                next = NULL;
index 198c2ba2fa405ee13ee9ce65ba45a6c4be3773ec..c9018a05036e943a52ad91d81019bb4b934b6b9a 100644 (file)
@@ -4120,6 +4120,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
                        if (atomic_inc_not_zero(&exists->refs)) {
                                spin_unlock(&mapping->private_lock);
                                unlock_page(p);
+                               page_cache_release(p);
                                mark_extent_buffer_accessed(exists);
                                goto free_eb;
                        }
@@ -4199,8 +4200,7 @@ free_eb:
                        unlock_page(eb->pages[i]);
        }
 
-       if (!atomic_dec_and_test(&eb->refs))
-               return exists;
+       WARN_ON(!atomic_dec_and_test(&eb->refs));
        btrfs_release_extent_buffer(eb);
        return exists;
 }
index 4f69028a68c486268bf5bcfc097a5412dbdd2ad0..086e6bdae1c4482b93b6dda4d16b1c5af288f2eb 100644 (file)
@@ -252,7 +252,7 @@ struct btrfs_data_container {
 
 struct btrfs_ioctl_ino_path_args {
        __u64                           inum;           /* in */
-       __u32                           size;           /* in */
+       __u64                           size;           /* in */
        __u64                           reserved[4];
        /* struct btrfs_data_container  *fspath;           out */
        __u64                           fspath;         /* out */
@@ -260,7 +260,7 @@ struct btrfs_ioctl_ino_path_args {
 
 struct btrfs_ioctl_logical_ino_args {
        __u64                           logical;        /* in */
-       __u32                           size;           /* in */
+       __u64                           size;           /* in */
        __u64                           reserved[4];
        /* struct btrfs_data_container  *inodes;        out   */
        __u64                           inodes;
index 4f76fc3f8e896ed70b01bcb2f45bdbc68a583ba7..2f3d6f917fb3373c02335b6912fcba1006f5fabe 100644 (file)
@@ -998,6 +998,7 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev,
                        page = sblock->pagev + page_index;
                        page->logical = logical;
                        page->physical = bbio->stripes[mirror_index].physical;
+                       /* for missing devices, bdev is NULL */
                        page->bdev = bbio->stripes[mirror_index].dev->bdev;
                        page->mirror_num = mirror_index + 1;
                        page->page = alloc_page(GFP_NOFS);
@@ -1042,6 +1043,12 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info,
                struct scrub_page *page = sblock->pagev + page_num;
                DECLARE_COMPLETION_ONSTACK(complete);
 
+               if (page->bdev == NULL) {
+                       page->io_error = 1;
+                       sblock->no_io_error_seen = 0;
+                       continue;
+               }
+
                BUG_ON(!page->page);
                bio = bio_alloc(GFP_NOFS, 1);
                if (!bio)
index d017283ae6f56fa8ea0ba1eeaa04077d443eb0fb..eb1ae908582cc51162a61798c80f3ed38e7ab6e8 100644 (file)
@@ -279,7 +279,7 @@ static int process_one_buffer(struct btrfs_root *log,
                                                log->fs_info->extent_root,
                                                eb->start, eb->len);
 
-       if (btrfs_buffer_uptodate(eb, gen)) {
+       if (btrfs_buffer_uptodate(eb, gen, 0)) {
                if (wc->write)
                        btrfs_write_tree_block(eb);
                if (wc->wait)
index 811245b1ff2e7a9f6f1d0388368d730a479953e5..ca6a3796a33bb0640b6444891713196834340eb4 100644 (file)
@@ -442,7 +442,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
        seq_printf(s, ",rsize=%u", cifs_sb->rsize);
        seq_printf(s, ",wsize=%u", cifs_sb->wsize);
        /* convert actimeo and display it in seconds */
-               seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
+       seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
 
        return 0;
 }
index d1389bb33ceb98ffdc068b1192dad4f1d2b3f425..65365358c9766dcd2882ab643805565e552f4e25 100644 (file)
@@ -125,5 +125,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "1.77"
+#define CIFS_VERSION   "1.78"
 #endif                         /* _CIFSFS_H */
index f52c5ab78f9dde7fa782bbb2ca26e7da70e450af..da2f5446fa7ae3d3bbba6bb1b7a92cd1cc8743e4 100644 (file)
@@ -4844,8 +4844,12 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
                max_len = data_end - temp;
                node->node_name = cifs_strndup_from_utf16(temp, max_len,
                                                is_unicode, nls_codepage);
-               if (!node->node_name)
+               if (!node->node_name) {
                        rc = -ENOMEM;
+                       goto parse_DFS_referrals_exit;
+               }
+
+               ref++;
        }
 
 parse_DFS_referrals_exit:
index f4d381e331ce442a6181613c6327b7e016cacd72..5dcc55197fb3ff93f3ff3960e3f0b1522f163fc5 100644 (file)
@@ -215,6 +215,8 @@ static const match_table_t cifs_mount_option_tokens = {
 
        { Opt_ignore, "cred" },
        { Opt_ignore, "credentials" },
+       { Opt_ignore, "cred=%s" },
+       { Opt_ignore, "credentials=%s" },
        { Opt_ignore, "guest" },
        { Opt_ignore, "rw" },
        { Opt_ignore, "ro" },
@@ -2183,6 +2185,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        tcp_ses->session_estab = false;
        tcp_ses->sequence_number = 0;
        tcp_ses->lstrp = jiffies;
+       spin_lock_init(&tcp_ses->req_lock);
        INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
        INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
        INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
@@ -3614,22 +3617,6 @@ cifs_get_volume_info(char *mount_data, const char *devname)
        return volume_info;
 }
 
-/* make sure ra_pages is a multiple of rsize */
-static inline unsigned int
-cifs_ra_pages(struct cifs_sb_info *cifs_sb)
-{
-       unsigned int reads;
-       unsigned int rsize_pages = cifs_sb->rsize / PAGE_CACHE_SIZE;
-
-       if (rsize_pages >= default_backing_dev_info.ra_pages)
-               return default_backing_dev_info.ra_pages;
-       else if (rsize_pages == 0)
-               return rsize_pages;
-
-       reads = default_backing_dev_info.ra_pages / rsize_pages;
-       return reads * rsize_pages;
-}
-
 int
 cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
 {
@@ -3717,7 +3704,7 @@ try_mount_again:
        cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info);
 
        /* tune readahead according to rsize */
-       cifs_sb->bdi.ra_pages = cifs_ra_pages(cifs_sb);
+       cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE;
 
 remote_path_check:
 #ifdef CONFIG_CIFS_DFS_UPCALL
index d172c8ed901786f9e72ee40a50cb6bc22a3be571..ec4e9a2a12f843edf9e8d2f60c8a32f58011ec4d 100644 (file)
@@ -668,12 +668,19 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
                        return 0;
                else {
                        /*
-                        * Forcibly invalidate automounting directory inodes
-                        * (remote DFS directories) so to have them
-                        * instantiated again for automount
+                        * If the inode wasn't known to be a dfs entry when
+                        * the dentry was instantiated, such as when created
+                        * via ->readdir(), it needs to be set now since the
+                        * attributes will have been updated by
+                        * cifs_revalidate_dentry().
                         */
-                       if (IS_AUTOMOUNT(direntry->d_inode))
-                               return 0;
+                       if (IS_AUTOMOUNT(direntry->d_inode) &&
+                          !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
+                               spin_lock(&direntry->d_lock);
+                               direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
+                               spin_unlock(&direntry->d_lock);
+                       }
+
                        return 1;
                }
        }
index b60ddc41d78385d168e67e98adc6020fedc1cfeb..b80531c917799475147ba59234c821ea52306fd3 100644 (file)
@@ -141,18 +141,29 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer,
  * Compare 2 name strings, return 0 if they match, otherwise non-zero.
  * The strings are both count bytes long, and count is non-zero.
  */
+#ifdef CONFIG_DCACHE_WORD_ACCESS
+
+#include <asm/word-at-a-time.h>
+/*
+ * NOTE! 'cs' and 'scount' come from a dentry, so it has a
+ * aligned allocation for this particular component. We don't
+ * strictly need the load_unaligned_zeropad() safety, but it
+ * doesn't hurt either.
+ *
+ * In contrast, 'ct' and 'tcount' can be from a pathname, and do
+ * need the careful unaligned handling.
+ */
 static inline int dentry_cmp(const unsigned char *cs, size_t scount,
                                const unsigned char *ct, size_t tcount)
 {
-#ifdef CONFIG_DCACHE_WORD_ACCESS
        unsigned long a,b,mask;
 
        if (unlikely(scount != tcount))
                return 1;
 
        for (;;) {
-               a = *(unsigned long *)cs;
-               b = *(unsigned long *)ct;
+               a = load_unaligned_zeropad(cs);
+               b = load_unaligned_zeropad(ct);
                if (tcount < sizeof(unsigned long))
                        break;
                if (unlikely(a != b))
@@ -165,7 +176,13 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount,
        }
        mask = ~(~0ul << tcount*8);
        return unlikely(!!((a ^ b) & mask));
+}
+
 #else
+
+static inline int dentry_cmp(const unsigned char *cs, size_t scount,
+                               const unsigned char *ct, size_t tcount)
+{
        if (scount != tcount)
                return 1;
 
@@ -177,9 +194,10 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount,
                tcount--;
        } while (tcount);
        return 0;
-#endif
 }
 
+#endif
+
 static void __d_free(struct rcu_head *head)
 {
        struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu);
index 4dfbfec357e8837055c2131206e0ca812fbec4de..ec2a9c23f0c9a58b66a517aceeeab8092efaf11b 100644 (file)
@@ -366,6 +366,10 @@ int hfsplus_rename_cat(u32 cnid,
        err = hfs_brec_find(&src_fd);
        if (err)
                goto out;
+       if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) {
+               err = -EIO;
+               goto out;
+       }
 
        hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset,
                                src_fd.entrylength);
index 88e155f895c6f0376db9e387b9f56f521bbbeb2f..26b53fb09f684404b2c488057f13c08ec8b2c0e2 100644 (file)
@@ -150,6 +150,11 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
                filp->f_pos++;
                /* fall through */
        case 1:
+               if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
+                       err = -EIO;
+                       goto out;
+               }
+
                hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
                        fd.entrylength);
                if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) {
@@ -181,6 +186,12 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)
                        err = -EIO;
                        goto out;
                }
+
+               if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) {
+                       err = -EIO;
+                       goto out;
+               }
+
                hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
                        fd.entrylength);
                type = be16_to_cpu(entry.type);
index 0062dd17eb55d0f7bc365d0e06064cfb34d43449..c42791914f8205e8608923608a44fcab5478a6ea 100644 (file)
@@ -1429,7 +1429,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len)
        unsigned long hash = 0;
 
        for (;;) {
-               a = *(unsigned long *)name;
+               a = load_unaligned_zeropad(name);
                if (len < sizeof(unsigned long))
                        break;
                hash += a;
@@ -1459,7 +1459,7 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp)
        do {
                hash = (hash + a) * 9;
                len += sizeof(unsigned long);
-               a = *(unsigned long *)(name+len);
+               a = load_unaligned_zeropad(name+len);
                /* Do we have any NUL or '/' bytes in this word? */
                mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/'));
        } while (!mask);
index 9c94297bb70e9502c40825249eecb24093e142d2..7f6a23f0244e7340f2861ac6fb0d3a2d20721287 100644 (file)
@@ -38,6 +38,8 @@
 #include <linux/buffer_head.h> /* various write calls */
 #include <linux/prefetch.h>
 
+#include "../pnfs.h"
+#include "../internal.h"
 #include "blocklayout.h"
 
 #define NFSDBG_FACILITY        NFSDBG_PNFS_LD
@@ -868,7 +870,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh,
         * GETDEVICEINFO's maxcount
         */
        max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
-       max_pages = max_resp_sz >> PAGE_SHIFT;
+       max_pages = nfs_page_array_len(0, max_resp_sz);
        dprintk("%s max_resp_sz %u max_pages %d\n",
                __func__, max_resp_sz, max_pages);
 
index da7b5e4ff9ec19adc0c7e53452a87d7cd35a609b..60f7e4ec842cf1d4fd48f21862d1d5ece26efc88 100644 (file)
@@ -1729,7 +1729,8 @@ error:
  */
 struct nfs_server *nfs_clone_server(struct nfs_server *source,
                                    struct nfs_fh *fh,
-                                   struct nfs_fattr *fattr)
+                                   struct nfs_fattr *fattr,
+                                   rpc_authflavor_t flavor)
 {
        struct nfs_server *server;
        struct nfs_fattr *fattr_fsinfo;
@@ -1758,7 +1759,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 
        error = nfs_init_server_rpcclient(server,
                        source->client->cl_timeout,
-                       source->client->cl_auth->au_flavor);
+                       flavor);
        if (error < 0)
                goto out_free_server;
        if (!IS_ERR(source->client_acl))
index b7f348bb618b8d8864f7a5e2569aff8f4ef4e3a7..ba3019f5934c21a610a96569b1d239b90eca0459 100644 (file)
@@ -554,12 +554,16 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
        struct nfs_client *clp;
        int error = 0;
 
+       if (!try_module_get(THIS_MODULE))
+               return 0;
+
        while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) {
                error = __rpc_pipefs_event(clp, event, sb);
                nfs_put_client(clp);
                if (error)
                        break;
        }
+       module_put(THIS_MODULE);
        return error;
 }
 
index 2476dc69365f223d78a0b514991bcb88fa144ec9..b777bdaba4c52e72ee86a1d6c1e67ec381a37788 100644 (file)
@@ -165,7 +165,8 @@ extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
 extern void nfs_free_server(struct nfs_server *server);
 extern struct nfs_server *nfs_clone_server(struct nfs_server *,
                                           struct nfs_fh *,
-                                          struct nfs_fattr *);
+                                          struct nfs_fattr *,
+                                          rpc_authflavor_t);
 extern void nfs_mark_client_ready(struct nfs_client *clp, int state);
 extern int nfs4_check_client_ready(struct nfs_client *clp);
 extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
@@ -186,10 +187,10 @@ static inline void nfs_fs_proc_exit(void)
 
 /* nfs4namespace.c */
 #ifdef CONFIG_NFS_V4
-extern struct vfsmount *nfs_do_refmount(struct dentry *dentry);
+extern struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry);
 #else
 static inline
-struct vfsmount *nfs_do_refmount(struct dentry *dentry)
+struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
 {
        return ERR_PTR(-ENOENT);
 }
@@ -234,7 +235,6 @@ extern const u32 nfs41_maxwrite_overhead;
 /* nfs4proc.c */
 #ifdef CONFIG_NFS_V4
 extern struct rpc_procinfo nfs4_procedures[];
-void nfs_fixup_secinfo_attributes(struct nfs_fattr *, struct nfs_fh *);
 #endif
 
 extern int nfs4_init_ds_session(struct nfs_client *clp);
index 1807866bb3ab845098de2a95c695bee5460aaf37..d51868e5683c0b34530c9db38a0cd4c26277c0b8 100644 (file)
@@ -148,66 +148,31 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
        return pseudoflavor;
 }
 
-static int nfs_negotiate_security(const struct dentry *parent,
-                                 const struct dentry *dentry,
-                                 rpc_authflavor_t *flavor)
+static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
+                                             struct qstr *name,
+                                             struct nfs_fh *fh,
+                                             struct nfs_fattr *fattr)
 {
-       struct page *page;
-       struct nfs4_secinfo_flavors *flavors;
-       int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
-       int ret = -EPERM;
-
-       secinfo = NFS_PROTO(parent->d_inode)->secinfo;
-       if (secinfo != NULL) {
-               page = alloc_page(GFP_KERNEL);
-               if (!page) {
-                       ret = -ENOMEM;
-                       goto out;
-               }
-               flavors = page_address(page);
-               ret = secinfo(parent->d_inode, &dentry->d_name, flavors);
-               *flavor = nfs_find_best_sec(flavors);
-               put_page(page);
-       }
-
-out:
-       return ret;
-}
-
-static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent,
-                              struct dentry *dentry, struct path *path,
-                              struct nfs_fh *fh, struct nfs_fattr *fattr,
-                              rpc_authflavor_t *flavor)
-{
-       struct rpc_clnt *clone;
-       struct rpc_auth *auth;
        int err;
 
-       err = nfs_negotiate_security(parent, path->dentry, flavor);
-       if (err < 0)
-               goto out;
-       clone  = rpc_clone_client(server->client);
-       auth   = rpcauth_create(*flavor, clone);
-       if (!auth) {
-               err = -EIO;
-               goto out_shutdown;
-       }
-       err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode,
-                                                 &path->dentry->d_name,
-                                                 fh, fattr);
-out_shutdown:
-       rpc_shutdown_client(clone);
-out:
-       return err;
+       if (NFS_PROTO(dir)->version == 4)
+               return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr);
+
+       err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
+       if (err)
+               return ERR_PTR(err);
+       return rpc_clone_client(NFS_SERVER(dir)->client);
 }
 #else /* CONFIG_NFS_V4 */
-static inline int nfs_lookup_with_sec(struct nfs_server *server,
-                                     struct dentry *parent, struct dentry *dentry,
-                                     struct path *path, struct nfs_fh *fh,
-                                     struct nfs_fattr *fattr,
-                                     rpc_authflavor_t *flavor)
+static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir,
+                                                    struct qstr *name,
+                                                    struct nfs_fh *fh,
+                                                    struct nfs_fattr *fattr)
 {
-       return -EPERM;
+       int err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr);
+       if (err)
+               return ERR_PTR(err);
+       return rpc_clone_client(NFS_SERVER(dir)->client);
 }
 #endif /* CONFIG_NFS_V4 */
 
@@ -226,12 +191,10 @@ static inline int nfs_lookup_with_sec(struct nfs_server *server,
 struct vfsmount *nfs_d_automount(struct path *path)
 {
        struct vfsmount *mnt;
-       struct nfs_server *server = NFS_SERVER(path->dentry->d_inode);
        struct dentry *parent;
        struct nfs_fh *fh = NULL;
        struct nfs_fattr *fattr = NULL;
-       int err;
-       rpc_authflavor_t flavor = RPC_AUTH_UNIX;
+       struct rpc_clnt *client;
 
        dprintk("--> nfs_d_automount()\n");
 
@@ -249,21 +212,19 @@ struct vfsmount *nfs_d_automount(struct path *path)
 
        /* Look it up again to get its attributes */
        parent = dget_parent(path->dentry);
-       err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode,
-                                                 &path->dentry->d_name,
-                                                 fh, fattr);
-       if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL)
-               err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor);
+       client = nfs_lookup_mountpoint(parent->d_inode, &path->dentry->d_name, fh, fattr);
        dput(parent);
-       if (err != 0) {
-               mnt = ERR_PTR(err);
+       if (IS_ERR(client)) {
+               mnt = ERR_CAST(client);
                goto out;
        }
 
        if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
-               mnt = nfs_do_refmount(path->dentry);
+               mnt = nfs_do_refmount(client, path->dentry);
        else
-               mnt = nfs_do_submount(path->dentry, fh, fattr, flavor);
+               mnt = nfs_do_submount(path->dentry, fh, fattr, client->cl_auth->au_flavor);
+       rpc_shutdown_client(client);
+
        if (IS_ERR(mnt))
                goto out;
 
index b6db9e33fb7bbe7d4d97b130252312e621c85056..8d75021020b31f44f0fcb9ec6f1ff05a8b39b313 100644 (file)
@@ -205,6 +205,9 @@ struct nfs4_state_maintenance_ops {
 extern const struct dentry_operations nfs4_dentry_operations;
 extern const struct inode_operations nfs4_dir_inode_operations;
 
+/* nfs4namespace.c */
+struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
+
 /* nfs4proc.c */
 extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
 extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
@@ -213,8 +216,11 @@ extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
 extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
-extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
-               struct nfs4_fs_locations *fs_locations, struct page *page);
+extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
+                                 struct nfs4_fs_locations *, struct page *);
+extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *,
+                           struct nfs_fh *, struct nfs_fattr *);
+extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
 extern int nfs4_release_lockowner(struct nfs4_lock_state *);
 extern const struct xattr_handler *nfs4_xattr_handlers[];
 
index a866bbd2890a056b530ebe3ae91cd74b0862f4a1..c9cff9adb2d3f7c832f3e3bc7e6d76ec45a6e692 100644 (file)
@@ -699,7 +699,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla
         * GETDEVICEINFO's maxcount
         */
        max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
-       max_pages = max_resp_sz >> PAGE_SHIFT;
+       max_pages = nfs_page_array_len(0, max_resp_sz);
        dprintk("%s inode %p max_resp_sz %u max_pages %d\n",
                __func__, inode, max_resp_sz, max_pages);
 
index 9c8eca315f431199aa481c0eabc6ae3e044f8267..a7f3dedc4ec7bade9df84ed6f0fc7524507b9c21 100644 (file)
@@ -51,6 +51,30 @@ Elong:
        return ERR_PTR(-ENAMETOOLONG);
 }
 
+/*
+ * return the path component of "<server>:<path>"
+ *  nfspath - the "<server>:<path>" string
+ *  end - one past the last char that could contain "<server>:"
+ * returns NULL on failure
+ */
+static char *nfs_path_component(const char *nfspath, const char *end)
+{
+       char *p;
+
+       if (*nfspath == '[') {
+               /* parse [] escaped IPv6 addrs */
+               p = strchr(nfspath, ']');
+               if (p != NULL && ++p < end && *p == ':')
+                       return p + 1;
+       } else {
+               /* otherwise split on first colon */
+               p = strchr(nfspath, ':');
+               if (p != NULL && p < end)
+                       return p + 1;
+       }
+       return NULL;
+}
+
 /*
  * Determine the mount path as a string
  */
@@ -59,9 +83,9 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
        char *limit;
        char *path = nfs_path(&limit, dentry, buffer, buflen);
        if (!IS_ERR(path)) {
-               char *colon = strchr(path, ':');
-               if (colon && colon < limit)
-                       path = colon + 1;
+               char *path_component = nfs_path_component(path, limit);
+               if (path_component)
+                       return path_component;
        }
        return path;
 }
@@ -108,6 +132,58 @@ static size_t nfs_parse_server_name(char *string, size_t len,
        return ret;
 }
 
+static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name)
+{
+       struct page *page;
+       struct nfs4_secinfo_flavors *flavors;
+       rpc_authflavor_t flavor;
+       int err;
+
+       page = alloc_page(GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+       flavors = page_address(page);
+
+       err = nfs4_proc_secinfo(inode, name, flavors);
+       if (err < 0) {
+               flavor = err;
+               goto out;
+       }
+
+       flavor = nfs_find_best_sec(flavors);
+
+out:
+       put_page(page);
+       return flavor;
+}
+
+/*
+ * Please call rpc_shutdown_client() when you are done with this client.
+ */
+struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode,
+                                       struct qstr *name)
+{
+       struct rpc_clnt *clone;
+       struct rpc_auth *auth;
+       rpc_authflavor_t flavor;
+
+       flavor = nfs4_negotiate_security(inode, name);
+       if (flavor < 0)
+               return ERR_PTR(flavor);
+
+       clone = rpc_clone_client(clnt);
+       if (IS_ERR(clone))
+               return clone;
+
+       auth = rpcauth_create(flavor, clone);
+       if (!auth) {
+               rpc_shutdown_client(clone);
+               clone = ERR_PTR(-EIO);
+       }
+
+       return clone;
+}
+
 static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
                                     char *page, char *page2,
                                     const struct nfs4_fs_location *location)
@@ -224,7 +300,7 @@ out:
  * @dentry - dentry of referral
  *
  */
-struct vfsmount *nfs_do_refmount(struct dentry *dentry)
+struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
 {
        struct vfsmount *mnt = ERR_PTR(-ENOMEM);
        struct dentry *parent;
@@ -250,7 +326,7 @@ struct vfsmount *nfs_do_refmount(struct dentry *dentry)
        dprintk("%s: getting locations for %s/%s\n",
                __func__, parent->d_name.name, dentry->d_name.name);
 
-       err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page);
+       err = nfs4_proc_fs_locations(client, parent->d_inode, &dentry->d_name, fs_locations, page);
        dput(parent);
        if (err != 0 ||
            fs_locations->nlocations <= 0 ||
index 60d5f4c26ddaeee0e107bea081544d8c3a50d0ef..99650aaf8937a28a52f9fca9946771f61379a8c7 100644 (file)
@@ -2377,8 +2377,9 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
  * Note that we'll actually follow the referral later when
  * we detect fsid mismatch in inode revalidation
  */
-static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
-                            struct nfs_fattr *fattr, struct nfs_fh *fhandle)
+static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir,
+                            const struct qstr *name, struct nfs_fattr *fattr,
+                            struct nfs_fh *fhandle)
 {
        int status = -ENOMEM;
        struct page *page = NULL;
@@ -2391,7 +2392,7 @@ static int nfs4_get_referral(struct inode *dir, const struct qstr *name,
        if (locations == NULL)
                goto out;
 
-       status = nfs4_proc_fs_locations(dir, name, locations, page);
+       status = nfs4_proc_fs_locations(client, dir, name, locations, page);
        if (status != 0)
                goto out;
        /* Make sure server returned a different fsid for the referral */
@@ -2528,39 +2529,84 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        return status;
 }
 
-void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr, struct nfs_fh *fh)
+static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
 {
-       memset(fh, 0, sizeof(struct nfs_fh));
-       fattr->fsid.major = 1;
        fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE |
-               NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_FSID | NFS_ATTR_FATTR_MOUNTPOINT;
+               NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_MOUNTPOINT;
        fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO;
        fattr->nlink = 2;
 }
 
-static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name,
-                           struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
+                                  struct qstr *name, struct nfs_fh *fhandle,
+                                  struct nfs_fattr *fattr)
 {
        struct nfs4_exception exception = { };
+       struct rpc_clnt *client = *clnt;
        int err;
        do {
-               int status;
-
-               status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr);
-               switch (status) {
+               err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr);
+               switch (err) {
                case -NFS4ERR_BADNAME:
-                       return -ENOENT;
+                       err = -ENOENT;
+                       goto out;
                case -NFS4ERR_MOVED:
-                       return nfs4_get_referral(dir, name, fattr, fhandle);
+                       err = nfs4_get_referral(client, dir, name, fattr, fhandle);
+                       goto out;
                case -NFS4ERR_WRONGSEC:
-                       nfs_fixup_secinfo_attributes(fattr, fhandle);
+                       err = -EPERM;
+                       if (client != *clnt)
+                               goto out;
+
+                       client = nfs4_create_sec_client(client, dir, name);
+                       if (IS_ERR(client))
+                               return PTR_ERR(client);
+
+                       exception.retry = 1;
+                       break;
+               default:
+                       err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception);
                }
-               err = nfs4_handle_exception(NFS_SERVER(dir),
-                               status, &exception);
        } while (exception.retry);
+
+out:
+       if (err == 0)
+               *clnt = client;
+       else if (client != *clnt)
+               rpc_shutdown_client(client);
+
        return err;
 }
 
+static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name,
+                           struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+{
+       int status;
+       struct rpc_clnt *client = NFS_CLIENT(dir);
+
+       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr);
+       if (client != NFS_CLIENT(dir)) {
+               rpc_shutdown_client(client);
+               nfs_fixup_secinfo_attributes(fattr);
+       }
+       return status;
+}
+
+struct rpc_clnt *
+nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name,
+                           struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+{
+       int status;
+       struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir));
+
+       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr);
+       if (status < 0) {
+               rpc_shutdown_client(client);
+               return ERR_PTR(status);
+       }
+       return client;
+}
+
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
        struct nfs_server *server = NFS_SERVER(inode);
@@ -3628,16 +3674,16 @@ out:
        return ret;
 }
 
-static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len)
+static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
 {
        struct nfs4_cached_acl *acl;
 
-       if (buf && acl_len <= PAGE_SIZE) {
+       if (pages && acl_len <= PAGE_SIZE) {
                acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
                if (acl == NULL)
                        goto out;
                acl->cached = 1;
-               memcpy(acl->data, buf, acl_len);
+               _copy_from_pages(acl->data, pages, pgbase, acl_len);
        } else {
                acl = kmalloc(sizeof(*acl), GFP_KERNEL);
                if (acl == NULL)
@@ -3670,7 +3716,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
        struct nfs_getaclres res = {
                .acl_len = buflen,
        };
-       void *resp_buf;
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
                .rpc_argp = &args,
@@ -3684,24 +3729,27 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
        if (npages == 0)
                npages = 1;
 
+       /* Add an extra page to handle the bitmap returned */
+       npages++;
+
        for (i = 0; i < npages; i++) {
                pages[i] = alloc_page(GFP_KERNEL);
                if (!pages[i])
                        goto out_free;
        }
-       if (npages > 1) {
-               /* for decoding across pages */
-               res.acl_scratch = alloc_page(GFP_KERNEL);
-               if (!res.acl_scratch)
-                       goto out_free;
-       }
+
+       /* for decoding across pages */
+       res.acl_scratch = alloc_page(GFP_KERNEL);
+       if (!res.acl_scratch)
+               goto out_free;
+
        args.acl_len = npages * PAGE_SIZE;
        args.acl_pgbase = 0;
+
        /* Let decode_getfacl know not to fail if the ACL data is larger than
         * the page we send as a guess */
        if (buf == NULL)
                res.acl_flags |= NFS4_ACL_LEN_REQUEST;
-       resp_buf = page_address(pages[0]);
 
        dprintk("%s  buf %p buflen %zu npages %d args.acl_len %zu\n",
                __func__, buf, buflen, npages, args.acl_len);
@@ -3712,9 +3760,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
 
        acl_len = res.acl_len - res.acl_data_offset;
        if (acl_len > args.acl_len)
-               nfs4_write_cached_acl(inode, NULL, acl_len);
+               nfs4_write_cached_acl(inode, NULL, 0, acl_len);
        else
-               nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
+               nfs4_write_cached_acl(inode, pages, res.acl_data_offset,
                                      acl_len);
        if (buf) {
                ret = -ERANGE;
@@ -4919,8 +4967,10 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr)
        fattr->nlink = 2;
 }
 
-int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
-               struct nfs4_fs_locations *fs_locations, struct page *page)
+static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
+                                  const struct qstr *name,
+                                  struct nfs4_fs_locations *fs_locations,
+                                  struct page *page)
 {
        struct nfs_server *server = NFS_SERVER(dir);
        u32 bitmask[2] = {
@@ -4954,11 +5004,26 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
        nfs_fattr_init(&fs_locations->fattr);
        fs_locations->server = server;
        fs_locations->nlocations = 0;
-       status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
+       status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0);
        dprintk("%s: returned status = %d\n", __func__, status);
        return status;
 }
 
+int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
+                          const struct qstr *name,
+                          struct nfs4_fs_locations *fs_locations,
+                          struct page *page)
+{
+       struct nfs4_exception exception = { };
+       int err;
+       do {
+               err = nfs4_handle_exception(NFS_SERVER(dir),
+                               _nfs4_proc_fs_locations(client, dir, name, fs_locations, page),
+                               &exception);
+       } while (exception.retry);
+       return err;
+}
+
 static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors)
 {
        int status;
@@ -4981,8 +5046,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
        return status;
 }
 
-static int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
-               struct nfs4_secinfo_flavors *flavors)
+int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name,
+                     struct nfs4_secinfo_flavors *flavors)
 {
        struct nfs4_exception exception = { };
        int err;
@@ -5057,10 +5122,9 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
        nfs4_construct_boot_verifier(clp, &verifier);
 
        args.id_len = scnprintf(args.id, sizeof(args.id),
-                               "%s/%s.%s/%u",
+                               "%s/%s/%u",
                                clp->cl_ipaddr,
-                               init_utsname()->nodename,
-                               init_utsname()->domainname,
+                               clp->cl_rpcclient->cl_nodename,
                                clp->cl_rpcclient->cl_auth->au_flavor);
 
        res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL);
index 77fc5f959c4ecf4322c3846323eb3bf4cdb22081..c54aae364beebd38833151f97328c3edfe7c2337 100644 (file)
@@ -4258,8 +4258,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
        status = decode_attr_error(xdr, bitmap, &err);
        if (status < 0)
                goto xdr_error;
-       if (err == -NFS4ERR_WRONGSEC)
-               nfs_fixup_secinfo_attributes(fattr, fh);
 
        status = decode_attr_filehandle(xdr, bitmap, fh);
        if (status < 0)
@@ -4902,11 +4900,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                 bitmap[3] = {0};
        struct kvec *iov = req->rq_rcv_buf.head;
        int status;
+       size_t page_len = xdr->buf->page_len;
 
        res->acl_len = 0;
        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
                goto out;
+
        bm_p = xdr->p;
+       res->acl_data_offset = be32_to_cpup(bm_p) + 2;
+       res->acl_data_offset <<= 2;
+       /* Check if the acl data starts beyond the allocated buffer */
+       if (res->acl_data_offset > page_len)
+               return -ERANGE;
+
        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
                goto out;
        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4916,28 +4922,24 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
                return -EIO;
        if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
                size_t hdrlen;
-               u32 recvd;
 
                /* The bitmap (xdr len + bitmaps) and the attr xdr len words
                 * are stored with the acl data to handle the problem of
                 * variable length bitmaps.*/
                xdr->p = bm_p;
-               res->acl_data_offset = be32_to_cpup(bm_p) + 2;
-               res->acl_data_offset <<= 2;
 
                /* We ignore &savep and don't do consistency checks on
                 * the attr length.  Let userspace figure it out.... */
                hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
                attrlen += res->acl_data_offset;
-               recvd = req->rq_rcv_buf.len - hdrlen;
-               if (attrlen > recvd) {
+               if (attrlen > page_len) {
                        if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
                                /* getxattr interface called with a NULL buf */
                                res->acl_len = attrlen;
                                goto out;
                        }
-                       dprintk("NFS: acl reply: attrlen %u > recvd %u\n",
-                                       attrlen, recvd);
+                       dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
+                                       attrlen, page_len);
                        return -EINVAL;
                }
                xdr_read_pages(xdr, attrlen);
@@ -5090,16 +5092,13 @@ out_err:
        return -EINVAL;
 }
 
-static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
+static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
 {
        struct nfs4_secinfo_flavor *sec_flavor;
        int status;
        __be32 *p;
        int i, num_flavors;
 
-       status = decode_op_hdr(xdr, OP_SECINFO);
-       if (status)
-               goto out;
        p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                goto out_overflow;
@@ -5125,6 +5124,7 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
                res->flavors->num_flavors++;
        }
 
+       status = 0;
 out:
        return status;
 out_overflow:
@@ -5132,7 +5132,23 @@ out_overflow:
        return -EIO;
 }
 
+static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
+{
+       int status = decode_op_hdr(xdr, OP_SECINFO);
+       if (status)
+               return status;
+       return decode_secinfo_common(xdr, res);
+}
+
 #if defined(CONFIG_NFS_V4_1)
+static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
+{
+       int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME);
+       if (status)
+               return status;
+       return decode_secinfo_common(xdr, res);
+}
+
 static int decode_exchange_id(struct xdr_stream *xdr,
                              struct nfs41_exchange_id_res *res)
 {
@@ -6817,7 +6833,7 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
        status = decode_putrootfh(xdr);
        if (status)
                goto out;
-       status = decode_secinfo(xdr, res);
+       status = decode_secinfo_no_name(xdr, res);
 out:
        return status;
 }
index 8d45f1c318ce40ac453b7b4a71288e71ba3c6a34..595c5fc21a19d15efaab48bff059336d7762c1b3 100644 (file)
@@ -604,7 +604,6 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
 {
        struct objlayout_deviceinfo *odi;
        struct pnfs_device pd;
-       struct super_block *sb;
        struct page *page, **pages;
        u32 *p;
        int err;
@@ -623,7 +622,6 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay,
        pd.pglen = PAGE_SIZE;
        pd.mincount = 0;
 
-       sb = pnfslay->plh_inode->i_sb;
        err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd);
        dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err);
        if (err)
index b5d4515869436dc6bd16a483590a433ac04c665c..38512bcd2e98b4c82e3b03e2592061c06897abe5 100644 (file)
@@ -587,7 +587,7 @@ send_layoutget(struct pnfs_layout_hdr *lo,
 
        /* allocate pages for xdr post processing */
        max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
-       max_pages = max_resp_sz >> PAGE_SHIFT;
+       max_pages = nfs_page_array_len(0, max_resp_sz);
 
        pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags);
        if (!pages)
index 1e6715f0616c938c237595458124395779b5492e..4ac7fca7e4bf32fc01ac980c26dfcb255325f3b1 100644 (file)
@@ -2428,7 +2428,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags,
        dprintk("--> nfs_xdev_mount()\n");
 
        /* create a new volume representation */
-       server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+       server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
        if (IS_ERR(server)) {
                error = PTR_ERR(server);
                goto out_err_noserver;
@@ -2955,7 +2955,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
        dprintk("--> nfs4_xdev_mount()\n");
 
        /* create a new volume representation */
-       server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
+       server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
        if (IS_ERR(server)) {
                error = PTR_ERR(server);
                goto out_err_noserver;
index 4767429264a25b3e6003953c8d3f1e70627b075d..ed3f9206a0ee87c914f133492f1f6011775bdef8 100644 (file)
@@ -577,7 +577,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
        struct cld_net *cn = nn->cld_net;
 
        if (mlen != sizeof(*cmsg)) {
-               dprintk("%s: got %lu bytes, expected %lu\n", __func__, mlen,
+               dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
                        sizeof(*cmsg));
                return -EINVAL;
        }
index eba66043cf1b7d1dccfc1956446ea9bafdbb588c..e8bcc4742e0e9a1f9563a27907871ab6ce727817 100644 (file)
@@ -499,9 +499,10 @@ typedef u64 acpi_integer;
 #define ACPI_STATE_D0                   (u8) 0
 #define ACPI_STATE_D1                   (u8) 1
 #define ACPI_STATE_D2                   (u8) 2
-#define ACPI_STATE_D3                   (u8) 3
-#define ACPI_STATE_D3_COLD              (u8) 4
-#define ACPI_D_STATES_MAX               ACPI_STATE_D3_COLD
+#define ACPI_STATE_D3_HOT               (u8) 3
+#define ACPI_STATE_D3                   (u8) 4
+#define ACPI_STATE_D3_COLD              ACPI_STATE_D3
+#define ACPI_D_STATES_MAX               ACPI_STATE_D3
 #define ACPI_D_STATE_COUNT              5
 
 #define ACPI_STATE_C0                   (u8) 0
index 0fd28e028de1d83130aeb751294159dffc39fa6a..c749af9c0983022876bffacf1aea628c270d4a34 100644 (file)
@@ -15,7 +15,7 @@ typedef __kernel_fsid_t       fsid_t;
  * with a 10' pole.
  */
 #ifndef __statfs_word
-#if BITS_PER_LONG == 64
+#if __BITS_PER_LONG == 64
 #define __statfs_word long
 #else
 #define __statfs_word __u32
index 88ec80670d5ff1da744a4a5d9174fb8c6f3512da..ec45ccd8708a85f54a903d769b0b5c2fbaf8bc3f 100644 (file)
@@ -554,7 +554,18 @@ extern int __init efi_setup_pcdp_console(char *);
 #define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
 #define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
-
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020
+#define EFI_VARIABLE_APPEND_WRITE      0x0000000000000040
+
+#define EFI_VARIABLE_MASK      (EFI_VARIABLE_NON_VOLATILE | \
+                               EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+                               EFI_VARIABLE_RUNTIME_ACCESS | \
+                               EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
+                               EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
+                               EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
+                               EFI_VARIABLE_APPEND_WRITE)
 /*
  * The type of search to perform when calling boottime->locate_handle
  */
index 42378d637ffbe489c65c0220b8a3a8dc2955f6c9..e926df7b54c963745d043e1041d8876a5a7c65e6 100644 (file)
@@ -996,7 +996,8 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
 extern void ata_sas_port_destroy(struct ata_port *);
 extern struct ata_port *ata_sas_port_alloc(struct ata_host *,
                                           struct ata_port_info *, struct Scsi_Host *);
-extern int ata_sas_async_port_init(struct ata_port *);
+extern void ata_sas_async_probe(struct ata_port *ap);
+extern int ata_sas_sync_probe(struct ata_port *ap);
 extern int ata_sas_port_init(struct ata_port *);
 extern int ata_sas_port_start(struct ata_port *ap);
 extern void ata_sas_port_stop(struct ata_port *ap);
index 0ddd161f3b060c2e2ec0d665c1ddc719213443f7..31d2844e6572be34ed104e1a92fafd48abc0bf76 100644 (file)
@@ -104,9 +104,18 @@ struct bridge_skb_cb {
        } daddr;
 };
 
+static inline void br_drop_fake_rtable(struct sk_buff *skb)
+{
+       struct dst_entry *dst = skb_dst(skb);
+
+       if (dst && (dst->flags & DST_FAKE_RTABLE))
+               skb_dst_drop(skb);
+}
+
 #else
 #define nf_bridge_maybe_copy_header(skb)       (0)
 #define nf_bridge_pad(skb)                     (0)
+#define br_drop_fake_rtable(skb)               do { } while (0)
 #endif /* CONFIG_BRIDGE_NETFILTER */
 
 #endif /* __KERNEL__ */
index c6db9fb33c448f28197ffb6d135689daf58625b6..600060e25ec6cb644fd4141f48e2493490305c8a 100644 (file)
@@ -141,7 +141,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s)
        unsigned ret;
 
 repeat:
-       ret = s->sequence;
+       ret = ACCESS_ONCE(s->sequence);
        if (unlikely(ret & 1)) {
                cpu_relax();
                goto repeat;
@@ -165,6 +165,27 @@ static inline unsigned read_seqcount_begin(const seqcount_t *s)
        return ret;
 }
 
+/**
+ * raw_seqcount_begin - begin a seq-read critical section
+ * @s: pointer to seqcount_t
+ * Returns: count to be passed to read_seqcount_retry
+ *
+ * raw_seqcount_begin opens a read critical section of the given seqcount.
+ * Validity of the critical section is tested by checking read_seqcount_retry
+ * function.
+ *
+ * Unlike read_seqcount_begin(), this function will not wait for the count
+ * to stabilize. If a writer is active when we begin, we will fail the
+ * read_seqcount_retry() instead of stabilizing at the beginning of the
+ * critical section.
+ */
+static inline unsigned raw_seqcount_begin(const seqcount_t *s)
+{
+       unsigned ret = ACCESS_ONCE(s->sequence);
+       smp_rmb();
+       return ret & ~1;
+}
+
 /**
  * __read_seqcount_retry - end a seq-read critical section (without barrier)
  * @s: pointer to seqcount_t
index 775292a66fa4d84615e2b3d3d15c84913cc7813b..111f26b6e28b992bbebbe645819712bf8c07ab63 100644 (file)
@@ -1020,7 +1020,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list,
 }
 
 /**
- *     skb_queue_splice - join two skb lists and reinitialise the emptied list
+ *     skb_queue_splice_init - join two skb lists and reinitialise the emptied list
  *     @list: the new list to add
  *     @head: the place to add it in the first list
  *
@@ -1051,7 +1051,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list,
 }
 
 /**
- *     skb_queue_splice_tail - join two skb lists and reinitialise the emptied list
+ *     skb_queue_splice_tail_init - join two skb lists and reinitialise the emptied list
  *     @list: the new list to add
  *     @head: the place to add it in the first list
  *
index 6822d2595aff983451b5c01b6286162635f25d9b..db1c5df45224d1635d7de925c51e5cb585e5346a 100644 (file)
@@ -314,6 +314,7 @@ struct hci_conn {
 
        __u8            remote_cap;
        __u8            remote_auth;
+       bool            flush_key;
 
        unsigned int    sent;
 
@@ -980,7 +981,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
 int mgmt_connectable(struct hci_dev *hdev, u8 connectable);
 int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
 int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
-                     u8 persistent);
+                     bool persistent);
 int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
                          u8 addr_type, u32 flags, u8 *name, u8 name_len,
                          u8 *dev_class);
index ff4da42fcfc6e1440e5bc5aca3ffffdb376d2a18..bed833d9796aed86bac5ca7d45ad53cde3447e52 100644 (file)
@@ -59,6 +59,7 @@ struct dst_entry {
 #define DST_NOCACHE            0x0010
 #define DST_NOCOUNT            0x0020
 #define DST_NOPEER             0x0040
+#define DST_FAKE_RTABLE                0x0080
 
        short                   error;
        short                   obsolete;
index 2bdee51ba30d29f1ccd296fdbdcd06a709a5b4c4..72522f0873757ae08507671667cc7bc7cc849110 100644 (file)
@@ -393,7 +393,7 @@ struct ip_vs_protocol {
 
        void (*exit)(struct ip_vs_protocol *pp);
 
-       void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
+       int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
        void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
@@ -1203,6 +1203,8 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol,
 
 extern int ip_vs_use_count_inc(void);
 extern void ip_vs_use_count_dec(void);
+extern int ip_vs_register_nl_ioctl(void);
+extern void ip_vs_unregister_nl_ioctl(void);
 extern int ip_vs_control_init(void);
 extern void ip_vs_control_cleanup(void);
 extern struct ip_vs_dest *
index 188532ee88b66649837b0a9771f2dc3f2b4a3b00..5a0a58ac4126c47517ea5a4da0fdb051cc88daba 100644 (file)
@@ -1129,9 +1129,9 @@ sk_sockets_allocated_read_positive(struct sock *sk)
        struct proto *prot = sk->sk_prot;
 
        if (mem_cgroup_sockets_enabled && sk->sk_cgrp)
-               return percpu_counter_sum_positive(sk->sk_cgrp->sockets_allocated);
+               return percpu_counter_read_positive(sk->sk_cgrp->sockets_allocated);
 
-       return percpu_counter_sum_positive(prot->sockets_allocated);
+       return percpu_counter_read_positive(prot->sockets_allocated);
 }
 
 static inline int
index 5f5ed1b8b41bb7d28886895e7742cb80e16f6a8b..f4f1c96dca726ff2f00211994dcf7381ef55b5b0 100644 (file)
@@ -217,11 +217,29 @@ struct domain_device {
        struct kref kref;
 };
 
-struct sas_discovery_event {
+struct sas_work {
+       struct list_head drain_node;
        struct work_struct work;
+};
+
+static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *))
+{
+       INIT_WORK(&sw->work, fn);
+       INIT_LIST_HEAD(&sw->drain_node);
+}
+
+struct sas_discovery_event {
+       struct sas_work work;
        struct asd_sas_port *port;
 };
 
+static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work)
+{
+       struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work);
+
+       return ev;
+}
+
 struct sas_discovery {
        struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
        unsigned long    pending;
@@ -244,7 +262,7 @@ struct asd_sas_port {
        struct list_head destroy_list;
        enum   sas_linkrate linkrate;
 
-       struct work_struct work;
+       struct sas_work work;
 
 /* public: */
        int id;
@@ -270,10 +288,17 @@ struct asd_sas_port {
 };
 
 struct asd_sas_event {
-       struct work_struct work;
+       struct sas_work work;
        struct asd_sas_phy *phy;
 };
 
+static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work)
+{
+       struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work);
+
+       return ev;
+}
+
 /* The phy pretty much is controlled by the LLDD.
  * The class only reads those fields.
  */
@@ -333,10 +358,17 @@ struct scsi_core {
 };
 
 struct sas_ha_event {
-       struct work_struct work;
+       struct sas_work work;
        struct sas_ha_struct *ha;
 };
 
+static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work)
+{
+       struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work);
+
+       return ev;
+}
+
 enum sas_ha_state {
        SAS_HA_REGISTERED,
        SAS_HA_DRAINING,
index cdccd2eb7b6cd759003ecd11903d397a166bc87a..77670e823ed8e7926c617c6a736f6c427f3b437e 100644 (file)
@@ -37,7 +37,7 @@ static inline int dev_is_sata(struct domain_device *dev)
 }
 
 int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
-int sas_ata_init_host_and_port(struct domain_device *found_dev);
+int sas_ata_init(struct domain_device *dev);
 void sas_ata_task_abort(struct sas_task *task);
 void sas_ata_strategy_handler(struct Scsi_Host *shost);
 void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q,
@@ -52,7 +52,7 @@ static inline int dev_is_sata(struct domain_device *dev)
 {
        return 0;
 }
-static inline int sas_ata_init_host_and_port(struct domain_device *found_dev)
+static inline int sas_ata_init(struct domain_device *dev)
 {
        return 0;
 }
index 0e93f92a0345a09a2aa84608a3bca34153a2eabb..42b0707c348108b98f6ce05ae1a98ad4f64a0e86 100644 (file)
@@ -472,7 +472,7 @@ void __init change_floppy(char *fmt, ...)
 void __init mount_root(void)
 {
 #ifdef CONFIG_ROOT_NFS
-       if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
+       if (ROOT_DEV == Root_NFS) {
                if (mount_nfs_root())
                        return;
 
index 92a857e3786d173273986ba179f7e9bac1856af7..edfd61addceca4b269891734646fedbe6fbe8606 100644 (file)
@@ -1215,40 +1215,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
        return NULL;
 }
 
-static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
+static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
                                                u8 key_type, u8 old_key_type)
 {
        /* Legacy key */
        if (key_type < 0x03)
-               return 1;
+               return true;
 
        /* Debug keys are insecure so don't store them persistently */
        if (key_type == HCI_LK_DEBUG_COMBINATION)
-               return 0;
+               return false;
 
        /* Changed combination key and there's no previous one */
        if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
-               return 0;
+               return false;
 
        /* Security mode 3 case */
        if (!conn)
-               return 1;
+               return true;
 
        /* Neither local nor remote side had no-bonding as requirement */
        if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
-               return 1;
+               return true;
 
        /* Local side had dedicated bonding as requirement */
        if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
-               return 1;
+               return true;
 
        /* Remote side had dedicated bonding as requirement */
        if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
-               return 1;
+               return true;
 
        /* If none of the above criteria match, then don't store the key
         * persistently */
-       return 0;
+       return false;
 }
 
 struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8])
@@ -1285,7 +1285,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
                     bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
 {
        struct link_key *key, *old_key;
-       u8 old_key_type, persistent;
+       u8 old_key_type;
+       bool persistent;
 
        old_key = hci_find_link_key(hdev, bdaddr);
        if (old_key) {
@@ -1328,10 +1329,8 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 
        mgmt_new_link_key(hdev, key, persistent);
 
-       if (!persistent) {
-               list_del(&key->list);
-               kfree(key);
-       }
+       if (conn)
+               conn->flush_key = !persistent;
 
        return 0;
 }
index b37531094c4999a6b9224056e4d5f283a9bdcece..6c065254afc03dcfbd11bad037791561b7f99f45 100644 (file)
@@ -1901,6 +1901,8 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff
        }
 
        if (ev->status == 0) {
+               if (conn->type == ACL_LINK && conn->flush_key)
+                       hci_remove_link_key(hdev, &conn->dst);
                hci_proto_disconn_cfm(conn, ev->reason);
                hci_conn_del(conn);
        }
@@ -2311,6 +2313,7 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 
        case HCI_OP_USER_PASSKEY_NEG_REPLY:
                hci_cc_user_passkey_neg_reply(hdev, skb);
+               break;
 
        case HCI_OP_LE_SET_SCAN_PARAM:
                hci_cc_le_set_scan_param(hdev, skb);
index 4ef275c69675ab116897da18663626a53ab6c6fe..4bb03b111122ca6c911ee1c7e74fbd8c03f22d30 100644 (file)
@@ -2884,7 +2884,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status)
        return 0;
 }
 
-int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent)
+int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent)
 {
        struct mgmt_ev_new_link_key ev;
 
index 61f65344e711fc4b87856889c8d83e89d0d911d6..a2098e3de500d4ab34c3d3b14435eddb5089b354 100644 (file)
@@ -47,6 +47,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
                kfree_skb(skb);
        } else {
                skb_push(skb, ETH_HLEN);
+               br_drop_fake_rtable(skb);
                dev_queue_xmit(skb);
        }
 
index dec4f3817133c879b524a65f0919b5dabcff46ea..d7f49b63ab0fd17b82828f60278b5f8a99664a1d 100644 (file)
@@ -156,7 +156,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
        rt->dst.dev = br->dev;
        rt->dst.path = &rt->dst;
        dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
-       rt->dst.flags   = DST_NOXFRM | DST_NOPEER;
+       rt->dst.flags   = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE;
        rt->dst.ops = &fake_dst_ops;
 }
 
@@ -694,11 +694,7 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
                                   const struct net_device *out,
                                   int (*okfn)(struct sk_buff *))
 {
-       struct rtable *rt = skb_rtable(skb);
-
-       if (rt && rt == bridge_parent_rtable(in))
-               skb_dst_drop(skb);
-
+       br_drop_fake_rtable(skb);
        return NF_ACCEPT;
 }
 
index 5c3c81a609e5d5b600a9491679e1f4843ec69df5..a7cad741df012a2b7790246d6c2d569bac38bda4 100644 (file)
@@ -42,13 +42,14 @@ static void send_dm_alert(struct work_struct *unused);
  * netlink alerts
  */
 static int trace_state = TRACE_OFF;
-static DEFINE_SPINLOCK(trace_state_lock);
+static DEFINE_MUTEX(trace_state_mutex);
 
 struct per_cpu_dm_data {
        struct work_struct dm_alert_work;
-       struct sk_buff *skb;
+       struct sk_buff __rcu *skb;
        atomic_t dm_hit_count;
        struct timer_list send_timer;
+       int cpu;
 };
 
 struct dm_hw_stat_delta {
@@ -79,29 +80,53 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data)
        size_t al;
        struct net_dm_alert_msg *msg;
        struct nlattr *nla;
+       struct sk_buff *skb;
+       struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1);
 
        al = sizeof(struct net_dm_alert_msg);
        al += dm_hit_limit * sizeof(struct net_dm_drop_point);
        al += sizeof(struct nlattr);
 
-       data->skb = genlmsg_new(al, GFP_KERNEL);
-       genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
-                       0, NET_DM_CMD_ALERT);
-       nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
-       msg = nla_data(nla);
-       memset(msg, 0, al);
-       atomic_set(&data->dm_hit_count, dm_hit_limit);
+       skb = genlmsg_new(al, GFP_KERNEL);
+
+       if (skb) {
+               genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
+                               0, NET_DM_CMD_ALERT);
+               nla = nla_reserve(skb, NLA_UNSPEC,
+                                 sizeof(struct net_dm_alert_msg));
+               msg = nla_data(nla);
+               memset(msg, 0, al);
+       } else
+               schedule_work_on(data->cpu, &data->dm_alert_work);
+
+       /*
+        * Don't need to lock this, since we are guaranteed to only
+        * run this on a single cpu at a time.
+        * Note also that we only update data->skb if the old and new skb
+        * pointers don't match.  This ensures that we don't continually call
+        * synchornize_rcu if we repeatedly fail to alloc a new netlink message.
+        */
+       if (skb != oskb) {
+               rcu_assign_pointer(data->skb, skb);
+
+               synchronize_rcu();
+
+               atomic_set(&data->dm_hit_count, dm_hit_limit);
+       }
+
 }
 
 static void send_dm_alert(struct work_struct *unused)
 {
        struct sk_buff *skb;
-       struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
+       struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
+
+       WARN_ON_ONCE(data->cpu != smp_processor_id());
 
        /*
         * Grab the skb we're about to send
         */
-       skb = data->skb;
+       skb = rcu_dereference_protected(data->skb, 1);
 
        /*
         * Replace it with a new one
@@ -111,8 +136,10 @@ static void send_dm_alert(struct work_struct *unused)
        /*
         * Ship it!
         */
-       genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL);
+       if (skb)
+               genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL);
 
+       put_cpu_var(dm_cpu_data);
 }
 
 /*
@@ -123,9 +150,11 @@ static void send_dm_alert(struct work_struct *unused)
  */
 static void sched_send_work(unsigned long unused)
 {
-       struct per_cpu_dm_data *data =  &__get_cpu_var(dm_cpu_data);
+       struct per_cpu_dm_data *data =  &get_cpu_var(dm_cpu_data);
+
+       schedule_work_on(smp_processor_id(), &data->dm_alert_work);
 
-       schedule_work(&data->dm_alert_work);
+       put_cpu_var(dm_cpu_data);
 }
 
 static void trace_drop_common(struct sk_buff *skb, void *location)
@@ -134,8 +163,15 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        struct nlmsghdr *nlh;
        struct nlattr *nla;
        int i;
-       struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
+       struct sk_buff *dskb;
+       struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data);
+
+
+       rcu_read_lock();
+       dskb = rcu_dereference(data->skb);
 
+       if (!dskb)
+               goto out;
 
        if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) {
                /*
@@ -144,7 +180,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
                goto out;
        }
 
-       nlh = (struct nlmsghdr *)data->skb->data;
+       nlh = (struct nlmsghdr *)dskb->data;
        nla = genlmsg_data(nlmsg_data(nlh));
        msg = nla_data(nla);
        for (i = 0; i < msg->entries; i++) {
@@ -158,7 +194,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        /*
         * We need to create a new entry
         */
-       __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
+       __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point));
        nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
        memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
        msg->points[msg->entries].count = 1;
@@ -170,6 +206,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location)
        }
 
 out:
+       rcu_read_unlock();
+       put_cpu_var(dm_cpu_data);
        return;
 }
 
@@ -214,7 +252,7 @@ static int set_all_monitor_traces(int state)
        struct dm_hw_stat_delta *new_stat = NULL;
        struct dm_hw_stat_delta *temp;
 
-       spin_lock(&trace_state_lock);
+       mutex_lock(&trace_state_mutex);
 
        if (state == trace_state) {
                rc = -EAGAIN;
@@ -253,7 +291,7 @@ static int set_all_monitor_traces(int state)
                rc = -EINPROGRESS;
 
 out_unlock:
-       spin_unlock(&trace_state_lock);
+       mutex_unlock(&trace_state_mutex);
 
        return rc;
 }
@@ -296,12 +334,12 @@ static int dropmon_net_event(struct notifier_block *ev_block,
 
                new_stat->dev = dev;
                new_stat->last_rx = jiffies;
-               spin_lock(&trace_state_lock);
+               mutex_lock(&trace_state_mutex);
                list_add_rcu(&new_stat->list, &hw_stats_list);
-               spin_unlock(&trace_state_lock);
+               mutex_unlock(&trace_state_mutex);
                break;
        case NETDEV_UNREGISTER:
-               spin_lock(&trace_state_lock);
+               mutex_lock(&trace_state_mutex);
                list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
                        if (new_stat->dev == dev) {
                                new_stat->dev = NULL;
@@ -312,7 +350,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
                                }
                        }
                }
-               spin_unlock(&trace_state_lock);
+               mutex_unlock(&trace_state_mutex);
                break;
        }
 out:
@@ -368,13 +406,15 @@ static int __init init_net_drop_monitor(void)
 
        for_each_present_cpu(cpu) {
                data = &per_cpu(dm_cpu_data, cpu);
-               reset_per_cpu_data(data);
+               data->cpu = cpu;
                INIT_WORK(&data->dm_alert_work, send_dm_alert);
                init_timer(&data->send_timer);
                data->send_timer.data = cpu;
                data->send_timer.function = sched_send_work;
+               reset_per_cpu_data(data);
        }
 
+
        goto out;
 
 out_unreg:
index 36851588536861bb5fe67f61c69829807e599fb4..840821b90bcd7e11c79c14dd44bcc02aedcedf23 100644 (file)
@@ -1044,6 +1044,24 @@ static void lowpan_dev_free(struct net_device *dev)
        free_netdev(dev);
 }
 
+static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_phy(real_dev);
+}
+
+static u16 lowpan_get_pan_id(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev);
+}
+
+static u16 lowpan_get_short_addr(const struct net_device *dev)
+{
+       struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+       return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev);
+}
+
 static struct header_ops lowpan_header_ops = {
        .create = lowpan_header_create,
 };
@@ -1053,6 +1071,12 @@ static const struct net_device_ops lowpan_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
 };
 
+static struct ieee802154_mlme_ops lowpan_mlme = {
+       .get_pan_id = lowpan_get_pan_id,
+       .get_phy = lowpan_get_phy,
+       .get_short_addr = lowpan_get_short_addr,
+};
+
 static void lowpan_setup(struct net_device *dev)
 {
        pr_debug("(%s)\n", __func__);
@@ -1070,6 +1094,7 @@ static void lowpan_setup(struct net_device *dev)
 
        dev->netdev_ops         = &lowpan_netdev_ops;
        dev->header_ops         = &lowpan_header_ops;
+       dev->ml_priv            = &lowpan_mlme;
        dev->destructor         = lowpan_dev_free;
 }
 
@@ -1143,6 +1168,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
        list_add_tail(&entry->list, &lowpan_devices);
        mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);
 
+       spin_lock_init(&flist_lock);
+
        register_netdevice(dev);
 
        return 0;
@@ -1152,11 +1179,20 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)
 {
        struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev);
        struct net_device *real_dev = lowpan_dev->real_dev;
-       struct lowpan_dev_record *entry;
-       struct lowpan_dev_record *tmp;
+       struct lowpan_dev_record *entry, *tmp;
+       struct lowpan_fragment *frame, *tframe;
 
        ASSERT_RTNL();
 
+       spin_lock(&flist_lock);
+       list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) {
+               del_timer(&frame->timer);
+               list_del(&frame->list);
+               dev_kfree_skb(frame->skb);
+               kfree(frame);
+       }
+       spin_unlock(&flist_lock);
+
        mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
        list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) {
                if (entry->ldev == dev) {
index 8d25a1c557eb50f012761227634d0ae7155c7180..8f8db724bfafe5f744a8f956dc7e710a67dc7faa 100644 (file)
@@ -141,7 +141,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
                        goto rtattr_failure;
 
        if (icsk == NULL) {
-               r->idiag_rqueue = r->idiag_wqueue = 0;
+               handler->idiag_get_info(sk, r, NULL);
                goto out;
        }
 
index 8bb6adeb62c0eb7dcba14841a1f08375cfde6304..1272a88c2a6331bb749d3a016710de649c1de057 100644 (file)
@@ -3243,7 +3243,7 @@ void __init tcp_init(void)
 {
        struct sk_buff *skb = NULL;
        unsigned long limit;
-       int max_share, cnt;
+       int max_rshare, max_wshare, cnt;
        unsigned int i;
        unsigned long jiffy = jiffies;
 
@@ -3303,15 +3303,16 @@ void __init tcp_init(void)
        tcp_init_mem(&init_net);
        /* Set per-socket limits to no more than 1/128 the pressure threshold */
        limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
-       max_share = min(4UL*1024*1024, limit);
+       max_wshare = min(4UL*1024*1024, limit);
+       max_rshare = min(6UL*1024*1024, limit);
 
        sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_wmem[1] = 16*1024;
-       sysctl_tcp_wmem[2] = max(64*1024, max_share);
+       sysctl_tcp_wmem[2] = max(64*1024, max_wshare);
 
        sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_rmem[1] = 87380;
-       sysctl_tcp_rmem[2] = max(87380, max_share);
+       sysctl_tcp_rmem[2] = max(87380, max_rshare);
 
        pr_info("Hash tables configured (established %u bind %u)\n",
                tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size);
index 3ff3640653762786de25c528f18180e8937838ae..257b61789eeba9fd064470c91e3a8bffb8d1812d 100644 (file)
@@ -85,7 +85,7 @@ int sysctl_tcp_ecn __read_mostly = 2;
 EXPORT_SYMBOL(sysctl_tcp_ecn);
 int sysctl_tcp_dsack __read_mostly = 1;
 int sysctl_tcp_app_win __read_mostly = 31;
-int sysctl_tcp_adv_win_scale __read_mostly = 2;
+int sysctl_tcp_adv_win_scale __read_mostly = 1;
 EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
 
 int sysctl_tcp_stdurg __read_mostly;
@@ -495,7 +495,7 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
                goto new_measure;
        if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
                return;
-       tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1);
+       tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_rtt_est.time, 1);
 
 new_measure:
        tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd;
@@ -2868,11 +2868,14 @@ static inline void tcp_complete_cwr(struct sock *sk)
 
        /* Do not moderate cwnd if it's already undone in cwr or recovery. */
        if (tp->undo_marker) {
-               if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR)
+               if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) {
                        tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
-               else /* PRR */
+                       tp->snd_cwnd_stamp = tcp_time_stamp;
+               } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) {
+                       /* PRR algorithm. */
                        tp->snd_cwnd = tp->snd_ssthresh;
-               tp->snd_cwnd_stamp = tcp_time_stamp;
+                       tp->snd_cwnd_stamp = tcp_time_stamp;
+               }
        }
        tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR);
 }
index 8a949f19deb6dc93542396138004a5a6b2bfeeab..a7f86a3cd5023e2a7489167fcdd84df0d75a26a0 100644 (file)
@@ -146,9 +146,17 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh,
        return udp_dump_one(&udp_table, in_skb, nlh, req);
 }
 
+static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r,
+               void *info)
+{
+       r->idiag_rqueue = sk_rmem_alloc_get(sk);
+       r->idiag_wqueue = sk_wmem_alloc_get(sk);
+}
+
 static const struct inet_diag_handler udp_diag_handler = {
        .dump            = udp_diag_dump,
        .dump_one        = udp_diag_dump_one,
+       .idiag_get_info  = udp_diag_get_info,
        .idiag_type      = IPPROTO_UDP,
 };
 
@@ -167,6 +175,7 @@ static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *
 static const struct inet_diag_handler udplite_diag_handler = {
        .dump            = udplite_diag_dump,
        .dump_one        = udplite_diag_dump_one,
+       .idiag_get_info  = udp_diag_get_info,
        .idiag_type      = IPPROTO_UDPLITE,
 };
 
index 585d93ecee2daad47505863f2ff84ae04248286f..6274f0be82b0c3445f6288f7fb8c7612d5325d69 100644 (file)
@@ -442,8 +442,9 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
 
                daddr = lip->l2tp_addr.s_addr;
        } else {
+               rc = -EDESTADDRREQ;
                if (sk->sk_state != TCP_ESTABLISHED)
-                       return -EDESTADDRREQ;
+                       goto out;
 
                daddr = inet->inet_daddr;
                connected = 1;
index d9798a307f20dabdeea69179e76008bccf144673..db8fae51714c54f35310777bb61a7052fa532297 100644 (file)
@@ -1210,7 +1210,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
                                  struct sk_buff *skb);
 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
-void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
 
 /* IBSS code */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
index 401c01f0731e996e5c22435f0066b53c97529559..c20051b7ffcd8518e6dd8e01c042b3fbf6981677 100644 (file)
@@ -486,6 +486,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                /* free all potentially still buffered bcast frames */
                local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf);
                skb_queue_purge(&sdata->u.ap.ps_bc_buf);
+       } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+               ieee80211_mgd_stop(sdata);
        }
 
        if (going_down)
@@ -644,8 +646,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
                mesh_rmc_free(sdata);
-       else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-               ieee80211_mgd_teardown(sdata);
 
        flushed = sta_info_flush(local, sdata);
        WARN_ON(flushed);
index f76da5b3f5c5864f0b649187fca47517d244ce77..20c680bfc3ae0fd52f502c9c920a0ea4c0f20f86 100644 (file)
@@ -3497,7 +3497,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
        return 0;
 }
 
-void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata)
+void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
index 782a60198df46977754c8720f101ed8016b928e5..e76facc69e952c9aedb835bbfeedbb7fbea0d5ea 100644 (file)
@@ -1158,7 +1158,8 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
                tx->sta = rcu_dereference(sdata->u.vlan.sta);
                if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
                        return TX_DROP;
-       } else if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+       } else if (info->flags & IEEE80211_TX_CTL_INJECTED ||
+                  tx->sdata->control_port_protocol == tx->skb->protocol) {
                tx->sta = sta_info_get_bss(sdata, hdr->addr1);
        }
        if (!tx->sta)
index 2555816e778827250e5aec0d33eaa2fa9512addc..00bdb1d9d690b5acb100fe38c2e455a110d8f09b 100644 (file)
@@ -1924,6 +1924,7 @@ protocol_fail:
 control_fail:
        ip_vs_estimator_net_cleanup(net);
 estimator_fail:
+       net->ipvs = NULL;
        return -ENOMEM;
 }
 
@@ -1936,6 +1937,7 @@ static void __net_exit __ip_vs_cleanup(struct net *net)
        ip_vs_control_net_cleanup(net);
        ip_vs_estimator_net_cleanup(net);
        IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
+       net->ipvs = NULL;
 }
 
 static void __net_exit __ip_vs_dev_cleanup(struct net *net)
@@ -1993,10 +1995,18 @@ static int __init ip_vs_init(void)
                goto cleanup_dev;
        }
 
+       ret = ip_vs_register_nl_ioctl();
+       if (ret < 0) {
+               pr_err("can't register netlink/ioctl.\n");
+               goto cleanup_hooks;
+       }
+
        pr_info("ipvs loaded.\n");
 
        return ret;
 
+cleanup_hooks:
+       nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
 cleanup_dev:
        unregister_pernet_device(&ipvs_core_dev_ops);
 cleanup_sub:
@@ -2012,6 +2022,7 @@ exit:
 
 static void __exit ip_vs_cleanup(void)
 {
+       ip_vs_unregister_nl_ioctl();
        nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
        unregister_pernet_device(&ipvs_core_dev_ops);
        unregister_pernet_subsys(&ipvs_core_ops);       /* free ip_vs struct */
index b3afe189af61880464ef6562c568016509957293..f5589987fc80d59a8d1fc5ec1e546d72562521fa 100644 (file)
@@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
        return 0;
 }
 
-void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
+void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -3692,7 +3692,7 @@ void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net)
 #else
 
 int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; }
-void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { }
+void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { }
 
 #endif
 
@@ -3750,21 +3750,10 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
        free_percpu(ipvs->tot_stats.cpustats);
 }
 
-int __init ip_vs_control_init(void)
+int __init ip_vs_register_nl_ioctl(void)
 {
-       int idx;
        int ret;
 
-       EnterFunction(2);
-
-       /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
-       for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++)  {
-               INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
-               INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
-       }
-
-       smp_wmb();      /* Do we really need it now ? */
-
        ret = nf_register_sockopt(&ip_vs_sockopts);
        if (ret) {
                pr_err("cannot register sockopt.\n");
@@ -3776,28 +3765,47 @@ int __init ip_vs_control_init(void)
                pr_err("cannot register Generic Netlink interface.\n");
                goto err_genl;
        }
-
-       ret = register_netdevice_notifier(&ip_vs_dst_notifier);
-       if (ret < 0)
-               goto err_notf;
-
-       LeaveFunction(2);
        return 0;
 
-err_notf:
-       ip_vs_genl_unregister();
 err_genl:
        nf_unregister_sockopt(&ip_vs_sockopts);
 err_sock:
        return ret;
 }
 
+void ip_vs_unregister_nl_ioctl(void)
+{
+       ip_vs_genl_unregister();
+       nf_unregister_sockopt(&ip_vs_sockopts);
+}
+
+int __init ip_vs_control_init(void)
+{
+       int idx;
+       int ret;
+
+       EnterFunction(2);
+
+       /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */
+       for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
+               INIT_LIST_HEAD(&ip_vs_svc_table[idx]);
+               INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]);
+       }
+
+       smp_wmb();      /* Do we really need it now ? */
+
+       ret = register_netdevice_notifier(&ip_vs_dst_notifier);
+       if (ret < 0)
+               return ret;
+
+       LeaveFunction(2);
+       return 0;
+}
+
 
 void ip_vs_control_cleanup(void)
 {
        EnterFunction(2);
        unregister_netdevice_notifier(&ip_vs_dst_notifier);
-       ip_vs_genl_unregister();
-       nf_unregister_sockopt(&ip_vs_sockopts);
        LeaveFunction(2);
 }
index 538d74ee4f68bc18e7bb379d7432388aba305425..e39f693dd3e49b9595ced939bd0531c07acdd159 100644 (file)
@@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
        struct ip_vs_app *app;
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
        app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
        if (!app)
                return -ENOMEM;
index 0f16283fd05854fccc68fad349c7f29509926252..caa43704e55ead5f5c6c2287e78c818cacb038e4 100644 (file)
@@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),
index eec797f8cce705a1676caeb3c3078053ddcdf523..548bf37aa29e07ebd53eaa760dbcadf844edfa13 100644 (file)
@@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return -ENOENT;
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),
index f843a88332509edc9ac7ed509cba6d679685664f..ed835e67a07e07598408b130f64fbafd85a33679 100644 (file)
@@ -59,9 +59,6 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
        return 0;
 }
 
-#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \
-    defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \
-    defined(CONFIG_IP_VS_PROTO_ESP)
 /*
  *     register an ipvs protocols netns related data
  */
@@ -81,12 +78,18 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
        ipvs->proto_data_table[hash] = pd;
        atomic_set(&pd->appcnt, 0);     /* Init app counter */
 
-       if (pp->init_netns != NULL)
-               pp->init_netns(net, pd);
+       if (pp->init_netns != NULL) {
+               int ret = pp->init_netns(net, pd);
+               if (ret) {
+                       /* unlink an free proto data */
+                       ipvs->proto_data_table[hash] = pd->next;
+                       kfree(pd);
+                       return ret;
+               }
+       }
 
        return 0;
 }
-#endif
 
 /*
  *     unregister an ipvs protocol
@@ -316,22 +319,35 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
  */
 int __net_init ip_vs_protocol_net_init(struct net *net)
 {
+       int i, ret;
+       static struct ip_vs_protocol *protos[] = {
 #ifdef CONFIG_IP_VS_PROTO_TCP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp);
+        &ip_vs_protocol_tcp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_UDP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_udp);
+       &ip_vs_protocol_udp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_SCTP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp);
+       &ip_vs_protocol_sctp,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_AH
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_ah);
+       &ip_vs_protocol_ah,
 #endif
 #ifdef CONFIG_IP_VS_PROTO_ESP
-       register_ip_vs_proto_netns(net, &ip_vs_protocol_esp);
+       &ip_vs_protocol_esp,
 #endif
+       };
+
+       for (i = 0; i < ARRAY_SIZE(protos); i++) {
+               ret = register_ip_vs_proto_netns(net, protos[i]);
+               if (ret < 0)
+                       goto cleanup;
+       }
        return 0;
+
+cleanup:
+       ip_vs_protocol_net_cleanup(net);
+       return ret;
 }
 
 void __net_exit ip_vs_protocol_net_cleanup(struct net *net)
index 1fbf7a2816f5ade317a747737840588d41621bf0..9f3fb751c49154bac37fa4baa84853a2c0dd0c06 100644 (file)
@@ -1090,7 +1090,7 @@ out:
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->sctp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
                                                        sizeof(sctp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
+       return 0;
 }
 
 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
index ef8641f7af8300efae329a3a74cb4325eba1761f..cd609cc62721095baf50475d14e80384089f280a 100644 (file)
@@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp)
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->tcp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
                                                        sizeof(tcp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
        pd->tcp_state_table =  tcp_states;
+       return 0;
 }
 
 static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
index f4b7262896bbd272fb8d3cff5298455b1deff703..2fedb2dcb3d1f5e831546b59480eceee14e59a84 100644 (file)
@@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
        cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
 }
 
-static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __udp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
        spin_lock_init(&ipvs->udp_app_lock);
        pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts,
                                                        sizeof(udp_timeouts));
+       if (!pd->timeout_table)
+               return -ENOMEM;
+       return 0;
 }
 
 static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd)
index 59530e93fa58f7abdaa4a0734ad2fd1e5241c040..3746d8b9a47868694be0848fc0d09013a0a5b282 100644 (file)
@@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
        }
 
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
-       if (info->timeout) {
+       if (info->timeout[0]) {
                typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
                struct nf_conn_timeout *timeout_ext;
 
index 5da548fa7ae9d46de78f5b75152e1a84b99ca9a7..ebd22966f7480aaacb49ca892c774ac23c477acb 100644 (file)
@@ -408,10 +408,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
                if (!(skb = skb_unshare(skb, GFP_ATOMIC)) ||
                    (skb->ip_summed == CHECKSUM_PARTIAL &&
-                    skb_checksum_help(skb))) {
-                       sch->qstats.drops++;
-                       return NET_XMIT_DROP;
-               }
+                    skb_checksum_help(skb)))
+                       return qdisc_drop(skb, sch);
 
                skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
        }
index 67972462a543d1bad6326ec214c73bc9dce17d0b..adf2990acebfd2ff7513f2344f0a143c326eb6ef 100644 (file)
@@ -176,16 +176,22 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name)
        return 0;
 }
 
-static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
-                               struct super_block *sb)
+static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event)
+{
+       if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
+           ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+               return 1;
+       return 0;
+}
+
+static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event,
+                                  struct super_block *sb)
 {
        struct dentry *dentry;
        int err = 0;
 
        switch (event) {
        case RPC_PIPEFS_MOUNT:
-               if (clnt->cl_program->pipe_dir_name == NULL)
-                       break;
                dentry = rpc_setup_pipedir_sb(sb, clnt,
                                              clnt->cl_program->pipe_dir_name);
                BUG_ON(dentry == NULL);
@@ -208,6 +214,20 @@ static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
        return err;
 }
 
+static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event,
+                               struct super_block *sb)
+{
+       int error = 0;
+
+       for (;; clnt = clnt->cl_parent) {
+               if (!rpc_clnt_skip_event(clnt, event))
+                       error = __rpc_clnt_handle_event(clnt, event, sb);
+               if (error || clnt == clnt->cl_parent)
+                       break;
+       }
+       return error;
+}
+
 static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
 {
        struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
@@ -215,10 +235,12 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event)
 
        spin_lock(&sn->rpc_client_lock);
        list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
-               if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) ||
-                   ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry))
+               if (clnt->cl_program->pipe_dir_name == NULL)
+                       break;
+               if (rpc_clnt_skip_event(clnt, event))
+                       continue;
+               if (atomic_inc_not_zero(&clnt->cl_count) == 0)
                        continue;
-               atomic_inc(&clnt->cl_count);
                spin_unlock(&sn->rpc_client_lock);
                return clnt;
        }
@@ -257,6 +279,14 @@ void rpc_clients_notifier_unregister(void)
        return rpc_pipefs_notifier_unregister(&rpc_clients_block);
 }
 
+static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename)
+{
+       clnt->cl_nodelen = strlen(nodename);
+       if (clnt->cl_nodelen > UNX_MAXNODENAME)
+               clnt->cl_nodelen = UNX_MAXNODENAME;
+       memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen);
+}
+
 static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
 {
        const struct rpc_program *program = args->program;
@@ -337,10 +367,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
        }
 
        /* save the nodename */
-       clnt->cl_nodelen = strlen(init_utsname()->nodename);
-       if (clnt->cl_nodelen > UNX_MAXNODENAME)
-               clnt->cl_nodelen = UNX_MAXNODENAME;
-       memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen);
+       rpc_clnt_set_nodename(clnt, utsname()->nodename);
        rpc_register_client(clnt);
        return clnt;
 
@@ -499,6 +526,7 @@ rpc_clone_client(struct rpc_clnt *clnt)
        err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
        if (err != 0)
                goto out_no_path;
+       rpc_clnt_set_nodename(new, utsname()->nodename);
        if (new->cl_auth)
                atomic_inc(&new->cl_auth->au_count);
        atomic_inc(&clnt->cl_count);
index 0af37fc468181e9a6917c695d8f60dd381734e78..3b62cf2880316bfb9942960e1fc34e39c64f92bf 100644 (file)
@@ -1126,19 +1126,20 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
                return -ENOMEM;
        dprintk("RPC:   sending pipefs MOUNT notification for net %p%s\n", net,
                                                                NET_NAME(net));
+       sn->pipefs_sb = sb;
        err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
                                           RPC_PIPEFS_MOUNT,
                                           sb);
        if (err)
                goto err_depopulate;
        sb->s_fs_info = get_net(net);
-       sn->pipefs_sb = sb;
        return 0;
 
 err_depopulate:
        blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
                                           RPC_PIPEFS_UMOUNT,
                                           sb);
+       sn->pipefs_sb = NULL;
        __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
        return err;
 }
index df3ac73f8778288d6666e29728e6136b44630827..b39ad356b92b84e2d649c0ea986c2ba23aecbac9 100644 (file)
@@ -99,6 +99,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
                .platform_name = "bfin-i2s-pcm-audio",
                .codec_name = "ssm2602.0-001b",
                .ops = &bf5xx_ssm2602_ops,
+               .dai_fmt = BF5XX_SSM2602_DAIFMT,
        },
        {
                .name = "ssm2602",
@@ -108,6 +109,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = {
                .platform_name = "bfin-i2s-pcm-audio",
                .codec_name = "ssm2602.0-001b",
                .ops = &bf5xx_ssm2602_ops,
+               .dai_fmt = BF5XX_SSM2602_DAIFMT,
        },
 };
 
index 16d55f91a6535e088dff5999ee9bae408999dd7e..df1e07ffac32f6057f1e94d2a9421b14a8a89c9b 100644 (file)
@@ -472,7 +472,7 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
                                      enum snd_soc_bias_level level)
 {
-       u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f;
+       u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -491,7 +491,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_OFF:
                /* everything off, dac mute, inactive */
                snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
-               snd_soc_write(codec, TLV320AIC23_PWR, 0xffff);
+               snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff);
                break;
        }
        codec->dapm.bias_level = level;
index 8c4c9591ec055103eb1cf3381ae3e3d969abac85..aa12c6b6beeb40c0cb80580772739259b1e9f27a 100644 (file)
@@ -60,7 +60,7 @@ struct wm8350_jack_data {
 };
 
 struct wm8350_data {
-       struct snd_soc_codec codec;
+       struct wm8350 *wm8350;
        struct wm8350_output out1;
        struct wm8350_output out2;
        struct wm8350_jack_data hpl;
@@ -1309,7 +1309,7 @@ static void wm8350_hp_work(struct wm8350_data *priv,
                           struct wm8350_jack_data *jack,
                           u16 mask)
 {
-       struct wm8350 *wm8350 = priv->codec.control_data;
+       struct wm8350 *wm8350 = priv->wm8350;
        u16 reg;
        int report;
 
@@ -1342,7 +1342,7 @@ static void wm8350_hpr_work(struct work_struct *work)
 static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
 {
        struct wm8350_data *priv = data;
-       struct wm8350 *wm8350 = priv->codec.control_data;
+       struct wm8350 *wm8350 = priv->wm8350;
        struct wm8350_jack_data *jack = NULL;
 
        switch (irq - wm8350->irq_base) {
@@ -1427,7 +1427,7 @@ EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect);
 static irqreturn_t wm8350_mic_handler(int irq, void *data)
 {
        struct wm8350_data *priv = data;
-       struct wm8350 *wm8350 = priv->codec.control_data;
+       struct wm8350 *wm8350 = priv->wm8350;
        u16 reg;
        int report = 0;
 
@@ -1536,6 +1536,8 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
                return -ENOMEM;
        snd_soc_codec_set_drvdata(codec, priv);
 
+       priv->wm8350 = wm8350;
+
        for (i = 0; i < ARRAY_SIZE(supply_names); i++)
                priv->supplies[i].supply = supply_names[i];
 
@@ -1544,7 +1546,6 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
        if (ret != 0)
                return ret;
 
-       wm8350->codec.codec = codec;
        codec->control_data = wm8350;
 
        /* Put the codec into reset if it wasn't already */
index f13f2886339ca4dee110746da3bbe838d99976c1..6c028c4706016e1f56bb36114d6ee9108e597736 100644 (file)
@@ -1035,7 +1035,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
                            enum snd_soc_bias_level level)
 {
        struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
-       int val;
+       int mask, val;
 
        switch (level) {
        case SND_SOC_BIAS_STANDBY:
@@ -1047,6 +1047,13 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
        case SND_SOC_BIAS_ON:
                /* Turn off any unneded single ended outputs */
                val = 0;
+               mask = 0;
+
+               if (hubs->lineout1_se)
+                       mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA;
+
+               if (hubs->lineout2_se)
+                       mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA;
 
                if (hubs->lineout1_se && hubs->lineout1n_ena)
                        val |= WM8993_LINEOUT1N_ENA;
@@ -1061,11 +1068,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec,
                        val |= WM8993_LINEOUT2P_ENA;
 
                snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3,
-                                   WM8993_LINEOUT1N_ENA |
-                                   WM8993_LINEOUT1P_ENA |
-                                   WM8993_LINEOUT2N_ENA |
-                                   WM8993_LINEOUT2P_ENA,
-                                   val);
+                                   mask, val);
 
                /* Remove the input clamps */
                snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG,
index a59bd352d34231981a99998a27ce6ad611f584ec..5a649da9122a3e798713999a766885f0f732a5cd 100644 (file)
@@ -401,6 +401,10 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd)
        }
 
 out:
+       /* free preallocated buffers in case of error */
+       if (ret)
+               omap_pcm_free_dma_buffers(pcm);
+
        return ret;
 }
 
index 72185078ddf8ef6f40a78105a6af09a4f33bf1b4..79fbeea99d46ddcd9b01ab4f0b67538369ce5c68 100644 (file)
@@ -166,7 +166,7 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = {
 
 static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev)
 {
-       return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai);
+       return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai);
 }
 
 static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev)
index 1d6a80c9f4c2a5ecedfa7ec585c7dc248a7cd31b..c88d9741b9e7942e60ba17e3d98231136b607dc9 100644 (file)
@@ -3625,10 +3625,10 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
        int i, ret;
 
        num_routes = of_property_count_strings(np, propname);
-       if (num_routes & 1) {
+       if (num_routes < 0 || num_routes & 1) {
                dev_err(card->dev,
-                       "Property '%s's length is not even\n",
-                       propname);
+                    "Property '%s' does not exist or its length is not even\n",
+                    propname);
                return -EINVAL;
        }
        num_routes /= 2;
index 95d6a6f7c33aa7971c50f9b107f0c8474a16d70a..4915408f6a98c0c6d970a7ef341da7733fa8e6bc 100755 (executable)
@@ -183,6 +183,9 @@ my %force_config;
 # do not force reboots on config problems
 my $no_reboot = 1;
 
+# reboot on success
+my $reboot_success = 0;
+
 my %option_map = (
     "MACHINE"                  => \$machine,
     "SSH_USER"                 => \$ssh_user,
@@ -2192,7 +2195,7 @@ sub run_bisect {
     }
 
     # Are we looking for where it worked, not failed?
-    if ($reverse_bisect) {
+    if ($reverse_bisect && $ret >= 0) {
        $ret = !$ret;
     }
 
@@ -3469,6 +3472,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
 
     # Do not reboot on failing test options
     $no_reboot = 1;
+    $reboot_success = 0;
 
     $iteration = $i;
 
@@ -3554,9 +3558,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
            die "failed to checkout $checkout";
     }
 
+    $no_reboot = 0;
+
     # A test may opt to not reboot the box
     if ($reboot_on_success) {
-       $no_reboot = 0;
+       $reboot_success = 1;
     }
 
     if ($test_type eq "bisect") {
@@ -3600,7 +3606,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
 
 if ($opt{"POWEROFF_ON_SUCCESS"}) {
     halt;
-} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
+} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) {
     reboot_to_good;
 } elsif (defined($switch_to_good)) {
     # still need to get to the good kernel
This page took 0.187203 seconds and 5 git commands to generate.